DB Layer:

- Make SQL Transactions actual objects used in code. (Thanks to Derex for the idea)
* Uncommitted transactions will be automatically rolled back and cleaned up using ACE_Refcounted_Auto_Ptr, so no need to call Rollback() in the code.
* Prevents recursive transactions and makes developers aware of transactions going on.
* Gets rid of unneccesary overhead iterating over a concurrent map.
- Some cleanups in affected code, including better usage of transaction control in AH / mail related code to prevent data loss.

*** Experimental, use at own risk, recommended to backup your DBs. ***

--HG--
branch : trunk
This commit is contained in:
Machiavelli
2010-08-21 03:19:25 +02:00
parent a7498d2f56
commit 994186f267
49 changed files with 861 additions and 774 deletions
+7 -7
View File
@@ -105,8 +105,8 @@ bool Corpse::Create(uint32 guidlow, Player *owner)
void Corpse::SaveToDB()
{
// prevent DB data inconsistence problems and duplicates
CharacterDatabase.BeginTransaction();
DeleteFromDB();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
DeleteFromDB(trans);
std::ostringstream ss;
ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,displayId,itemCache,bytes1,bytes2,guild,flags,dynFlags,time,corpse_type,instance,phaseMask) VALUES ("
@@ -131,8 +131,8 @@ void Corpse::SaveToDB()
<< uint32(GetType()) << ", "
<< int(GetInstanceId()) << ", "
<< uint16(GetPhaseMask()) << ")"; // prevent out of range error
CharacterDatabase.Execute(ss.str().c_str());
CharacterDatabase.CommitTransaction();
trans->Append(ss.str().c_str());
CharacterDatabase.CommitTransaction(trans);
}
void Corpse::DeleteBonesFromWorld()
@@ -149,14 +149,14 @@ void Corpse::DeleteBonesFromWorld()
AddObjectToRemoveList();
}
void Corpse::DeleteFromDB()
void Corpse::DeleteFromDB(SQLTransaction& trans)
{
if (GetType() == CORPSE_BONES)
// only specific bones
CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%d'", GetGUIDLow());
trans->PAppend("DELETE FROM corpse WHERE guid = '%d'", GetGUIDLow());
else
// all corpses (not bones)
CharacterDatabase.PExecute("DELETE FROM corpse WHERE player = '%d' AND corpse_type <> '0'", GUID_LOPART(GetOwnerGUID()));
trans->PAppend("DELETE FROM corpse WHERE player = '%d' AND corpse_type <> '0'", GUID_LOPART(GetOwnerGUID()));
}
bool Corpse::LoadFromDB(uint32 guid, Field *fields)
+1 -1
View File
@@ -64,7 +64,7 @@ class Corpse : public WorldObject, public GridObject<Corpse>
bool LoadFromDB(uint32 guid, Field *fields);
void DeleteBonesFromWorld();
void DeleteFromDB();
void DeleteFromDB(SQLTransaction& trans);
uint64 const& GetOwnerGUID() const { return GetUInt64Value(CORPSE_FIELD_OWNER); }
+10 -10
View File
@@ -1052,9 +1052,9 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
data.spawnMask = spawnMask;
// updated in DB
WorldDatabase.BeginTransaction();
SQLTransaction trans = WorldDatabase.BeginTransaction();
WorldDatabase.PExecute("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
trans->PAppend("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
std::ostringstream ss;
ss << "INSERT INTO creature VALUES ("
@@ -1077,9 +1077,9 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
<< (m_isDeadByDefault ? 1 : 0) << "," //is_dead
<< GetDefaultMovementType() << ")"; //default movement generator type
WorldDatabase.PExecute(ss.str().c_str());
trans->Append(ss.str().c_str());
WorldDatabase.CommitTransaction();
WorldDatabase.CommitTransaction(trans);
}
void Creature::SelectLevel(const CreatureInfo *cinfo)
@@ -1348,12 +1348,12 @@ void Creature::DeleteFromDB()
sObjectMgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),0);
sObjectMgr.DeleteCreatureData(m_DBTableGuid);
WorldDatabase.BeginTransaction();
WorldDatabase.PExecute("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecute("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecute("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecute("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.CommitTransaction();
SQLTransaction trans = WorldDatabase.BeginTransaction();
trans->PAppend("DELETE FROM creature WHERE guid = '%u'", m_DBTableGuid);
trans->PAppend("DELETE FROM creature_addon WHERE guid = '%u'", m_DBTableGuid);
trans->PAppend("DELETE FROM game_event_creature WHERE guid = '%u'", m_DBTableGuid);
trans->PAppend("DELETE FROM game_event_model_equip WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.CommitTransaction(trans);
}
bool Creature::canSeeOrDetect(Unit const* u, bool detect, bool /*inVisibleList*/, bool /*is3dDistance*/) const
@@ -644,10 +644,10 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
<< uint32(GetGoAnimProgress()) << ", "
<< uint32(GetGoState()) << ")";
WorldDatabase.BeginTransaction();
WorldDatabase.PExecute("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid);
WorldDatabase.PExecute(ss.str().c_str());
WorldDatabase.CommitTransaction();
SQLTransaction trans = WorldDatabase.BeginTransaction();
trans->PAppend("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid);
trans->Append(ss.str().c_str());
WorldDatabase.CommitTransaction(trans);
}
bool GameObject::LoadFromDB(uint32 guid, Map *map)
@@ -102,9 +102,9 @@ bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner)
return true;
}
void Bag::SaveToDB()
void Bag::SaveToDB(SQLTransaction& trans)
{
Item::SaveToDB();
Item::SaveToDB(trans);
}
bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result, uint32 entry)
@@ -125,13 +125,13 @@ bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result,
return true;
}
void Bag::DeleteFromDB()
void Bag::DeleteFromDB(SQLTransaction& trans)
{
for (uint8 i = 0; i < MAX_BAG_SIZE; ++i)
if (m_bagslot[i])
m_bagslot[i]->DeleteFromDB();
m_bagslot[i]->DeleteFromDB(trans);
Item::DeleteFromDB();
Item::DeleteFromDB(trans);
}
uint32 Bag::GetFreeSlots() const
@@ -54,11 +54,11 @@ class Bag : public Item
// DB operations
// overwrite virtual Item::SaveToDB
void SaveToDB();
void SaveToDB(SQLTransaction& trans);
// overwrite virtual Item::LoadFromDB
bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result, uint32 entry);
// overwrite virtual Item::DeleteFromDB
void DeleteFromDB();
void DeleteFromDB(SQLTransaction& trans);
void BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) const;
+14 -14
View File
@@ -301,7 +301,7 @@ void Item::UpdateDuration(Player* owner, uint32 diff)
SetState(ITEM_CHANGED, owner); // save new time in database
}
void Item::SaveToDB()
void Item::SaveToDB(SQLTransaction& trans)
{
uint32 guid = GetGUIDLow();
switch (uState)
@@ -334,7 +334,7 @@ void Item::SaveToDB()
ss << GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME) << ",'";
ss << text << "')";
CharacterDatabase.Execute(ss.str().c_str());
trans->Append(ss.str().c_str());
}break;
case ITEM_CHANGED:
{
@@ -364,16 +364,16 @@ void Item::SaveToDB()
ss << ", playedTime = " << GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME);
ss << ", text = '" << text << "' WHERE guid = " << guid;
CharacterDatabase.Execute(ss.str().c_str());
trans->Append(ss.str().c_str());
if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
CharacterDatabase.PExecute("UPDATE character_gifts SET guid = '%u' WHERE item_guid = '%u'", GUID_LOPART(GetOwnerGUID()),GetGUIDLow());
trans->PAppend("UPDATE character_gifts SET guid = '%u' WHERE item_guid = '%u'", GUID_LOPART(GetOwnerGUID()),GetGUIDLow());
}break;
case ITEM_REMOVED:
{
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", guid);
trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", guid);
if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_WRAPPED))
CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE item_guid = '%u'", GetGUIDLow());
trans->PAppend("DELETE FROM character_gifts WHERE item_guid = '%u'", GetGUIDLow());
delete this;
return;
}
@@ -471,14 +471,14 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result
return true;
}
void Item::DeleteFromDB()
void Item::DeleteFromDB(SQLTransaction& trans)
{
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'",GetGUIDLow());
trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'",GetGUIDLow());
}
void Item::DeleteFromInventoryDB()
void Item::DeleteFromInventoryDB(SQLTransaction& trans)
{
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'",GetGUIDLow());
trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'",GetGUIDLow());
}
ItemPrototype const *Item::GetProto() const
@@ -1103,11 +1103,11 @@ void Item::BuildUpdate(UpdateDataMapType& data_map)
void Item::SaveRefundDataToDB()
{
CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM item_refund_instance WHERE item_guid = '%u'", GetGUIDLow());
CharacterDatabase.PExecute("INSERT INTO item_refund_instance (`item_guid`,`player_guid`,`paidMoney`,`paidExtendedCost`)"
SQLTransaction trans = CharacterDatabase.BeginTransaction();
trans->PAppend("DELETE FROM item_refund_instance WHERE item_guid = '%u'", GetGUIDLow());
trans->PAppend("INSERT INTO item_refund_instance (`item_guid`,`player_guid`,`paidMoney`,`paidExtendedCost`)"
" VALUES('%u','%u','%u','%u')", GetGUIDLow(), GetRefundRecipient(), GetPaidMoney(), GetPaidExtendedCost());
CharacterDatabase.CommitTransaction();
CharacterDatabase.CommitTransaction(trans);
}
void Item::DeleteRefundDataFromDB()
+3 -3
View File
@@ -244,10 +244,10 @@ class Item : public Object
bool IsBoundAccountWide() const { return (GetProto()->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT) != 0; }
bool IsBindedNotWith(Player const* player) const;
bool IsBoundByEnchant() const;
virtual void SaveToDB();
virtual void SaveToDB(SQLTransaction& trans);
virtual bool LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result, uint32 entry);
virtual void DeleteFromDB();
void DeleteFromInventoryDB();
virtual void DeleteFromDB(SQLTransaction& trans);
void DeleteFromInventoryDB(SQLTransaction& trans);
void SaveRefundDataToDB();
void DeleteRefundDataFromDB();
+33 -35
View File
@@ -262,12 +262,12 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c
// PET_SAVE_NOT_IN_SLOT(100) = not stable slot (summoning))
if (fields[7].GetUInt32() != 0)
{
CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'",
SQLTransaction trans = CharacterDatabase.BeginTransaction();
trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u' AND id <> '%u'",
PET_SAVE_NOT_IN_SLOT, ownerid, PET_SAVE_AS_CURRENT, m_charmInfo->GetPetNumber());
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND id = '%u'",
trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND id = '%u'",
PET_SAVE_AS_CURRENT, ownerid, m_charmInfo->GetPetNumber());
CharacterDatabase.CommitTransaction();
CharacterDatabase.CommitTransaction(trans);
}
// Send fake summon spell cast - this is needed for correct cooldown application for spells
@@ -377,19 +377,17 @@ void Pet::SavePetToDB(PetSaveMode mode)
uint32 curhealth = GetHealth();
uint32 curmana = GetPower(POWER_MANA);
CharacterDatabase.BeginTransaction();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// save auras before possibly removing them
_SaveAuras();
_SaveAuras(trans);
// stable and not in slot saves
if (mode > PET_SAVE_AS_CURRENT)
{
RemoveAllAuras();
}
_SaveSpells();
_SaveSpellCooldowns();
CharacterDatabase.CommitTransaction();
_SaveSpells(trans);
_SaveSpellCooldowns(trans);
CharacterDatabase.CommitTransaction(trans);
// current/stable/not_in_slot
if (mode >= PET_SAVE_AS_CURRENT)
@@ -397,18 +395,18 @@ void Pet::SavePetToDB(PetSaveMode mode)
uint32 owner = GUID_LOPART(GetOwnerGUID());
std::string name = m_name;
CharacterDatabase.escape_string(name);
CharacterDatabase.BeginTransaction();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// remove current data
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND id = '%u'", owner,m_charmInfo->GetPetNumber());
trans->PAppend("DELETE FROM character_pet WHERE owner = '%u' AND id = '%u'", owner,m_charmInfo->GetPetNumber());
// prevent duplicate using slot (except PET_SAVE_NOT_IN_SLOT)
if (mode <= PET_SAVE_LAST_STABLE_SLOT)
CharacterDatabase.PExecute("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u'",
trans->PAppend("UPDATE character_pet SET slot = '%u' WHERE owner = '%u' AND slot = '%u'",
PET_SAVE_NOT_IN_SLOT, owner, uint32(mode));
// prevent existence another hunter pet in PET_SAVE_AS_CURRENT and PET_SAVE_NOT_IN_SLOT
if (getPetType() == HUNTER_PET && (mode == PET_SAVE_AS_CURRENT||mode > PET_SAVE_LAST_STABLE_SLOT))
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u')",
trans->PAppend("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '%u' OR slot > '%u')",
owner,PET_SAVE_AS_CURRENT,PET_SAVE_LAST_STABLE_SLOT);
// save pet
std::ostringstream ss;
@@ -441,8 +439,8 @@ void Pet::SavePetToDB(PetSaveMode mode)
<< GetUInt32Value(UNIT_CREATED_BY_SPELL) << ", "
<< uint32(getPetType()) << ")";
CharacterDatabase.Execute(ss.str().c_str());
CharacterDatabase.CommitTransaction();
trans->Append(ss.str().c_str());
CharacterDatabase.CommitTransaction(trans);
}
// delete
else
@@ -454,13 +452,13 @@ void Pet::SavePetToDB(PetSaveMode mode)
void Pet::DeleteFromDB(uint32 guidlow)
{
CharacterDatabase.BeginTransaction();
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE id = '%u'", guidlow);
CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE id = '%u'", guidlow);
CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", guidlow);
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u'", guidlow);
CharacterDatabase.PExecute("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", guidlow);
CharacterDatabase.CommitTransaction();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
trans->PAppend("DELETE FROM character_pet WHERE id = '%u'", guidlow);
trans->PAppend("DELETE FROM character_pet_declinedname WHERE id = '%u'", guidlow);
trans->PAppend("DELETE FROM pet_aura WHERE guid = '%u'", guidlow);
trans->PAppend("DELETE FROM pet_spell WHERE guid = '%u'", guidlow);
trans->PAppend("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", guidlow);
CharacterDatabase.CommitTransaction(trans);
}
void Pet::setDeathState(DeathState s) // overwrite virtual Creature::setDeathState and Unit::setDeathState
@@ -1143,9 +1141,9 @@ void Pet::_LoadSpellCooldowns()
}
}
void Pet::_SaveSpellCooldowns()
void Pet::_SaveSpellCooldowns(SQLTransaction& trans)
{
CharacterDatabase.PExecute("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", m_charmInfo->GetPetNumber());
trans->PAppend("DELETE FROM pet_spell_cooldown WHERE guid = '%u'", m_charmInfo->GetPetNumber());
time_t curTime = time(NULL);
@@ -1156,7 +1154,7 @@ void Pet::_SaveSpellCooldowns()
m_CreatureSpellCooldowns.erase(itr++);
else
{
CharacterDatabase.PExecute("INSERT INTO pet_spell_cooldown (guid,spell,time) VALUES ('%u', '%u', '" UI64FMTD "')", m_charmInfo->GetPetNumber(), itr->first, uint64(itr->second));
trans->PAppend("INSERT INTO pet_spell_cooldown (guid,spell,time) VALUES ('%u', '%u', '" UI64FMTD "')", m_charmInfo->GetPetNumber(), itr->first, uint64(itr->second));
++itr;
}
}
@@ -1178,7 +1176,7 @@ void Pet::_LoadSpells()
}
}
void Pet::_SaveSpells()
void Pet::_SaveSpells(SQLTransaction& trans)
{
for (PetSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end(); itr = next)
{
@@ -1191,15 +1189,15 @@ void Pet::_SaveSpells()
switch (itr->second.state)
{
case PETSPELL_REMOVED:
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first);
trans->PAppend("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first);
m_spells.erase(itr);
continue;
case PETSPELL_CHANGED:
CharacterDatabase.PExecute("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first);
CharacterDatabase.PExecute("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second.active);
trans->PAppend("DELETE FROM pet_spell WHERE guid = '%u' and spell = '%u'", m_charmInfo->GetPetNumber(), itr->first);
trans->PAppend("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second.active);
break;
case PETSPELL_NEW:
CharacterDatabase.PExecute("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second.active);
trans->PAppend("INSERT INTO pet_spell (guid,spell,active) VALUES ('%u', '%u', '%u')", m_charmInfo->GetPetNumber(), itr->first, itr->second.active);
break;
case PETSPELL_UNCHANGED:
continue;
@@ -1278,9 +1276,9 @@ void Pet::_LoadAuras(uint32 timediff)
}
}
void Pet::_SaveAuras()
void Pet::_SaveAuras(SQLTransaction& trans)
{
CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber());
trans->PAppend("DELETE FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber());
for (AuraMap::const_iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end() ; ++itr)
{
@@ -1311,7 +1309,7 @@ void Pet::_SaveAuras()
}
}
CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges) "
trans->PAppend("INSERT INTO pet_aura (guid,caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges) "
"VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')",
m_charmInfo->GetPetNumber(), itr->second->GetCasterGUID(), itr->second->GetId(), effMask, recalculateMask,
itr->second->GetStackAmount(), damage[0], damage[1], damage[2], baseDamage[0], baseDamage[1], baseDamage[2],
+3 -3
View File
@@ -191,11 +191,11 @@ class Pet : public Guardian
bool IsPetAura(Aura const* aura);
void _LoadSpellCooldowns();
void _SaveSpellCooldowns();
void _SaveSpellCooldowns(SQLTransaction& trans);
void _LoadAuras(uint32 timediff);
void _SaveAuras();
void _SaveAuras(SQLTransaction& trans);
void _LoadSpells();
void _SaveSpells();
void _SaveSpells(SQLTransaction& trans);
bool addSpell(uint32 spell_id,ActiveStates active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, PetSpellType type = PETSPELL_NORMAL);
bool learnSpell(uint32 spell_id);
+178 -151
View File
@@ -2736,7 +2736,12 @@ void Player::GiveLevel(uint8 level)
pet->SynchronizeLevelWithOwner();
if (MailLevelReward const* mailReward = sObjectMgr.GetMailLevelReward(level,getRaceMask()))
MailDraft(mailReward->mailTemplateId).SendMailTo(this,MailSender(MAIL_CREATURE,mailReward->senderEntry));
{
//- TODO: Poor design of mail system
SQLTransaction trans = CharacterDatabase.BeginTransaction();
MailDraft(mailReward->mailTemplateId).SendMailTo(trans, this,MailSender(MAIL_CREATURE,mailReward->senderEntry));
CharacterDatabase.CommitTransaction(trans);
}
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
}
@@ -3925,9 +3930,9 @@ void Player::_LoadSpellCooldowns(QueryResult_AutoPtr result)
}
}
void Player::_SaveSpellCooldowns()
void Player::_SaveSpellCooldowns(SQLTransaction& trans)
{
CharacterDatabase.PExecute("DELETE FROM character_spell_cooldown WHERE guid = '%u'", GetGUIDLow());
trans->PAppend("DELETE FROM character_spell_cooldown WHERE guid = '%u'", GetGUIDLow());
time_t curTime = time(NULL);
time_t infTime = curTime + infinityCooldownDelayCheck;
@@ -3959,7 +3964,7 @@ void Player::_SaveSpellCooldowns()
}
// if something changed execute
if (!first_round)
CharacterDatabase.Execute(ss.str().c_str());
trans->Append(ss.str().c_str());
}
uint32 Player::resetTalentsCost() const
@@ -4059,7 +4064,9 @@ bool Player::resetTalents(bool no_cost)
}
}
_SaveSpells();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
_SaveSpells(trans);
CharacterDatabase.CommitTransaction(trans);
SetFreeTalentPoints(talentPointsForLevel);
@@ -4416,6 +4423,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
// Completely remove from the database
case CHAR_DELETE_REMOVE:
{
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// Return back all mails with COD and Item 0 1 2 3 4 5 6 7
QueryResult_AutoPtr resultMail = CharacterDatabase.PQuery("SELECT id,messageType,mailTemplateId,sender,subject,body,money,has_items FROM mail WHERE receiver='%u' AND has_items<>0 AND cod<>0", guid);
if (resultMail)
@@ -4435,13 +4443,13 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
// We can return mail now
// So firstly delete the old one
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", mail_id);
trans->PAppend("DELETE FROM mail WHERE id = '%u'", mail_id);
// Mail is not from player
if (mailType != MAIL_NORMAL)
{
if (has_items)
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id);
trans->PAppend("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id);
continue;
}
@@ -4465,7 +4473,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
ItemPrototype const* itemProto = sObjectMgr.GetItemPrototype(item_template);
if (!itemProto)
{
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item_guidlow);
trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", item_guidlow);
continue;
}
@@ -4473,7 +4481,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
if (!pItem->LoadFromDB(item_guidlow, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER), resultItems, item_template))
{
pItem->FSetState(ITEM_REMOVED);
pItem->SaveToDB(); // it also deletes item object!
pItem->SaveToDB(trans); // it also deletes item object!
continue;
}
@@ -4483,7 +4491,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
}
}
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id);
trans->PAppend("DELETE FROM mail_items WHERE mail_id = '%u'", mail_id);
uint32 pl_account = sObjectMgr.GetPlayerAccountIdByGUID(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
@@ -4497,7 +4505,6 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
QueryResult_AutoPtr resultPets = CharacterDatabase.PQuery("SELECT id FROM character_pet WHERE owner = '%u'",guid);
// NOW we can finally clear other DB data related to character
CharacterDatabase.BeginTransaction();
if (resultPets)
{
do
@@ -4508,41 +4515,41 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC
} while (resultPets->NextRow());
}
CharacterDatabase.PExecute("DELETE FROM characters WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_account_data WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_action WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_gifts WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_homebind WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_instance WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_queststatus WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_reputation WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_spell WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_spell_cooldown WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM gm_tickets WHERE playerGuid = '%u'", guid);
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE owner_guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_social WHERE guid = '%u' OR friend='%u'",guid,guid);
CharacterDatabase.PExecute("DELETE FROM mail WHERE receiver = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE receiver = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE guid = '%u' " // NOTE: These achievements have flags & 256 in DBC.
trans->PAppend("DELETE FROM characters WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_account_data WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_declinedname WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_action WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_aura WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_gifts WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_homebind WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_instance WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_inventory WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_queststatus WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_reputation WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_spell WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_spell_cooldown WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM gm_tickets WHERE playerGuid = '%u'", guid);
trans->PAppend("DELETE FROM item_instance WHERE owner_guid = '%u'",guid);
trans->PAppend("DELETE FROM character_social WHERE guid = '%u' OR friend='%u'",guid,guid);
trans->PAppend("DELETE FROM mail WHERE receiver = '%u'",guid);
trans->PAppend("DELETE FROM mail_items WHERE receiver = '%u'",guid);
trans->PAppend("DELETE FROM character_pet WHERE owner = '%u'",guid);
trans->PAppend("DELETE FROM character_pet_declinedname WHERE owner = '%u'",guid);
trans->PAppend("DELETE FROM character_achievement WHERE guid = '%u' " // NOTE: These achievements have flags & 256 in DBC.
"AND achievement NOT BETWEEN '456' AND '467' " // Realm First Level 80
"AND achievement NOT BETWEEN '1400' AND '1427' " // Realm First Raid Achievements
"AND achievement NOT IN(1463, 3117, 3259) ", guid); // Realm First Northen Vanguard + Raid Achievements
CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_equipmentsets WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM guild_eventlog WHERE PlayerGuid1 = '%u' OR PlayerGuid2 = '%u'",guid, guid);
CharacterDatabase.PExecute("DELETE FROM guild_bank_eventlog WHERE PlayerGuid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_battleground_data WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_glyphs WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_queststatus_daily WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_talent WHERE guid = '%u'",guid);
CharacterDatabase.PExecute("DELETE FROM character_skills WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_achievement_progress WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_equipmentsets WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM guild_eventlog WHERE PlayerGuid1 = '%u' OR PlayerGuid2 = '%u'",guid, guid);
trans->PAppend("DELETE FROM guild_bank_eventlog WHERE PlayerGuid = '%u'",guid);
trans->PAppend("DELETE FROM character_battleground_data WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_glyphs WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_queststatus_daily WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_talent WHERE guid = '%u'",guid);
trans->PAppend("DELETE FROM character_skills WHERE guid = '%u'",guid);
CharacterDatabase.CommitTransaction();
CharacterDatabase.CommitTransaction(trans);
break;
}
// The character gets unlinked from the account, the name gets freed up and appears as deleted ingame
@@ -5071,7 +5078,11 @@ uint32 Player::DurabilityRepair(uint16 pos, bool cost, float discountMod, bool g
return TotalCost;
}
pGuild->MemberMoneyWithdraw(costs, GetGUIDLow());
//- TODO: Fix bad function call design
SQLTransaction trans = CharacterDatabase.BeginTransaction();
pGuild->MemberMoneyWithdraw(costs, GetGUIDLow(), trans);
CharacterDatabase.CommitTransaction(trans);
TotalCost = costs;
}
else if (GetMoney() < costs)
@@ -14429,7 +14440,12 @@ void Player::RewardQuest(Quest const *pQuest, uint32 reward, Object* questGiver,
// Send reward mail
if (uint32 mail_template_id = pQuest->GetRewMailTemplateId())
MailDraft(mail_template_id).SendMailTo(this, questGiver, MAIL_CHECK_MASK_HAS_BODY, pQuest->GetRewMailDelaySecs());
{
//- TODO: Poor design of mail system
SQLTransaction trans = CharacterDatabase.BeginTransaction();
MailDraft(mail_template_id).SendMailTo(trans, this, questGiver, MAIL_CHECK_MASK_HAS_BODY, pQuest->GetRewMailDelaySecs());
CharacterDatabase.CommitTransaction(trans);
}
if (pQuest->IsDaily())
{
@@ -16668,6 +16684,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
if (result)
{
std::list<Item*> problematicItems;
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// prevent items from being added to the queue when stored
m_itemUpdateQueueBlocked = true;
@@ -16683,8 +16700,8 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
if (!proto)
{
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item_guid);
trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", item_guid);
sLog.outError("Player::_LoadInventory: Player %s has an unknown item (id: #%u) in inventory, deleted.", GetName(),item_id);
continue;
}
@@ -16696,7 +16713,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
sLog.outError("Player::_LoadInventory: Player %s has broken item (id: #%u) in inventory, deleted.", GetName(),item_id);
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
item->FSetState(ITEM_REMOVED);
item->SaveToDB(); // it also deletes item object !
item->SaveToDB(trans); // it also deletes item object !
continue;
}
@@ -16705,7 +16722,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
{
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
item->FSetState(ITEM_REMOVED);
item->SaveToDB(); // it also deletes item object !
item->SaveToDB(trans); // it also deletes item object !
continue;
}
@@ -16714,7 +16731,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
{
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item_guid);
item->FSetState(ITEM_REMOVED);
item->SaveToDB(); // it also deletes item object !
item->SaveToDB(trans); // it also deletes item object !
continue;
}
@@ -16723,7 +16740,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
if (item->GetPlayedTime() > (2*HOUR))
{
sLog.outDebug("Item::LoadFromDB, Item GUID: %u: refund time expired, deleting refund data and removing refundable flag.", item->GetGUIDLow());
CharacterDatabase.PExecute("DELETE FROM item_refund_instance WHERE item_guid = '%u'", item->GetGUIDLow());
trans->PAppend("DELETE FROM item_refund_instance WHERE item_guid = '%u'", item->GetGUIDLow());
item->RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE);
}
else
@@ -16839,8 +16856,9 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff)
draft.AddItem(item);
}
draft.SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM), MAIL_CHECK_MASK_COPIED);
draft.SendMailTo(trans, this, MailSender(this, MAIL_STATIONERY_GM), MAIL_CHECK_MASK_COPIED);
}
CharacterDatabase.CommitTransaction(trans);
}
//if (isAlive())
_ApplyAllItemMods();
@@ -16854,6 +16872,7 @@ void Player::_LoadMailedItems(Mail *mail)
if (!result)
return;
SQLTransaction trans = CharacterDatabase.BeginTransaction();
do
{
Field *fields = result->Fetch();
@@ -16867,8 +16886,8 @@ void Player::_LoadMailedItems(Mail *mail)
if (!proto)
{
sLog.outError("Player %u has unknown item_template (ProtoType) in mailed items(GUID: %u template: %u) in mail (%u), deleted.", GetGUIDLow(), item_guid_low, item_template,mail->messageID);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
CharacterDatabase.PExecute("DELETE FROM item_instance WHERE guid = '%u'", item_guid_low);
trans->PAppend("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", item_guid_low);
continue;
}
@@ -16879,12 +16898,14 @@ void Player::_LoadMailedItems(Mail *mail)
sLog.outError("Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, item_guid_low);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low);
item->FSetState(ITEM_REMOVED);
item->SaveToDB(); // it also deletes item object !
item->SaveToDB(trans); // it also deletes item object !
continue;
}
AddMItem(item);
} while (result->NextRow());
CharacterDatabase.CommitTransaction(trans);
}
void Player::_LoadMailInit(QueryResult_AutoPtr resultUnread, QueryResult_AutoPtr resultDelivery)
@@ -17737,36 +17758,36 @@ void Player::SaveToDB()
ss << uint32(GetByteValue(PLAYER_FIELD_BYTES, 2));
ss << ")";
CharacterDatabase.BeginTransaction();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
CharacterDatabase.Execute(ss.str().c_str());
trans->Append(ss.str().c_str());
if (m_mailsUpdated) //save mails only when needed
_SaveMail();
_SaveMail(trans);
_SaveBGData();
_SaveInventory();
_SaveQuestStatus();
_SaveDailyQuestStatus();
_SaveWeeklyQuestStatus();
_SaveTalents();
_SaveSpells();
_SaveSpellCooldowns();
_SaveActions();
_SaveAuras();
_SaveSkills();
m_achievementMgr.SaveToDB();
m_reputationMgr.SaveToDB();
_SaveEquipmentSets();
GetSession()->SaveTutorialsData(); // changed only while character in game
_SaveGlyphs();
_SaveBGData(trans);
_SaveInventory(trans);
_SaveQuestStatus(trans);
_SaveDailyQuestStatus(trans);
_SaveWeeklyQuestStatus(trans);
_SaveTalents(trans);
_SaveSpells(trans);
_SaveSpellCooldowns(trans);
_SaveActions(trans);
_SaveAuras(trans);
_SaveSkills(trans);
m_achievementMgr.SaveToDB(trans);
m_reputationMgr.SaveToDB(trans);
_SaveEquipmentSets(trans);
GetSession()->SaveTutorialsData(trans); // changed only while character in game
_SaveGlyphs(trans);
// check if stats should only be saved on logout
// save stats can be out of transaction
if (m_session->isLogingOut() || !sWorld.getConfig(CONFIG_STATS_SAVE_ONLY_ON_LOGOUT))
_SaveStats();
_SaveStats(trans);
CharacterDatabase.CommitTransaction();
CharacterDatabase.CommitTransaction(trans);
// save pet (hunter pet level and experience and all type pets health/mana).
if (Pet* pet = GetPet())
@@ -17775,37 +17796,37 @@ void Player::SaveToDB()
}
// fast save function for item/money cheating preventing - save only inventory and money state
void Player::SaveInventoryAndGoldToDB()
void Player::SaveInventoryAndGoldToDB(SQLTransaction& trans)
{
_SaveInventory();
SaveGoldToDB();
_SaveInventory(trans);
SaveGoldToDB(trans);
}
void Player::SaveGoldToDB()
void Player::SaveGoldToDB(SQLTransaction& trans)
{
CharacterDatabase.PExecute("UPDATE characters SET money = '%u' WHERE guid = '%u'", GetMoney(), GetGUIDLow());
trans->PAppend("UPDATE characters SET money = '%u' WHERE guid = '%u'", GetMoney(), GetGUIDLow());
}
void Player::_SaveActions()
void Player::_SaveActions(SQLTransaction& trans)
{
for (ActionButtonList::iterator itr = m_actionButtons.begin(); itr != m_actionButtons.end();)
{
switch (itr->second.uState)
{
case ACTIONBUTTON_NEW:
CharacterDatabase.PExecute("INSERT INTO character_action (guid,spec,button,action,type) VALUES ('%u', '%u', '%u', '%u', '%u')",
trans->PAppend("INSERT INTO character_action (guid,spec,button,action,type) VALUES ('%u', '%u', '%u', '%u', '%u')",
GetGUIDLow(), m_activeSpec, (uint32)itr->first, (uint32)itr->second.GetAction(), (uint32)itr->second.GetType());
itr->second.uState = ACTIONBUTTON_UNCHANGED;
++itr;
break;
case ACTIONBUTTON_CHANGED:
CharacterDatabase.PExecute("UPDATE character_action SET action = '%u', type = '%u' WHERE guid = '%u' AND button = '%u' AND spec = '%u'",
trans->PAppend("UPDATE character_action SET action = '%u', type = '%u' WHERE guid = '%u' AND button = '%u' AND spec = '%u'",
(uint32)itr->second.GetAction(), (uint32)itr->second.GetType(), GetGUIDLow(), (uint32)itr->first, m_activeSpec);
itr->second.uState = ACTIONBUTTON_UNCHANGED;
++itr;
break;
case ACTIONBUTTON_DELETED:
CharacterDatabase.PExecute("DELETE FROM character_action WHERE guid = '%u' and button = '%u' and spec = '%u'", GetGUIDLow(), (uint32)itr->first, m_activeSpec);
trans->PAppend("DELETE FROM character_action WHERE guid = '%u' and button = '%u' and spec = '%u'", GetGUIDLow(), (uint32)itr->first, m_activeSpec);
m_actionButtons.erase(itr++);
break;
default:
@@ -17815,9 +17836,9 @@ void Player::_SaveActions()
}
}
void Player::_SaveAuras()
void Player::_SaveAuras(SQLTransaction& trans)
{
CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow());
trans->PAppend("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow());
for (AuraMap::const_iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end() ; ++itr)
{
@@ -17847,7 +17868,7 @@ void Player::_SaveAuras()
}
}
CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges) "
trans->PAppend("INSERT INTO character_aura (guid,caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges) "
"VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')",
GetGUIDLow(), itr->second->GetCasterGUID(), itr->second->GetId(), effMask, recalculateMask,
itr->second->GetStackAmount(), damage[0], damage[1], damage[2], baseDamage[0], baseDamage[1], baseDamage[2],
@@ -17855,7 +17876,7 @@ void Player::_SaveAuras()
}
}
void Player::_SaveInventory()
void Player::_SaveInventory(SQLTransaction& trans)
{
// force items in buyback slots to new state
// and remove those that aren't already
@@ -17864,8 +17885,8 @@ void Player::_SaveInventory()
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());
trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", item->GetGUIDLow());
m_items[i]->FSetState(ITEM_NEW);
}
@@ -17942,25 +17963,25 @@ void Player::_SaveInventory()
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());
trans->PAppend("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("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
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());
trans->PAppend("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
trans->PAppend("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_REMOVED:
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item = '%u'", item->GetGUIDLow());
trans->PAppend("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
item->SaveToDB(trans); // item have unchanged inventory record and can be save standalone
}
m_itemUpdateQueue.clear();
}
void Player::_SaveMail()
void Player::_SaveMail(SQLTransaction& trans)
{
if (!m_mailsLoaded)
return;
@@ -17970,12 +17991,12 @@ void Player::_SaveMail()
Mail *m = (*itr);
if (m->state == MAIL_STATE_CHANGED)
{
CharacterDatabase.PExecute("UPDATE mail SET has_items = '%u',expire_time = '" UI64FMTD "', deliver_time = '" UI64FMTD "',money = '%u',cod = '%u',checked = '%u' WHERE id = '%u'",
trans->PAppend("UPDATE mail SET has_items = '%u',expire_time = '" UI64FMTD "', deliver_time = '" UI64FMTD "',money = '%u',cod = '%u',checked = '%u' WHERE id = '%u'",
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);
trans->PAppend("DELETE FROM mail_items WHERE item_guid = '%u'", *itr2);
m->removedItems.clear();
}
m->state = MAIL_STATE_UNCHANGED;
@@ -17984,9 +18005,9 @@ void Player::_SaveMail()
{
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);
CharacterDatabase.PExecute("DELETE FROM mail WHERE id = '%u'", m->messageID);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE mail_id = '%u'", m->messageID);
trans->PAppend("DELETE FROM item_instance WHERE guid = '%u'", itr2->item_guid);
trans->PAppend("DELETE FROM mail WHERE id = '%u'", m->messageID);
trans->PAppend("DELETE FROM mail_items WHERE mail_id = '%u'", m->messageID);
}
}
@@ -18007,7 +18028,7 @@ void Player::_SaveMail()
m_mailsUpdated = false;
}
void Player::_SaveQuestStatus()
void Player::_SaveQuestStatus(SQLTransaction& trans)
{
// we don't need transactions here.
for (QuestStatusMap::iterator i = mQuestStatus.begin(); i != mQuestStatus.end(); ++i)
@@ -18015,12 +18036,12 @@ void Player::_SaveQuestStatus()
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) "
trans->PAppend("INSERT INTO character_queststatus (guid,quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4) "
"VALUES ('%u', '%u', '%u', '%u', '%u', '" UI64FMTD "', '%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 / IN_MILLISECONDS+ 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 = '" UI64FMTD "',mobcount1 = '%u',mobcount2 = '%u',mobcount3 = '%u',mobcount4 = '%u',itemcount1 = '%u',itemcount2 = '%u',itemcount3 = '%u',itemcount4 = '%u' WHERE guid = '%u' AND quest = '%u' ",
trans->PAppend("UPDATE character_queststatus SET status = '%u',rewarded = '%u',explored = '%u',timer = '" UI64FMTD "',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 / IN_MILLISECONDS + 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:
@@ -18030,7 +18051,7 @@ void Player::_SaveQuestStatus()
}
}
void Player::_SaveDailyQuestStatus()
void Player::_SaveDailyQuestStatus(SQLTransaction& trans)
{
if (!m_DailyQuestChanged)
return;
@@ -18040,32 +18061,32 @@ void Player::_SaveDailyQuestStatus()
// 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());
trans->PAppend("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','" UI64FMTD "')",
trans->PAppend("INSERT INTO character_queststatus_daily (guid,quest,time) VALUES ('%u', '%u','" UI64FMTD "')",
GetGUIDLow(), GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx),uint64(m_lastDailyQuestTime));
}
void Player::_SaveWeeklyQuestStatus()
void Player::_SaveWeeklyQuestStatus(SQLTransaction& trans)
{
if (!m_WeeklyQuestChanged || m_weeklyquests.empty())
return;
// we don't need transactions here.
CharacterDatabase.PExecute("DELETE FROM character_queststatus_weekly WHERE guid = '%u'",GetGUIDLow());
trans->PAppend("DELETE FROM character_queststatus_weekly WHERE guid = '%u'",GetGUIDLow());
for (QuestSet::const_iterator iter = m_weeklyquests.begin(); iter != m_weeklyquests.end(); ++iter)
{
uint32 quest_id = *iter;
CharacterDatabase.PExecute("INSERT INTO character_queststatus_weekly (guid,quest) VALUES ('%u', '%u')", GetGUIDLow(), quest_id);
trans->PAppend("INSERT INTO character_queststatus_weekly (guid,quest) VALUES ('%u', '%u')", GetGUIDLow(), quest_id);
}
m_WeeklyQuestChanged = false;
}
void Player::_SaveSkills()
void Player::_SaveSkills(SQLTransaction& trans)
{
// we don't need transactions here.
for (SkillStatusMap::iterator itr = mSkillStatus.begin(); itr != mSkillStatus.end();)
@@ -18078,7 +18099,7 @@ void Player::_SaveSkills()
if (itr->second.uState == SKILL_DELETED)
{
CharacterDatabase.PExecute("DELETE FROM character_skills WHERE guid = '%u' AND skill = '%u' ", GetGUIDLow(), itr->first);
trans->PAppend("DELETE FROM character_skills WHERE guid = '%u' AND skill = '%u' ", GetGUIDLow(), itr->first);
mSkillStatus.erase(itr++);
continue;
}
@@ -18090,11 +18111,11 @@ void Player::_SaveSkills()
switch (itr->second.uState)
{
case SKILL_NEW:
CharacterDatabase.PExecute("INSERT INTO character_skills (guid, skill, value, max) VALUES ('%u', '%u', '%u', '%u')",
trans->PAppend("INSERT INTO character_skills (guid, skill, value, max) VALUES ('%u', '%u', '%u', '%u')",
GetGUIDLow(), itr->first, value, max);
break;
case SKILL_CHANGED:
CharacterDatabase.PExecute("UPDATE character_skills SET value = '%u',max = '%u'WHERE guid = '%u' AND skill = '%u' ",
trans->PAppend("UPDATE character_skills SET value = '%u',max = '%u'WHERE guid = '%u' AND skill = '%u' ",
value, max, GetGUIDLow(), itr->first);
break;
};
@@ -18104,16 +18125,16 @@ void Player::_SaveSkills()
}
}
void Player::_SaveSpells()
void Player::_SaveSpells(SQLTransaction& trans)
{
for (PlayerSpellMap::iterator itr = m_spells.begin(), next = m_spells.begin(); itr != m_spells.end();)
{
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);
trans->PAppend("DELETE FROM character_spell WHERE guid = '%u' and spell = '%u'", GetGUIDLow(), itr->first);
// add only changed/new not dependent spells
if (!itr->second->dependent && (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED))
CharacterDatabase.PExecute("INSERT INTO character_spell (guid,spell,active,disabled) VALUES ('%u', '%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->active ? 1 : 0,itr->second->disabled ? 1 : 0);
trans->PAppend("INSERT INTO character_spell (guid,spell,active,disabled) VALUES ('%u', '%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->active ? 1 : 0,itr->second->disabled ? 1 : 0);
if (itr->second->state == PLAYERSPELL_REMOVED)
{
@@ -18131,13 +18152,13 @@ void Player::_SaveSpells()
// save player stats -- only for external usage
// real stats will be recalculated on player login
void Player::_SaveStats()
void Player::_SaveStats(SQLTransaction& trans)
{
// check if stat saving is enabled and if char level is high enough
if (!sWorld.getConfig(CONFIG_MIN_LEVEL_STAT_SAVE) || getLevel() < sWorld.getConfig(CONFIG_MIN_LEVEL_STAT_SAVE))
return;
CharacterDatabase.PExecute("DELETE FROM character_stats WHERE guid = '%u'", GetGUIDLow());
trans->PAppend("DELETE FROM character_stats WHERE guid = '%u'", GetGUIDLow());
std::ostringstream ss;
ss << "INSERT INTO character_stats (guid, maxhealth, maxpower1, maxpower2, maxpower3, maxpower4, maxpower5, maxpower6, maxpower7, "
"strength, agility, stamina, intellect, spirit, armor, resHoly, resFire, resNature, resFrost, resShadow, resArcane, "
@@ -18160,7 +18181,7 @@ void Player::_SaveStats()
<< GetUInt32Value(UNIT_FIELD_ATTACK_POWER) << ", "
<< GetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER) << ", "
<< GetBaseSpellPowerBonus() << ")";
CharacterDatabase.Execute(ss.str().c_str());
trans->Append(ss.str().c_str());
}
void Player::outDebugValues() const
@@ -19084,18 +19105,18 @@ void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type)
CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE playerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type);
}
CharacterDatabase.BeginTransaction();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
if (type == 10)
{
CharacterDatabase.PExecute("DELETE FROM petition WHERE ownerguid = '%u'", GUID_LOPART(guid));
CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE ownerguid = '%u'", GUID_LOPART(guid));
trans->PAppend("DELETE FROM petition WHERE ownerguid = '%u'", GUID_LOPART(guid));
trans->PAppend("DELETE FROM petition_sign WHERE ownerguid = '%u'", GUID_LOPART(guid));
}
else
{
CharacterDatabase.PExecute("DELETE FROM petition WHERE ownerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type);
CharacterDatabase.PExecute("DELETE FROM petition_sign WHERE ownerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type);
trans->PAppend("DELETE FROM petition WHERE ownerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type);
trans->PAppend("DELETE FROM petition_sign WHERE ownerguid = '%u' AND type = '%u'", GUID_LOPART(guid), type);
}
CharacterDatabase.CommitTransaction();
CharacterDatabase.CommitTransaction(trans);
}
void Player::LeaveAllArenaTeams(uint64 guid)
@@ -21507,13 +21528,14 @@ void Player::AutoUnequipOffhandIfNeed(bool force /*= false*/)
else
{
MoveItemFromInventory(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND, true);
CharacterDatabase.BeginTransaction();
offItem->DeleteFromInventoryDB(); // deletes item from character's inventory
offItem->SaveToDB(); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
CharacterDatabase.CommitTransaction();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
offItem->DeleteFromInventoryDB(trans); // deletes item from character's inventory
offItem->SaveToDB(trans); // recursive and not have transaction guard into self, item not in inventory and can be save standalone
std::string subject = GetSession()->GetTrinityString(LANG_NOT_EQUIPPED_ITEM);
MailDraft(subject, "There were problems with equipping one or several items").AddItem(offItem).SendMailTo(this, MailSender(this, MAIL_STATIONERY_GM), MAIL_CHECK_MASK_COPIED);
MailDraft(subject, "There were problems with equipping one or several items").AddItem(offItem).SendMailTo(trans, this, MailSender(this, MAIL_STATIONERY_GM), MAIL_CHECK_MASK_COPIED);
CharacterDatabase.CommitTransaction(trans);
}
}
@@ -23519,7 +23541,7 @@ void Player::SetEquipmentSet(uint32 index, EquipmentSet eqset)
eqslot.state = old_state == EQUIPMENT_SET_NEW ? EQUIPMENT_SET_NEW : EQUIPMENT_SET_CHANGED;
}
void Player::_SaveEquipmentSets()
void Player::_SaveEquipmentSets(SQLTransaction& trans)
{
for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end();)
{
@@ -23533,7 +23555,7 @@ void Player::_SaveEquipmentSets()
case EQUIPMENT_SET_CHANGED:
CharacterDatabase.escape_string(eqset.Name);
CharacterDatabase.escape_string(eqset.IconName);
CharacterDatabase.PExecute("UPDATE character_equipmentsets SET name='%s', iconname='%s', item0='%u', item1='%u', item2='%u', item3='%u', item4='%u', item5='%u', item6='%u', item7='%u', item8='%u', item9='%u', item10='%u', item11='%u', item12='%u', item13='%u', item14='%u', item15='%u', item16='%u', item17='%u', item18='%u' WHERE guid='%u' AND setguid='"UI64FMTD"' AND setindex='%u'",
trans->PAppend("UPDATE character_equipmentsets SET name='%s', iconname='%s', item0='%u', item1='%u', item2='%u', item3='%u', item4='%u', item5='%u', item6='%u', item7='%u', item8='%u', item9='%u', item10='%u', item11='%u', item12='%u', item13='%u', item14='%u', item15='%u', item16='%u', item17='%u', item18='%u' WHERE guid='%u' AND setguid='"UI64FMTD"' AND setindex='%u'",
eqset.Name.c_str(), eqset.IconName.c_str(), eqset.Items[0], eqset.Items[1], eqset.Items[2], eqset.Items[3], eqset.Items[4], eqset.Items[5], eqset.Items[6], eqset.Items[7],
eqset.Items[8], eqset.Items[9], eqset.Items[10], eqset.Items[11], eqset.Items[12], eqset.Items[13], eqset.Items[14], eqset.Items[15], eqset.Items[16], eqset.Items[17], eqset.Items[18], GetGUIDLow(), eqset.Guid, index);
eqset.state = EQUIPMENT_SET_UNCHANGED;
@@ -23542,27 +23564,27 @@ void Player::_SaveEquipmentSets()
case EQUIPMENT_SET_NEW:
CharacterDatabase.escape_string(eqset.Name);
CharacterDatabase.escape_string(eqset.IconName);
CharacterDatabase.PExecute("INSERT INTO character_equipmentsets VALUES ('%u', '"UI64FMTD"', '%u', '%s', '%s', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
trans->PAppend("INSERT INTO character_equipmentsets VALUES ('%u', '"UI64FMTD"', '%u', '%s', '%s', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
GetGUIDLow(), eqset.Guid, index, eqset.Name.c_str(), eqset.IconName.c_str(), eqset.Items[0], eqset.Items[1], eqset.Items[2], eqset.Items[3], eqset.Items[4], eqset.Items[5], eqset.Items[6], eqset.Items[7],
eqset.Items[8], eqset.Items[9], eqset.Items[10], eqset.Items[11], eqset.Items[12], eqset.Items[13], eqset.Items[14], eqset.Items[15], eqset.Items[16], eqset.Items[17], eqset.Items[18]);
eqset.state = EQUIPMENT_SET_UNCHANGED;
++itr;
break;
case EQUIPMENT_SET_DELETED:
CharacterDatabase.PExecute("DELETE FROM character_equipmentsets WHERE setguid="UI64FMTD, eqset.Guid);
trans->PAppend("DELETE FROM character_equipmentsets WHERE setguid="UI64FMTD, eqset.Guid);
m_EquipmentSets.erase(itr++);
break;
}
}
}
void Player::_SaveBGData()
void Player::_SaveBGData(SQLTransaction& trans)
{
CharacterDatabase.PExecute("DELETE FROM character_battleground_data WHERE guid='%u'", GetGUIDLow());
trans->PAppend("DELETE FROM character_battleground_data WHERE guid='%u'", GetGUIDLow());
if (m_bgData.bgInstanceID)
{
/* guid, bgInstanceID, bgTeam, x, y, z, o, map, taxi[0], taxi[1], mountSpell */
CharacterDatabase.PExecute("INSERT INTO character_battleground_data VALUES ('%u', '%u', '%u', '%f', '%f', '%f', '%f', '%u', '%u', '%u', '%u')",
trans->PAppend("INSERT INTO character_battleground_data VALUES ('%u', '%u', '%u', '%f', '%f', '%f', '%f', '%u', '%u', '%u', '%u')",
GetGUIDLow(), m_bgData.bgInstanceID, m_bgData.bgTeam, m_bgData.joinPos.GetPositionX(), m_bgData.joinPos.GetPositionY(), m_bgData.joinPos.GetPositionZ(),
m_bgData.joinPos.GetOrientation(), m_bgData.joinPos.GetMapId(), m_bgData.taxiPath[0], m_bgData.taxiPath[1], m_bgData.mountSpell);
}
@@ -23641,12 +23663,12 @@ void Player::_LoadGlyphs(QueryResult_AutoPtr result)
} while (result->NextRow());
}
void Player::_SaveGlyphs()
void Player::_SaveGlyphs(SQLTransaction& trans)
{
CharacterDatabase.PExecute("DELETE FROM character_glyphs WHERE guid='%u'",GetGUIDLow());
trans->PAppend("DELETE FROM character_glyphs WHERE guid='%u'",GetGUIDLow());
for (uint8 spec = 0; spec < m_specsCount; ++spec)
{
CharacterDatabase.PExecute("INSERT INTO character_glyphs VALUES('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
trans->PAppend("INSERT INTO character_glyphs VALUES('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
GetGUIDLow(), spec, m_Glyphs[spec][0], m_Glyphs[spec][1], m_Glyphs[spec][2], m_Glyphs[spec][3], m_Glyphs[spec][4], m_Glyphs[spec][5]);
}
}
@@ -23666,17 +23688,17 @@ void Player::_LoadTalents(QueryResult_AutoPtr result)
}
}
void Player::_SaveTalents()
void Player::_SaveTalents(SQLTransaction& trans)
{
for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i)
{
for (PlayerTalentMap::iterator itr = m_talents[i]->begin(); itr != m_talents[i]->end();)
{
if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED)
CharacterDatabase.PExecute("DELETE FROM character_talent WHERE guid = '%u' and spell = '%u' and spec = '%u'", GetGUIDLow(), itr->first, itr->second->spec);
trans->PAppend("DELETE FROM character_talent WHERE guid = '%u' and spell = '%u' and spec = '%u'", GetGUIDLow(), itr->first, itr->second->spec);
if (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED)
CharacterDatabase.PExecute("INSERT INTO character_talent (guid,spell,spec) VALUES ('%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->spec);
trans->PAppend("INSERT INTO character_talent (guid,spell,spec) VALUES ('%u', '%u', '%u')", GetGUIDLow(), itr->first, itr->second->spec);
if (itr->second->state == PLAYERSPELL_REMOVED)
{
@@ -23701,23 +23723,26 @@ void Player::UpdateSpecCount(uint8 count)
if (m_activeSpec >= count)
ActivateSpec(0);
SQLTransaction trans = CharacterDatabase.BeginTransaction();
// Copy spec data
if (count > curCount)
{
_SaveActions(); // make sure the button list is cleaned up
_SaveActions(trans); // make sure the button list is cleaned up
for (ActionButtonList::iterator itr = m_actionButtons.begin(); itr != m_actionButtons.end(); ++itr)
CharacterDatabase.PExecute("INSERT INTO character_action (guid,button,action,type,spec) VALUES ('%u', '%u', '%u', '%u', '%u')",
trans->PAppend("INSERT INTO character_action (guid,button,action,type,spec) VALUES ('%u', '%u', '%u', '%u', '%u')",
GetGUIDLow(), uint32(itr->first), uint32(itr->second.GetAction()), uint32(itr->second.GetType()), 1);
}
// Delete spec data for removed spec.
else if (count < curCount)
{
_SaveActions();
CharacterDatabase.PExecute("DELETE FROM character_action WHERE spec<>'%u' AND guid='%u'",m_activeSpec, GetGUIDLow());
_SaveActions(trans);
trans->PAppend("DELETE FROM character_action WHERE spec<>'%u' AND guid='%u'",m_activeSpec, GetGUIDLow());
m_activeSpec = 0;
}
CharacterDatabase.CommitTransaction(trans);
SetSpecsCount(count);
@@ -23740,7 +23765,9 @@ void Player::ActivateSpec(uint8 spec)
if (IsNonMeleeSpellCasted(false))
InterruptNonMeleeSpells(false);
_SaveActions();
SQLTransaction trans = CharacterDatabase.BeginTransaction();
_SaveActions(trans);
CharacterDatabase.CommitTransaction(trans);
UnsummonPetTemporaryIfAny();
ClearComboPointHolders();
+18 -17
View File
@@ -1422,8 +1422,9 @@ class Player : public Unit, public GridObject<Player>
/*********************************************************/
void SaveToDB();
void SaveInventoryAndGoldToDB(); // fast save function for item/money cheating preventing
void SaveGoldToDB();
void SaveInventoryAndGoldToDB(SQLTransaction& trans); // fast save function for item/money cheating preventing
void SaveGoldToDB(SQLTransaction& trans);
static void SetUInt32ValueInArray(Tokens& data,uint16 index, uint32 value);
static void SetFloatValueInArray(Tokens& data,uint16 index, float value);
static void Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair);
@@ -1617,7 +1618,7 @@ class Player : public Unit, public GridObject<Player>
void RemoveArenaSpellCooldowns();
void RemoveAllSpellCooldown();
void _LoadSpellCooldowns(QueryResult_AutoPtr result);
void _SaveSpellCooldowns();
void _SaveSpellCooldowns(SQLTransaction& trans);
void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; }
void UpdatePotionCooldown(Spell* spell = NULL);
@@ -2428,20 +2429,20 @@ class Player : public Unit, public GridObject<Player>
/*** SAVE SYSTEM ***/
/*********************************************************/
void _SaveActions();
void _SaveAuras();
void _SaveInventory();
void _SaveMail();
void _SaveQuestStatus();
void _SaveDailyQuestStatus();
void _SaveWeeklyQuestStatus();
void _SaveSkills();
void _SaveSpells();
void _SaveEquipmentSets();
void _SaveBGData();
void _SaveGlyphs();
void _SaveTalents();
void _SaveStats();
void _SaveActions(SQLTransaction& trans);
void _SaveAuras(SQLTransaction& trans);
void _SaveInventory(SQLTransaction& trans);
void _SaveMail(SQLTransaction& trans);
void _SaveQuestStatus(SQLTransaction& trans);
void _SaveDailyQuestStatus(SQLTransaction& trans);
void _SaveWeeklyQuestStatus(SQLTransaction& trans);
void _SaveSkills(SQLTransaction& trans);
void _SaveSpells(SQLTransaction& trans);
void _SaveEquipmentSets(SQLTransaction& trans);
void _SaveBGData(SQLTransaction& trans);
void _SaveGlyphs(SQLTransaction& trans);
void _SaveTalents(SQLTransaction& trans);
void _SaveStats(SQLTransaction& trans);
void _SetCreateBits(UpdateMask *updateMask, Player *target) const;
void _SetUpdateBits(UpdateMask *updateMask, Player *target) const;