void SpellHandler::HandleMsg( NetworkPacket & recv_data, GameClient *pClient ) { NetworkPacket data; NetworkPacket data2; char f[256]; sprintf(f, "WORLD: Spell 0x%.4X", recv_data.opcode); LOG.outString( f ); switch (recv_data.opcode) { case CMSG_USE_ITEM: { //printf("ok got opcode here %u\n", recv_data.length); uint8 packslot,slot; uint16 targets; uint8 spell; int datalen = recv_data.length; recv_data >> packslot >> slot >> spell; recv_data >> targets; //if (targets == 0) // return; uint32 spellid; //printf("recived data!\n"); //printf("Item ID - %d\nItem GUID - %d\n",pClient->getCurrentChar()->getItemIdBySlot(slot),pClient->getCurrentChar()->getGuidBySlot(slot)); Item *tmpItem = WORLDSERVER.GetItem( pClient->getCurrentChar()->getItemIdBySlot(slot) ); spellid = tmpItem->SpellID[spell - 1]; for(int i = 0;i < 5;i++) { //printf("spell number %d - %d\n",i,tmpItem->SpellID[i]); } data.Clear(); data.Initialize (datalen - 3 + 32, SMSG_SPELL_GO); data << pClient->getCurrentChar()->GetGUID().sno << pClient->getCurrentChar()->GetGUID ().type; data << pClient->getCurrentChar()->GetGUID().sno << pClient->getCurrentChar()->GetGUID ().type; data << uint32(spellid); data << uint8(0x00) << uint8(0x01); if( targets & 0x2 || targets & 0x800 || targets & 0x8000 ) { guid unitTarget; recv_data >> unitTarget.sno >> unitTarget.type; data << uint8(0x01); data << unitTarget.sno << unitTarget.type; data << uint8(0x00); data << uint16(targets); data << unitTarget.sno << unitTarget.type; } SpellInformation spellInfo; //get a hook for the DB DatabaseInterface *dbi = DATABASE.createDatabaseInterface(); //returns a SpellInformation object/struct spellInfo = dbi->GetSpellInformation ( tmpItem->SpellID[0] ); DATABASE.removeDatabaseInterface( dbi ); //clean up used resources if(spellInfo.spell_type == (uint32)POTIONS) usePotion(pClient, tmpItem->SpellID[0], spellInfo, targets); }break; case CMSG_CAST_SPELL: { uint32 spell, target1, target2; uint16 flags; uint8 hitCount ,missCount; recv_data >> spell >> flags; guid pguid = pClient->getCurrentChar()->GetGUID(); SpellInformation spellInfo; //get a hook for the DB DatabaseInterface *dbi = DATABASE.createDatabaseInterface(); spellInfo = dbi->GetSpellInformation ( spell ); //returns a SpellInformation object/struct DATABASE.removeDatabaseInterface( dbi ); //clean up used resources //let's check spell type: if( spellInfo.spell_type == (uint32)SINGLE_TARGET) { recv_data >> target1 >> target2; printf("recv_data >> spell: %u\n", spell); printf("recv_data >> flags: %u\n", flags); Unit* pUnit_target = WORLDSERVER.GetCreature(target1); if(pUnit_target) { if(spellInfo.race == 0 || pUnit_target->getRace() == spellInfo.race) { //if( > spellInfo.Range ){ data.Clear(); data.Initialize( 36, SMSG_SPELL_START ); data << pguid.sno << pguid.type << pguid.sno << pguid.type << spell; data << flags << uint32 (3500) << flags << target1 << target2; pClient->SendMsg( &data ); hitCount = 1; missCount = 0; data2.Clear(); data2.Initialize( 42, SMSG_SPELL_GO ); data2 << pguid.sno << pguid.type << pguid.sno << pguid.type; data2 << spell << uint16 (0x0100) << hitCount << target1 << target2; data2 << missCount << flags << target1 << target2; uint32 damage = spellInfo.DmgPlus1+rand()%spellInfo.RandomPercentDmg; WORLDSERVER.mCombatHandler.AttackerStateUpdate(pClient->getCurrentChar( ), WORLDSERVER.getCreatureMap( )[ target1 ], damage); if(spellInfo.addDuration > 0) { Unit* pCast_target = WORLDSERVER.GetCreature(target1); if( pCast_target ) { uint32 time = spellInfo.addDuration/1000; uint32 addDmg = (uint32)((float)spellInfo.addDmg/(float)time); if(addDmg == 0) addDmg = 1; pCast_target->m_damageDuration = spellInfo.addDuration/1000; pCast_target->m_damage = addDmg; pCast_target->m_Attacker = pClient->getCurrentChar()->GetGUID(); } } uint32 mana = pClient->getCurrentChar()->getUpdateValue( UNIT_FIELD_POWER1 ); pClient->getCurrentChar( )->setUpdateValue( UNIT_FIELD_POWER1, mana-spellInfo.ManaCost ); data.Clear(); data.Initialize( 5, SMSG_CAST_RESULT ); data << spell << uint8( 0x01); pClient->SendMsg( &data ); pClient->getCurrentChar()->SendMessageToSet(&data2, true); } else { data.Clear(); data.Initialize( 6, SMSG_CAST_RESULT ); data << spell << uint8( 0x02); data << uint8(9); pClient->SendMsg( &data ); } } } else if( spellInfo.spell_type == (uint32)MULTI_TARGET )
void ItemHandler::HandleMsg (NetworkPacket & recv_data, GameClient *pClient) { NetworkPacket data; char f[ 256 ]; sprintf (f, "WORLDSERVER: Item Opcode 0x%.4X", recv_data.opcode); LOG.outString (f); switch (recv_data.opcode) { case CMSG_SWAP_INV_ITEM: { //ok i'm gonna do that a looootttt cleaner :/ uint8 srcslot, destslot; recv_data >> srcslot >> destslot; int slot = destslot; //START OF LINA LVL REQUIREMENT SWAP PATCH int8 CharLvl, ItemLvl; //printf("ITEM: LVL TEST\n"); CharLvl=pClient->getCurrentChar()->getLevel(); ItemLvl=WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(srcslot))->RequiredLevel; //printf("ITEM: CharLvl %d, ItemLvl %d\n", CharLvl, ItemLvl); if (CharLvl < ItemLvl) { ChatHandler * MsgLvlItem = new ChatHandler; if(MsgLvlItem !=NULL) { //NEED TO PUT SOME CODE TO UNGRAY ITEM uint8 buf[256]; NetworkPacket data; sprintf((char*)buf,"You need the Lvl %d to equip that item.", ItemLvl); MsgLvlItem->FillMessageData(&data, 0x09, pClient, buf); pClient->SendMsg (&data); delete(MsgLvlItem); } else printf("ITEM: CMSG_SWAP_INV_ITEM can't send message\n"); return; } //END OF LINA LVL REQUIREMENT SWAP PATCH //these are the bags slots...ignore it for now if ((slot <= 22) && (slot >=19)) destslot = srcslot; //check to make sure items are not being put in wrong spots if (((srcslot > 23) && (destslot < 19)) || ((srcslot < 23) && (destslot > 19))) { if ((pClient->getCurrentChar()->getGuidBySlot(destslot) != 0) && (pClient->getCurrentChar()->getGuidBySlot(srcslot) != 0)) { Item * tmpitem1 = WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot)); Item * tmpitem2 = WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(srcslot)); if ((tmpitem1 != NULL) && (tmpitem2 != NULL)) { if (tmpitem1->Inventorytype != tmpitem2->Inventorytype) { data.Initialize (18, SMSG_INVENTORY_CHANGE_FAILURE); data << uint8(0x0c) ; data << uint32(pClient->getCurrentChar()->getGuidBySlot(destslot)); data << uint32(0x00000040); data << uint32(pClient->getCurrentChar()->getGuidBySlot(srcslot)); data << uint32(0x00000040); data << uint8(0); pClient->SendMsg (&data); return; } } } } //swap items pClient->getCurrentChar()->SwapItemInSlot((int)srcslot, (int)destslot); UpdateMask updateMask; updateMask.SetLength (PLAYER_FIELDS); //error if (srcslot == destslot) { data.Initialize (18, SMSG_INVENTORY_CHANGE_FAILURE); data << uint8(0x0c) ; data << uint32(pClient->getCurrentChar()->getGuidBySlot(destslot)); data << uint32(0x00000040); data << uint32(pClient->getCurrentChar()->getGuidBySlot(srcslot)); data << uint32(0x00000040); data << uint8(0); pClient->SendMsg (&data); return; } pClient->getCurrentChar()->updateItemStats(); //send to zone players...they don't need to know about the item if the slot is over 19 if (destslot < 19) { pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (destslot*2), pClient->getCurrentChar()->getGuidBySlot(destslot), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (destslot*2)+1, pClient->getCurrentChar()->getGuidBySlot(destslot) == 0 ? 0 : 0x00000040, updateMask.data); } if (srcslot < 19) { pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (srcslot*2), pClient->getCurrentChar()->getGuidBySlot(srcslot), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (srcslot*2)+1, pClient->getCurrentChar()->getGuidBySlot(srcslot) == 0 ? 0 : 0x00000040, updateMask.data); } pClient->getCurrentChar ()->UpdateObject (&updateMask, &data); // WORLDSERVERSERVER.SendZoneMessage(&data, pClient, 0); pClient->getCurrentChar()->SendMessageToSet(&data, false); //send update to the player pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (destslot*2), pClient->getCurrentChar()->getGuidBySlot(destslot), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (destslot*2)+1, pClient->getCurrentChar()->getGuidBySlot(destslot) == 0 ? 0 : 0x00000040, updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (srcslot*2), pClient->getCurrentChar()->getGuidBySlot(srcslot), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (srcslot*2)+1, pClient->getCurrentChar()->getGuidBySlot(srcslot) == 0 ? 0 : 0x00000040, updateMask.data); pClient->getCurrentChar ()->UpdateObject (&updateMask, &data); pClient->SendMsg (&data); if ((srcslot < 19) && (destslot < 19)) return; int invcount = srcslot; if ((pClient->getCurrentChar()->getGuidBySlot(invcount) != 0) && (srcslot < 19)) { createItemUpdate(&data, pClient, invcount); // WORLDSERVER.SendZoneMessage(&data, pClient, 0); pClient->getCurrentChar()->SendMessageToSet(&data, false); } invcount = destslot; if ((pClient->getCurrentChar()->getGuidBySlot(invcount) != 0) && (destslot < 19)) { createItemUpdate(&data, pClient, invcount); // WORLDSERVER.SendZoneMessage(&data, pClient, 0); pClient->getCurrentChar()->SendMessageToSet(&data, false); } break; } case CMSG_DESTROYITEM: { uint8 srcslot, destslot; uint32 itemguid; recv_data >> srcslot >> destslot; if (WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot)) != NULL) srcslot = WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot))->Inventorytype && 0xff; else return; if (pClient->getCurrentChar()->getGuidBySlot(destslot) == 0) return; itemguid = pClient->getCurrentChar()->getGuidBySlot(destslot); pClient->getCurrentChar()->AddItemToSlot(destslot,0,0); UpdateMask updateMask; updateMask.SetLength (PLAYER_FIELDS); if (destslot < 19) { pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (destslot*2), pClient->getCurrentChar()->getGuidBySlot (destslot), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (destslot*2)+1, pClient->getCurrentChar()->getGuidBySlot(destslot) == 0 ? 0 : 0x00000040, updateMask.data); } pClient->getCurrentChar ()->UpdateObject (&updateMask, &data); // WORLDSERVERSERVER.SendZoneMessage(&data, pClient, 0); pClient->getCurrentChar()->SendMessageToSet(&data, false); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (destslot*2), pClient->getCurrentChar()->getGuidBySlot(destslot), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (destslot*2)+1, pClient->getCurrentChar()->getGuidBySlot(destslot) == 0 ? 0 : 0x00000040, updateMask.data); pClient->getCurrentChar ()->UpdateObject (&updateMask, &data); pClient->SendMsg (&data); data.Clear(); data.Initialize(8, SMSG_DESTROY_OBJECT); data << itemguid << uint32(0x00000040); // WORLDSERVER.SendZoneMessage(&data, pClient, 1); pClient->getCurrentChar()->SendMessageToSet(&data, true); break; } case CMSG_AUTOEQUIP_ITEM: { uint8 srcslot, destslot; recv_data >> srcslot >> destslot; int8 CharLvl, ItemLvl; //START OF LINA LVL REQUIREMENT AUTOEQUIP PATCH CharLvl=pClient->getCurrentChar()->getLevel(); ItemLvl=WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot))->RequiredLevel; //printf("ITEM: CharLvl %d, ItemLvl %d\n", CharLvl, ItemLvl); if (CharLvl < ItemLvl) { ChatHandler * MsgLvlItem = new ChatHandler; if (MsgLvlItem != NULL) { //NEED TO PUT SOME CODE TO UNGRAY ITEM uint8 buf[256]; NetworkPacket data; sprintf((char*)buf,"You need the Lvl %d to equip that item.", ItemLvl); MsgLvlItem->FillMessageData(&data, 0x09, pClient, buf); pClient->SendMsg (&data); delete(MsgLvlItem); } else printf("ITEM: CMSG_AUTOEQUIP_ITEM can't send message\n"); return; } //END OF LINA LVL REQUIREMENT AUTOEQUIP PATCH if (WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot)) != NULL) srcslot = uint8(WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot))->Inventorytype); else return; if (WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot))->Class == 4) { if (srcslot < 11) srcslot--; else if (srcslot == 11) { if (pClient->getCurrentChar()->getGuidBySlot(10) == 0) { srcslot = 10; } else if (pClient->getCurrentChar()->getGuidBySlot(11) == 0) { srcslot = 11; } else { srcslot = destslot; } } else if (srcslot == 14) srcslot += 2; else if (srcslot == 13) srcslot += 2; else srcslot = 4; } else if (WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot))->Class == 2) { switch (WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(destslot))->SubClass) { case 2: case 3: case 16: case 19: srcslot = 17; break; default: srcslot = 15; break; } } else { srcslot = destslot; } if (srcslot == destslot) { data.Initialize (18, SMSG_INVENTORY_CHANGE_FAILURE); data << uint8(0x0c) ; data << uint32(pClient->getCurrentChar()->getGuidBySlot(destslot)); data << uint32(0x00000040); data << uint32(0) << uint32(0) << uint8(0); pClient->SendMsg (&data); return; } pClient->getCurrentChar()->SwapItemInSlot((int)srcslot, (int)destslot); UpdateMask updateMask; updateMask.SetLength (PLAYER_FIELDS); if (destslot < 19) { pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (destslot*2), pClient->getCurrentChar()->getGuidBySlot(destslot), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (destslot*2)+1, pClient->getCurrentChar()->getGuidBySlot(destslot) == 0 ? 0 : 0x00000040, updateMask.data); } if (srcslot < 19) { pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (srcslot*2), pClient->getCurrentChar()->getGuidBySlot(srcslot), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (srcslot*2)+1, pClient->getCurrentChar()->getGuidBySlot(srcslot) == 0 ? 0 : 0x00000040, updateMask.data); } pClient->getCurrentChar ()->UpdateObject (&updateMask, &data); // WORLDSERVERSERVER.SendZoneMessage(&data, pClient, 0); pClient->getCurrentChar()->SendMessageToSet(&data, false); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (destslot*2), pClient->getCurrentChar()->getGuidBySlot(destslot), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (destslot*2)+1, pClient->getCurrentChar()->getGuidBySlot(destslot) == 0 ? 0 : 0x00000040, updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (srcslot*2), pClient->getCurrentChar()->getGuidBySlot(srcslot), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (srcslot*2)+1, pClient->getCurrentChar()->getGuidBySlot(srcslot) == 0 ? 0 : 0x00000040, updateMask.data); pClient->getCurrentChar ()->UpdateObject (&updateMask, &data); pClient->SendMsg (&data); Item *tempitem; UpdateMask invUpdateMask; int invcount = srcslot; invUpdateMask.SetLength (64); tempitem = new Item; if ((pClient->getCurrentChar()->getGuidBySlot(invcount) != 0) && (srcslot < 19)) { createItemUpdate(&data, pClient, invcount); // WORLDSERVER.SendZoneMessage(&data, pClient, 0); pClient->getCurrentChar()->SendMessageToSet(&data, false); delete tempitem; } else delete tempitem; invcount = destslot; invUpdateMask.SetLength (64); tempitem = new Item; if (srcslot == destslot) return; if ((pClient->getCurrentChar()->getGuidBySlot(invcount) != 0) && (destslot < 19)) { createItemUpdate(&data, pClient, invcount); // WORLDSERVER.SendZoneMessage(&data, pClient, 0); pClient->getCurrentChar()->SendMessageToSet(&data, false); } LOG.outString ("WORLDSERVER: Sent Updated Item slot Masks"); break; } case CMSG_ITEM_QUERY_SINGLE: { int i; uint32 itemid, guid1, guid2; recv_data >> itemid >> guid1 >> guid2; // guid is the guid of the ITEM OWNER - NO ITS NOT if (WORLDSERVER.GetItem(itemid) == NULL) return; sprintf (curopcodebuf, "WORLDSERVER: Recvd CMSG_ITEM_QUERY_SINGLE for item id 0x%.8X, guid 0x%.8X 0x%.8X", itemid, guid1, guid2); LOG.outString (curopcodebuf); Item *tempItem = WORLDSERVER.GetItem(itemid); //data.Initialize (413 + tempItem->name1.length() + tempItem->name2.length() + tempItem->name3.length() + tempItem->name4.length() + tempItem->Description.length(), SMSG_ITEM_QUERY_SINGLE_RESPONSE); data.Initialize (413 + 12 + tempItem->name1.length() + tempItem->name2.length() + tempItem->name3.length() + tempItem->name4.length() + tempItem->Description.length(), SMSG_ITEM_QUERY_SINGLE_RESPONSE); //printf("%d\n", data.length); //printf("%s\n%s\n", tempItem->name1.c_str(), tempItem->Description.c_str()); data << itemid; data << tempItem->Class; data << tempItem->SubClass; data << tempItem->name1.c_str(); data << tempItem->name2.c_str(); data << tempItem->name3.c_str(); data << tempItem->name4.c_str(); data << tempItem->DisplayInfoID; data << tempItem->OverallQualityID; data << tempItem->Flags; data << tempItem->Buyprice; data << tempItem->Sellprice; data << tempItem->Inventorytype; data << tempItem->AllowableClass; data << tempItem->AllowableRace; data << tempItem->ItemLevel; data << tempItem->RequiredLevel; data << tempItem->RequiredSkill; data << tempItem->RequiredSkillRank; data << uint32(0); // other requirements here? - 10 = "Requires Blizzard" data << uint32(0); // ??? 10 = "Requires Knight" data << uint32(0); // ??? 10 = "Requires " data << tempItem->MaxCount; data << tempItem->Stackable; data << tempItem->ContainerSlots; for(i = 0; i<10; i++) { data << tempItem->BonusStat[i]; data << tempItem->BonusAmount[i]; } for(i = 0; i<5; i++) { data << (float)(tempItem->MinimumDamage[i]); data << (float)(tempItem->MaximumDamage[i]); data << tempItem->DamageType[i]; } data << tempItem->Resistances[0]; // armor data << uint32(0); // unknown extra resistance data << tempItem->Resistances[2]; // fire data << tempItem->Resistances[3]; // nature data << tempItem->Resistances[4]; // frost data << tempItem->Resistances[5]; // shadow data << tempItem->Resistances[1]; // arcane at the end now //for(i = 0; i<6; i++) //{ // data << tempItem->Resistances[i]; //} data << tempItem->Delay; data << tempItem->AmmunitionType; //data << tempItem->MaxDurability; for(i = 0; i<5; i++) { data << tempItem->SpellID[i]; data << tempItem->SpellTrigger[i]; data << tempItem->SpellCharges[i]; data << tempItem->SpellCooldown[i]; data << tempItem->SpellCategory[i]; data << tempItem->SpellCategoryCooldown[i]; } data << tempItem->Bonding; if (tempItem->Description.c_str()[0] != 48) data << tempItem->Description.c_str(); else data << uint32(0); data << tempItem->Pagetext; data << tempItem->LanguageID; data << tempItem->PageMaterial; data << tempItem->StartQuestID; data << tempItem->LockID; data << tempItem->Material; data << tempItem->Sheathetype; data << tempItem->Unknown1; data << tempItem->Unknown2; pClient->SendMsg (&data); break; } case CMSG_SELL_ITEM: { LOG.outString ("WORLDSERVER: Recieved CMSG_SELL_ITEM"); uint32 srcguid1, srcguid2, itemguid1, itemguid2,newmoney; uint8 amount; recv_data >> srcguid1 >> srcguid2; recv_data >> itemguid1 >> itemguid2; recv_data >> amount; if (itemguid1 == 0) { data.Clear(); data.Initialize(17, SMSG_SELL_ITEM); data << srcguid1 << srcguid2 << itemguid1 << itemguid2 << uint8(0x01); pClient->SendMsg (&data); return; } int itemindex = -1,i,check = 0; Unit *tempunit; tempunit = WORLDSERVER.GetCreature(srcguid1); if (tempunit == NULL) return; for(i = 0; i< 39;i++) { if (pClient->getCurrentChar()->getGuidBySlot(i) == itemguid1) { itemindex = i; break; } } if (itemindex == -1) { data.Clear(); data.Initialize(17, SMSG_SELL_ITEM); data << srcguid1 << srcguid2 << itemguid1 << itemguid2 << uint8(0x01); pClient->SendMsg (&data); return; //our player doesn't have this item } /***************************************************** * i will need to put some stack count check here * *****************************************************/ if (amount == 0) amount = 1; //adding this item to the vendor's item list for(i=0; i<tempunit->getItemCount();i++) { if (tempunit->getItemId(i) == pClient->getCurrentChar()->getItemIdBySlot(itemindex)) { tempunit->setItemAmount(i, tempunit->getItemAmount(i) + amount); check = 1; } } if (check == 0) { if (tempunit->getItemCount() > 100) { data.Clear(); data.Initialize(17, SMSG_SELL_ITEM); data << srcguid1 << srcguid2 << itemguid1 << itemguid2 << uint8(0x02); pClient->SendMsg (&data); return; } else tempunit->addItem(pClient->getCurrentChar()->getItemIdBySlot(itemindex), amount); } newmoney = WORLDSERVER.GetItem(pClient->getCurrentChar()->getItemIdBySlot(itemindex))->Sellprice + pClient->getCurrentChar()->getUpdateValue(PLAYER_FIELD_COINAGE); //removing the item from the char's inventory pClient->getCurrentChar()->AddItemToSlot(itemindex,0,0); //sending a player update UpdateMask updateMask; updateMask.SetLength (PLAYER_FIELDS); if (itemindex < 19) { pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (itemindex*2), pClient->getCurrentChar()->getGuidBySlot(itemindex), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (itemindex*2)+1, pClient->getCurrentChar()->getGuidBySlot(itemindex) == 0 ? 0 : 0x00000040, updateMask.data); } pClient->getCurrentChar ()->UpdateObject (&updateMask, &data); //WORLDSERVER.SendZoneMessage(&data, pClient, 0); pClient->getCurrentChar()->SendMessageToSet(&data, false); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_COINAGE, newmoney, updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (itemindex*2), pClient->getCurrentChar()->getGuidBySlot(itemindex), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (itemindex*2)+1, pClient->getCurrentChar()->getGuidBySlot(itemindex) == 0 ? 0 : 0x00000040, updateMask.data); pClient->getCurrentChar ()->UpdateObject (&updateMask, &data); pClient->SendMsg (&data); //send an SMSG_SELL_ITEM data.Clear(); data.Initialize(17, SMSG_SELL_ITEM); data << srcguid1 << srcguid2 << itemguid1 << itemguid2 << uint8(0x05); pClient->SendMsg (&data); //send an object destroy packet data.Clear(); data.Initialize(8, SMSG_DESTROY_OBJECT); data << itemguid1 << uint32(0x00000040); // WORLDSERVER.SendZoneMessage(&data, pClient, 1); pClient->getCurrentChar()->SendMessageToSet(&data, true); break; } case CMSG_BUY_ITEM_IN_SLOT: { LOG.outString ("WORLDSERVER: Recieved CMSG_BUY_ITEM_IN_SLOT"); uint32 srcguid1, srcguid2, itemid, destguid1, destguid2; uint8 slot, amount; recv_data >> srcguid1 >> srcguid2 >> itemid; recv_data >> destguid1 >> destguid2; recv_data >> slot; recv_data >> amount; int itemindex,i,varify = 0; Unit *tempunit; tempunit = WORLDSERVER.GetCreature(srcguid1); if (tempunit == NULL) return; if (slot > 38) return; if (slot < 19) return; if ((slot <= 22) && (slot >=19)) return; //these are the bags slots...i'm not sure exactly how to use them if (pClient->getCurrentChar()->getGuidBySlot(slot) != 0) return; //slot is not empty...i'll have to make code to check for other slots for(i = 0; i< tempunit->getItemCount();i++) { if (tempunit->getItemId(i) == itemid) { varify = 1; break; } } if (varify == 0) return; //our vendor doesn't have this item itemindex = i; if (amount > tempunit->getItemAmount(i)) return; //our vendor doesn't have the required amount of that item tempunit->setItemAmountById(itemid,tempunit->getItemAmount(i) - amount); //START OF LINA BUY PATCH //INFO printf("ARGENT: %d, COUT: %d\n", (pClient->getCurrentChar()->getUpdateValue(PLAYER_FIELD_COINAGE)), (WORLDSERVER.GetItem(tempunit->getItemId(itemindex))->Buyprice)); int32 newmoney; //LINA newmoney = ((pClient->getCurrentChar()->getUpdateValue(PLAYER_FIELD_COINAGE)) - (WORLDSERVER.GetItem(tempunit->getItemId(itemindex))->Buyprice)); printf("DIF: %d\n",newmoney); //INFO if(newmoney < 0) { ChatHandler * MsgGold = new ChatHandler; if (MsgGold != NULL) { uint8 buf[256]; NetworkPacket data; sprintf((char*)buf,"You need %i to buy this item.", abs(newmoney)); MsgGold->FillMessageData(&data, 0x09, pClient, buf); pClient->SendMsg (&data); delete(MsgGold); } else printf("ITEM: CMSG_BUY_ITEM_IN_SLOT can't send message\n"); return; } //END OF LINA BUY PATCH WORLDSERVER.m_hiItemGuid++; std::string templog; char tempiid[10]; sprintf(tempiid,"%d",WORLDSERVER.m_hiItemGuid); templog = "Created Item. Guid: "; templog+= tempiid; LOG.outString (templog.c_str()); pClient->getCurrentChar()->AddItemToSlot(slot,WORLDSERVER.m_hiItemGuid,itemid); data.Clear(); data.Initialize(16, SMSG_BUY_ITEM); data << uint32(srcguid1) << uint32(srcguid2); data << uint32(itemid) << uint32(amount); pClient->SendMsg (&data); Item *tempitem; UpdateMask invUpdateMask; int invcount = slot; invUpdateMask.SetLength (64); tempitem = new Item; createItemUpdate(&data, pClient, invcount); if (slot > 23) pClient->SendMsg (&data); else { // WORLDSERVER.SendZoneMessage(&data, pClient, 0); pClient->getCurrentChar()->SendMessageToSet(&data, true); // pClient->SendMsg (&data); } delete tempitem; UpdateMask updateMask; updateMask.SetLength (PLAYER_FIELDS); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_COINAGE, newmoney, updateMask.data); //LINA BUY PATCH NEXT pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (slot*2), pClient->getCurrentChar()->getGuidBySlot(slot), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (slot*2)+1, pClient->getCurrentChar()->getGuidBySlot(slot) == 0 ? 0 : 0x00000040, updateMask.data); pClient->getCurrentChar ()->UpdateObject (&updateMask, &data); if (slot > 23) pClient->SendMsg (&data); else { // WORLDSERVER.SendZoneMessage(&data, pClient, 0); pClient->getCurrentChar()->SendMessageToSet(&data, true); // pClient->SendMsg (&data); } break; } case CMSG_BUY_ITEM: //right click { LOG.outString ("WORLDSERVER: Recieved CMSG_BUY_ITEM"); uint32 srcguid1, srcguid2, itemid; uint8 slot, amount; recv_data >> srcguid1 >> srcguid2 >> itemid; recv_data >> amount >> slot; int itemindex,i,varify = 0; Unit *tempunit; tempunit = WORLDSERVER.GetCreature(srcguid1); if (tempunit == NULL) return; slot = 0; for(i = 23; i <= 38; i++) { if (pClient->getCurrentChar()->getGuidBySlot(i) == 0) { slot = i; break; } } if (slot == 0) return; for(i = 0; i< tempunit->getItemCount();i++) { if (tempunit->getItemId(i) == itemid) { varify = 1; break; } } if (varify == 0) return; //our vendor doesn't have this item itemindex = i; if (amount > tempunit->getItemAmount(i)) return; //our vendor doesn't have the required amount of that item tempunit->setItemAmountById(itemid,tempunit->getItemAmount(i) - amount); //START OF LINA BUY PATCH //INFO printf("ARGENT: %d, COUT: %d\n", (pClient->getCurrentChar()->getUpdateValue(PLAYER_FIELD_COINAGE)), (WORLDSERVER.GetItem(tempunit->getItemId(itemindex))->Buyprice)); int32 newmoney; //LINA newmoney = ((pClient->getCurrentChar()->getUpdateValue(PLAYER_FIELD_COINAGE)) - (WORLDSERVER.GetItem(tempunit->getItemId(itemindex))->Buyprice)); printf("DIF: %d\n",newmoney); //INFO if(newmoney < 0) { //NEED TO PUT SOME CODE TO UNGRAY ITEM AND SEND A MESSAGE TO PLAYER ChatHandler * MsgGold = new ChatHandler; if (MsgGold != NULL) { uint8 buf[256]; NetworkPacket data; sprintf((char*)buf,"You need %i to buy this item.", abs(newmoney)); MsgGold->FillMessageData(&data, 0x09, pClient, buf); pClient->SendMsg (&data); delete(MsgGold); } else printf("ITEM: CMSG_BUY_ITEM can't send message\n"); return; } //END OF LINA BUY PATCH WORLDSERVER.m_hiItemGuid++; std::string templog; char tempiid[10]; sprintf(tempiid,"%d",WORLDSERVER.m_hiItemGuid); templog = "Created Item. Guid: "; templog+= tempiid; LOG.outString (templog.c_str()); pClient->getCurrentChar()->AddItemToSlot(slot,WORLDSERVER.m_hiItemGuid,itemid); UpdateMask invUpdateMask; int invcount = slot; invUpdateMask.SetLength (64); createItemUpdate(&data, pClient, invcount); if (slot > 23) pClient->SendMsg (&data); else { // WORLDSERVER.SendZoneMessage(&data, pClient, 0); pClient->getCurrentChar()->SendMessageToSet(&data, true); // pClient->SendMsg (&data); } UpdateMask updateMask; updateMask.SetLength (PLAYER_FIELDS); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_COINAGE, newmoney, updateMask.data); //LINA BUY PATCH NEXT pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (slot*2), pClient->getCurrentChar()->getGuidBySlot(slot), updateMask.data); pClient->getCurrentChar ()->setUpdateValue ( PLAYER_FIELD_INV_SLOT_HEAD + (slot*2)+1, pClient->getCurrentChar()->getGuidBySlot(slot) == 0 ? 0 : 0x00000040, updateMask.data); pClient->getCurrentChar ()->UpdateObject (&updateMask, &data); if (slot > 23) pClient->SendMsg (&data); else { // WORLDSERVER.SendZoneMessage(&data, pClient, 0); pClient->getCurrentChar()->SendMessageToSet(&data, false); // pClient->SendMsg (&data); } break; } case CMSG_LIST_INVENTORY: { LOG.outString ("WORLDSERVER: Recvd CMSG_LIST_INVENTORY Message"); uint32 guid1, guid2; //guid1+guid2 = npc's full uint64 guid recv_data >> guid1 >> guid2; Unit *tempunit; tempunit = WORLDSERVER.GetCreature(guid1); if (tempunit == NULL) return; uint8 numitems = (uint8)tempunit->getItemCount(); if (numitems == 0) return; data.Initialize (8 + 1 + numitems * 7 * 4, SMSG_LIST_INVENTORY); data << guid1 << guid2; data << uint8 (numitems); // num items // each item has seven uint32's Item * curItem; for(uint8 itemcount = 0; itemcount < numitems; itemcount ++) { curItem = WORLDSERVER.GetItem(tempunit->getItemId(itemcount)); if (!curItem) { LOG.outError ("Unit %i has nonexistant item %i!", guid1, tempunit->getItemId(itemcount)); LOG.outString ("WORLDSERVER: DID NOT Send SMSG_LIST_INVENTORY Message"); for (int a = 0; a < 7; a ++) data << uint32 (0); } else { data << uint32 (itemcount + 1); // index ? doesn't seem to affect anything // item id data << uint32 (tempunit->getItemId(itemcount)); data << uint32 (curItem->DisplayInfoID);// item icon // number of items available, -1 works for infinity, although maybe just 'cause it's really big data << uint32 (tempunit->getItemAmount(itemcount)); data << uint32 (curItem->Buyprice); // price data << uint32 (0); // ? data << uint32 (0); // ? } } //data.WriteData (tdata, sizeof (tdata)); pClient->SendMsg (&data); LOG.outString ("WORLDSERVER: Sent SMSG_LIST_INVENTORY Message"); break; } } }
void QueryHandler::HandleMsg( NetworkPacket & recv_data, GameClient *pClient ) { NetworkPacket data; char f[256]; sprintf(f, "WORLD: Query Opcode 0x%.4X", recv_data.opcode); LOG.outString( f ); switch (recv_data.opcode) { case CMSG_NAME_QUERY: { uint32 guid; memcpy(&guid, recv_data.data, 4); uint32 race = 0, gender = 0, cl = 0; char name[32]; std::map<uint32, Character*>::iterator itr = WORLDSERVER.mCharacters.find(guid); if (itr == WORLDSERVER.mCharacters.end()) { DatabaseInterface *dbi = DATABASE.createDatabaseInterface( ); if (!dbi->GetPlayerNameFromGUID(1, (uint8*)name)) LOG.outString( "No player name found for this guid" ); DATABASE.removeDatabaseInterface( dbi ); } else { Character *pChar = WORLDSERVER.mCharacters[guid]; race = pChar->getRace(); gender = pChar->getGender(); cl = pChar->getClass(); strcpy(name, pChar->getName()); } data.Clear(); data.length = 8 + strlen(name)+ 1 + 4*sizeof(uint32); data.data = new uint8[ data.length ]; data.opcode = SMSG_NAME_QUERY_RESPONSE; LOG.outString( name ); data << guid << uint32(0); data << (std::string)name << uint32(0); data << race << gender << cl; // FIXME, something wrong here, crashes client. pClient->SendMsg( &data ); } break; case CMSG_QUERY_TIME: { data.Clear(); data.Initialize(4, SMSG_QUERY_TIME_RESPONSE); data << (int32)time(NULL); pClient->SendMsg(&data); }break; case CMSG_CREATURE_QUERY: { uint32 entry=0; uint32 guid=0; recv_data.ReadData(entry); recv_data.ReadData(guid); uint8 *name = 0; /*std::map<uint32, uint8*>::iterator itr = WORLDSERVER.mCreatureNames.find(entry); if (itr == WORLDSERVER.mCreatureNames.end()){ WPAssert(!"invalid creature entry"); }*/ name = WORLDSERVER.mCreatureNames[entry]; if (!name) name = (uint8 *)"ERROR_NO_CREATURENAME_FOR_ENTRY"; // return; printf(" WORLD: CMSG_CREATURE_QUERY '%s'\n", name ); uint16 namesize = strlen((char*)name)+1; data.Clear(); data.Initialize(4+namesize+16, SMSG_CREATURE_QUERY_RESPONSE); data << (uint32)entry; strcpy((char*)data.data+4, (char*)name); uint8 somedata[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; memcpy(data.data+namesize+4, somedata, 16); pClient->SendMsg(&data); }break; case CMSG_GAMEOBJECT_QUERY: { data.Initialize( 64, SMSG_GAMEOBJECT_QUERY_RESPONSE ); //TODO: Check the database for the ENTRY (First long) and obtain all the details from there... data << uint32( 0x00000787 ) << uint32( 0x00000013 ) << uint32( 0x0000088e ); data << uint32( 0x6c69614d ) << uint32( 0x00786f62 ); data << uint32( 0x00000000 ) << uint32( 0x00000000 ) << uint32( 0x00000000 ); data << uint32( 0x00000000 ); data << uint32( 0 ) << uint32( 0 ) << uint32( 0 ) << uint32( 0 ) << uint32( 0 ) << uint32( 0 ); data << uint16( 0 ) << uint8( 0 ); /* 00 00 07 87 00 00 00 08 00 00 00 C0 54 F9 EC 01 04 00 00 00 0A 00 00 00 12 00 00 00 00 00 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 4F 52 44 45 52 */ /* Mailbox 22 33 02 00 // ENTRY 13 00 00 00 // Unknown 8e 08 00 00 // Display_id 4d 61 69 6c | 62 6f 78 00 // Mailbox (Null terminated) 00 00 00 00 // 1 00 00 00 00 // 2 00 00 00 00 // 3 00 00 00 00 // 4 00 00 00 00 // 5 00 00 00 00 // 6 00 00 00 00 // 7 00 00 00 00 // 8 00 00 00 00 // 9 00 00 00 00 // 10 00 00 00 // 11 */ pClient->SendMsg( &data ); LOG.outString( "WORLD: Sent Object Query Response." ); }break; } }
void GossipHandler::HandleMsg( NetworkPacket & recv_data, GameClient *pClient ) { NetworkPacket data; char f[256]; sprintf(f, "WORLD: Gossip Opcode 0x%.4X", recv_data.opcode); Log::getSingleton( ).outString( f ); switch (recv_data.opcode) { case CMSG_GOSSIP_HELLO: { uint16 tSize,i; uint32 TextID; guid cguid; recv_data >> cguid.sno >> cguid.type; TextID = getTextID(cguid.sno); if(TextID == 0) { //text Id 0 don't exist so maybe they don't want to talk :P data.Initialize( 8 , SMSG_NPC_WONT_TALK ); data << cguid.sno << cguid.type; pClient->SendMsg (&data); break; } //TextRelation * pRelation = getTextRelation(cguid.sno); NPCText * theText = getNPCText(TextID); //Calculate the size tSize = 20 + (8*theText->m_OptionCount); TextOption * theOption; for(i = 1; i <= theText->m_OptionCount;i++) { // add option textsize to the size theOption = getTextOption(theText->m_OptionID[i]); tSize += strlen((char *)theOption->m_OptionText.c_str())+1; } //Create the Packet data.Initialize( tSize, SMSG_GOSSIP_MESSAGE ); data << cguid.sno << cguid.type; data << (uint32)TextID; //TextID data << (uint32)theText->m_OptionCount; // Bullet Points Count for(i = 1; i <= theText->m_OptionCount;i++) { theOption = getTextOption(theText->m_OptionID[i]); data << (uint32)theOption->m_OptionID; //Bullet Point Number data << (uint32)theOption->m_OptionIconID; //Bullet Point IconID //option text data.WriteData(theOption->m_OptionText.c_str() , strlen((char *)theOption->m_OptionText.c_str())+1 ); } data << (uint32)0; pClient->SendMsg (&data); //pClient->getCurrentChar()->setUpdateValue(CORPSE_FIELD_ITEM3, 6947); //pClient->getCurrentChar()->setUpdateValue(CORPSE_FIELD_ITEM4, (uint32)0xf0001000 ); //pClient->getCurrentChar()->UpdateObject(); }break; case CMSG_GOSSIP_SELECT_OPTION: { uint32 option; guid cguid; recv_data >> cguid.sno >> cguid.type; recv_data >> option; TextOption * theOption; theOption = getTextOption(option); // Textid of 0 is Reserved for exiting and SH Comfirm if(theOption->m_TextID == 0) { Unit *pSelection = world.GetValidCreature(cguid.sno); if(pSelection != 0) { //if the selection is a spirit healer if(pSelection->getUpdateValue(UNIT_NPC_FLAGS) == 32) { // Sh Accept Dialog data.Initialize(8,SMSG_SPIRIT_HEALER_CONFIRM); data << cguid.sno << cguid.type; pClient->SendMsg( &data ); } } //close the Gossip Window data.Initialize(0,SMSG_GOSSIP_COMPLETE); pClient->SendMsg( &data ); break; } uint16 TextID,tSize,i; //get the Text ID TextID = theOption->m_TextID; //get the Related text info NPCText * theText = getNPCText(TextID); //calculate our size tSize = 20 + (8*theText->m_OptionCount); for(i = 1; i <= theText->m_OptionCount;i++) { //get each options text and add it to the size theOption = getTextOption(theText->m_OptionID[i]); tSize += strlen((char *)theOption->m_OptionText.c_str())+1; } //Create the Packet data.Initialize( tSize, SMSG_GOSSIP_MESSAGE ); data << cguid.sno << cguid.type; data << (uint32)TextID; //TextID data << (uint32)theText->m_OptionCount; // Bullet Points Count //Get each option for(i = 1; i <= theText->m_OptionCount;i++) { theOption = getTextOption(theText->m_OptionID[i]); data << (uint32)theOption->m_OptionID; //Bullet Point Number data << (uint32)theOption->m_OptionIconID; //Bullet Point IconID //option text data.WriteData(theOption->m_OptionText.c_str() , strlen((char *)theOption->m_OptionText.c_str())+1 ); } data << (uint32)0; //Null Terminator pClient->SendMsg (&data); }break; case CMSG_NPC_TEXT_QUERY: { uint32 textID, tSize; recv_data >> textID; /* i don't think this is used but if Spirit healers don't work try it :P //this is having to do with spirit healers uint32 uField0, uField1; recv_data >> uField0 >> uField1; Unit pSelection = world.GetValidCreature(uField0); if(pSelection != 0) { if(pSelection.getUpdateValue(UNIT_NPC_FLAGS) == 32) //if the selection is a spirit healer { pClient->getCurrentChar()->setUpdateValue(UNIT_FIELD_TARGET, uField0); pClient->getCurrentChar()->setUpdateValue(UNIT_FIELD_TARGET + 1, uField1); } } */ //get the text from the text id NPCText * theText = getNPCText(textID); //calculate hte size tSize = strlen((char *)theText->m_Text.c_str())+9; //create the packet data.Initialize(tSize, SMSG_NPC_TEXT_UPDATE); data << textID << (uint32)0x42c80000; //text id and text display fix ?? data.WriteData((char *)theText->m_Text.c_str(), strlen((char *)theText->m_Text.c_str())+1); pClient->SendMsg( &data ); }break; default: break; } }