rendered paste bodyvoid Player::_SaveInventory()
{
// force items in buyback slots to new state
// and remove those that aren't already
for (uint8 i = BUYBACK_SLOT_START; i < BUYBACK_SLOT_END; i++)
{
Item *item = m_items[i];
if (!item || item->GetState() == ITEM_NEW) continue;
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item->GetGUIDLow());
m_items[i]->FSetState(ITEM_NEW);
}
// update enchantment durations
for(EnchantDurationList::iterator itr = m_enchantDuration.begin();itr != m_enchantDuration.end();++itr)
{
itr->item->SetEnchantmentDuration(itr->slot,itr->leftduration);
}
// if no changes
if (m_itemUpdateQueue.empty()) return;
// do not save if the update queue is corrupt
bool error = false;
for(size_t i = 0; i < m_itemUpdateQueue.size(); i++)
{
Item *item = m_itemUpdateQueue[i];
if(!item || item->GetState() == ITEM_REMOVED) continue;
Item *test = GetItemByPos( item->GetBagSlot(), item->GetSlot());
if (test == NULL)
{
sLog.outError("Player::_SaveInventory - the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the player doesn't have an item at that position!", item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow());
error = true;
}
else if (test != item)
{
sLog.outError("Player::_SaveInventory - the bag(%d) and slot(%d) values for the item with guid %d are incorrect, the item with guid %d is there instead!", item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow());
error = true;
}
}
if (error)
{
sLog.outError("Player::_SaveInventory - one or more errors occurred save aborted!");
ChatHandler(this).SendSysMessage(LANG_ITEM_SAVE_FAILED);
return;
}
for(size_t i = 0; i < m_itemUpdateQueue.size(); i++)
{
Item *item = m_itemUpdateQueue[i];
if(!item) continue;
Bag *container = item->GetContainer();
uint32 bag_guid = container ? container->GetGUIDLow() : 0;
switch(item->GetState())
{
case ITEM_NEW:
CharacterDatabase.PExecute("INSERT INTO character_inventory (guid,bag,slot,item,item_template) VALUES ('%u', '%u', '%u', '%u', '%u')", GetGUIDLow(), bag_guid, item->GetSlot(), item->GetGUIDLow(), item->GetEntry());
break;
case ITEM_CHANGED:
CharacterDatabase.PExecute("UPDATE character_inventory SET guid='%u', bag='%u', slot='%u', item_template='%u' WHERE item='%u'", GetGUIDLow(), bag_guid, item->GetSlot(), item->GetEntry(), item->GetGUIDLow());
break;
case ITEM_REMOVED:
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
break;
case ITEM_UNCHANGED:
break;
}
item->SaveToDB(); // item have unchanged inventory record and can be save standalone
}
m_itemUpdateQueue.clear();
}
void Player::_SaveMail()
{
if (!m_mailsLoaded)
return;
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); itr++)
{
Mail *m = (*itr);
if (m->state == MAIL_STATE_CHANGED)
{
CharacterDatabase.PExecute("UPDATE mail SET itemTextId = '%u',has_items = '%u',expire_time = '" I64FMTD "', deliver_time = '" I64FMTD "',money = '%u',cod = '%u',checked = '%u' WHERE id = '%u'",
m->itemTextId, m->HasItems() ? 1 : 0, (uint64)m->expire_time, (uint64)m->deliver_time, m->money, m->COD, m->checked, m->messageID);
if(m->removedItems.size())
{
for(std::vector<uint32>::iterator itr2 = m->removedItems.begin(); itr2 != m->removedItems.end(); ++itr2)
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", *itr2);
m->removedItems.clear();
}
m->state = MAIL_STATE_UNCHANGED;
}
else if (m->state == MAIL_STATE_DELETED)
{
if (m->HasItems())
for(std::vector<MailItemInfo>::iterator itr2 = m->items.begin(); itr2 != m->items.end(); ++itr2)
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", itr2->item_guid);
if (m->itemTextId)
CharacterDatabase.PExecute("DELETE FROM item_text WHERE id = '%u'", m->itemTextId);
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", m->messageID);
}
}
//deallocate deleted mails...
for (PlayerMails::iterator itr = m_mail.begin(); itr != m_mail.end(); )
{
if ((*itr)->state == MAIL_STATE_DELETED)
{
Mail* m = *itr;
m_mail.erase(itr);
delete m;
itr = m_mail.begin();
}
else
++itr;
}
m_mailsUpdated = false;
}
void Player::_SaveQuestStatus()
{
// we don't need transactions here.
for( QuestStatusMap::iterator i = mQuestStatus.begin( ); i != mQuestStatus.end( ); ++i )
{
switch (i->second.uState)
{
case QUEST_NEW :
CharacterDatabase.PExecute("INSERT INTO character_queststatus (guid,quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4) "
"VALUES ('%u', '%u', '%u', '%u', '%u', '" I64FMTD "', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
GetGUIDLow(), i->first, i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / 1000 + sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3]);
break;
case QUEST_CHANGED :
CharacterDatabase.PExecute("UPDATE character_queststatus SET status = '%u',rewarded = '%u',explored = '%u',timer = '" I64FMTD "',mobcount1 = '%u',mobcount2 = '%u',mobcount3 = '%u',mobcount4 = '%u',itemcount1 = '%u',itemcount2 = '%u',itemcount3 = '%u',itemcount4 = '%u' WHERE guid = '%u' AND quest = '%u' ",
i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / 1000 + sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3], GetGUIDLow(), i->first );
break;
case QUEST_UNCHANGED:
break;
};
i->second.uState = QUEST_UNCHANGED;
}
}
void Player::_SaveDailyQuestStatus()
{
if(!m_DailyQuestChanged)
return;
m_DailyQuestChanged = false;
// save last daily quest time for all quests: we need only mostly reset time for reset check anyway
// we don't need transactions here.
CharacterDatabase.PExecute("DELETE FROM character_queststatus_daily WHERE guid = '%u'",GetGUIDLow());
for(uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx)
if(GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx))
CharacterDatabase.PExecute("INSERT INTO character_queststatus_daily (guid,quest,time) VALUES ('%u', '%u','" I64FMTD "')",
GetGUIDLow(), GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx),uint64(m_lastDailyQuestTime));
}
void Player::_SaveReputation()
{
for(FactionsList::iterator itr = m_factions.begin(); itr != m_factions.end(); ++itr)
{
if (itr->second.Changed)
{
CharacterDatabase.PExecute("DELETE FROM character_reputation WHERE guid = '%u' AND faction='%u'", GetGUIDLow(), itr->second.ID);
CharacterDatabase.PExecute("INSERT INTO character_reputation (guid,faction,standing,flags) VALUES ('%u', '%u', '%i', '%u')", GetGUIDLow(), itr->second.ID, itr->second.Standing, itr->second.Flags);
itr->second.Changed = false;
}
}
}
void Player::_SaveSpells()
{
for (PlayerSpellMap::const_iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
{
++next;
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED)
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first);
if (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED)
CharacterDatabase.PExecute("INSERT INTO character_spell (guid,spell,slot,active) VALUES ('%u', '%u', '%u','%u')", GetGUIDLow(), itr->first, itr->second->slotId,itr->second->active ? 1 : 0);
if (itr->second->state == PLAYERSPELL_REMOVED)
_removeSpell(itr->first);
else
itr->second->state = PLAYERSPELL_UNCHANGED;
}
}