Merge remote branch 'origin/master' into 330

Conflicts:
	src/game/Player.cpp
	src/game/PlayerDump.cpp
This commit is contained in:
tomrus88 2010-03-13 00:54:13 +03:00
commit 086e9fa1ce
45 changed files with 616 additions and 422 deletions

View file

@ -79,6 +79,18 @@ bool GossipHello ( Player * player, Creature *_Creature )
return tmpscript->pGossipHello(player,_Creature);
}
MANGOS_DLL_EXPORT
bool GOGossipHello(Player *pPlayer, GameObject *pGo)
{
Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId];
if (!tmpscript || !tmpscript->pGOGossipHello)
return false;
pPlayer->PlayerTalkClass->ClearMenus();
return tmpscript->pGOGossipHello(pPlayer, pGo);
}
MANGOS_DLL_EXPORT
bool GossipSelect( Player *player, Creature *_Creature,uint32 sender, uint32 action )
{
@ -93,6 +105,20 @@ bool GossipSelect( Player *player, Creature *_Creature,uint32 sender, uint32 act
return tmpscript->pGossipSelect(player,_Creature,sender,action);
}
MANGOS_DLL_EXPORT
bool GOGossipSelect(Player *pPlayer, GameObject *pGo, uint32 sender, uint32 action)
{
debug_log("DEBUG: GO Gossip selection, sender: %u, action: %u", sender, action);
Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId];
if (!tmpscript || !tmpscript->pGOGossipSelect)
return false;
pPlayer->PlayerTalkClass->ClearMenus();
return tmpscript->pGOGossipSelect(pPlayer, pGo, sender, action);
}
MANGOS_DLL_EXPORT
bool GossipSelectWithCode( Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode )
{
@ -107,6 +133,20 @@ bool GossipSelectWithCode( Player *player, Creature *_Creature, uint32 sender, u
return tmpscript->pGossipSelectWithCode(player,_Creature,sender,action,sCode);
}
MANGOS_DLL_EXPORT
bool GOGossipSelectWithCode(Player *pPlayer, GameObject *pGo, uint32 sender, uint32 action, const char* sCode)
{
debug_log("DEBUG: GO Gossip selection, sender: %u, action: %u", sender, action);
Script *tmpscript = m_scripts[pGo->GetGOInfo()->ScriptId];
if (!tmpscript || !tmpscript->pGOGossipSelectWithCode)
return false;
pPlayer->PlayerTalkClass->ClearMenus();
return tmpscript->pGOGossipSelectWithCode(pPlayer, pGo, sender, action, sCode);
}
MANGOS_DLL_EXPORT
bool QuestAccept( Player *player, Creature *_Creature, Quest *_Quest )
{

View file

@ -39,7 +39,8 @@ class Aura;
struct Script
{
Script() :
pGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGossipSelectWithCode(NULL),
pGossipHello(NULL), pGOGossipHello(NULL), pQuestAccept(NULL), pGossipSelect(NULL), pGOGossipSelect(NULL),
pGossipSelectWithCode(NULL), pGOGossipSelectWithCode(NULL),
pQuestSelect(NULL), pQuestComplete(NULL), pNPCDialogStatus(NULL), pGODialogStatus(NULL), pChooseReward(NULL),
pItemHello(NULL), pGOHello(NULL), pAreaTrigger(NULL), pItemQuestAccept(NULL), pGOQuestAccept(NULL),
pGOChooseReward(NULL), pItemUse(NULL), pEffectDummyGameObj(NULL), pEffectDummyCreature(NULL),
@ -50,9 +51,12 @@ struct Script
// -- Quest/gossip Methods to be scripted --
bool (*pGossipHello )(Player *player, Creature *_Creature);
bool (*pGOGossipHello )(Player *player, GameObject *_GO);
bool (*pQuestAccept )(Player *player, Creature *_Creature, Quest const*_Quest );
bool (*pGossipSelect )(Player *player, Creature *_Creature, uint32 sender, uint32 action );
bool (*pGOGossipSelect )(Player *player, GameObject *_GO, uint32 sender, uint32 action );
bool (*pGossipSelectWithCode)(Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode );
bool (*pGOGossipSelectWithCode)(Player *player, GameObject *_GO, uint32 sender, uint32 action, const char* sCode );
bool (*pQuestSelect )(Player *player, Creature *_Creature, Quest const*_Quest );
bool (*pQuestComplete )(Player *player, Creature *_Creature, Quest const*_Quest );
uint32 (*pNPCDialogStatus )(Player *player, Creature *_Creature );

View file

@ -67,7 +67,7 @@ class TypeUnorderedMapContainer
// Insert helpers
template<class SPECIFIC_TYPE> static bool insert(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE handle, SPECIFIC_TYPE* obj)
{
typename UNORDERED_MAP<OBJECT_HANDLE, SPECIFIC_TYPE*>::iterator i = elements._element.find(handle);
typename UNORDERED_MAP<KEY_TYPE, SPECIFIC_TYPE*>::iterator i = elements._element.find(handle);
if (i == elements._element.end())
{
elements._element[handle] = obj;
@ -95,7 +95,7 @@ class TypeUnorderedMapContainer
// Find helpers
template<class SPECIFIC_TYPE> static SPECIFIC_TYPE* find(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE hdl, SPECIFIC_TYPE* /*obj*/)
{
typename UNORDERED_MAP<OBJECT_HANDLE, SPECIFIC_TYPE*>::iterator i = elements._element.find(hdl);
typename UNORDERED_MAP<KEY_TYPE, SPECIFIC_TYPE*>::iterator i = elements._element.find(hdl);
if (i == elements._element.end())
return NULL;
else

View file

@ -201,7 +201,7 @@ template<class Do>
void BattleGround::BroadcastWorker(Do& _do)
{
for(BattleGroundPlayerMap::const_iterator itr = m_Players.begin(); itr != m_Players.end(); ++itr)
if (Player *plr = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)))
if (Player *plr = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)))
_do(plr);
}

View file

@ -594,7 +594,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
{
sObjectMgr.RemoveCreatureFromGrid(*itr, data);
if( Creature* pCreature = ObjectAccessor::GetCreatureInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_UNIT)) )
if (Creature* pCreature = ObjectAccessor::GetCreatureInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, *itr)))
pCreature->AddObjectToRemoveList();
}
}
@ -612,7 +612,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id)
{
sObjectMgr.RemoveGameobjectFromGrid(*itr, data);
if( GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_GAMEOBJECT)) )
if( GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, *itr)) )
pGameobject->AddObjectToRemoveList();
}
}
@ -638,8 +638,7 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate)
continue;
// Update if spawned
Creature* pCreature = ObjectAccessor::GetCreatureInWorld(MAKE_NEW_GUID(itr->first, data->id,HIGHGUID_UNIT));
if (pCreature)
if (Creature* pCreature = ObjectAccessor::GetCreatureInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, itr->first)))
{
if (activate)
{

View file

@ -930,8 +930,12 @@ void GameObject::Use(Unit* user)
Player* player = (Player*)user;
player->PrepareGossipMenu(this, GetGOInfo()->questgiver.gossipID);
player->SendPreparedGossip(this);
if (!Script->GOGossipHello(player, this))
{
player->PrepareGossipMenu(this, GetGOInfo()->questgiver.gossipID);
player->SendPreparedGossip(this);
}
return;
}
case GAMEOBJECT_TYPE_CHEST:
@ -1037,8 +1041,11 @@ void GameObject::Use(Unit* user)
}
else if (info->goober.gossipID) // ...or gossip, if page does not exist
{
player->PrepareGossipMenu(this, info->goober.gossipID);
player->SendPreparedGossip(this);
if (!Script->GOGossipHello(player, this))
{
player->PrepareGossipMenu(this, info->goober.gossipID);
player->SendPreparedGossip(this);
}
}
if (info->goober.eventId)

View file

@ -100,7 +100,7 @@ VisibleNotifier::Notify()
#ifdef MANGOS_DEBUG
if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0)
sLog.outDebug("Object %u (Type: %u) is out of range (no in active cells set) now for player %u",GUID_LOPART(*itr),GuidHigh2TypeId(GUID_HIPART(*itr)),i_player.GetGUIDLow());
sLog.outDebug("%s is out of range (no in active cells set) now for player %u",itr->GetString().c_str(),i_player.GetGUIDLow());
#endif
}
@ -123,10 +123,10 @@ VisibleNotifier::Notify()
i_player.GetSession()->SendPacket(&packet);
// send out of range to other players if need
std::set<uint64> const& oor = i_data.GetOutOfRangeGUIDs();
for(std::set<uint64>::const_iterator iter = oor.begin(); iter != oor.end(); ++iter)
std::set<ObjectGuid> const& oor = i_data.GetOutOfRangeGUIDs();
for(std::set<ObjectGuid>::const_iterator iter = oor.begin(); iter != oor.end(); ++iter)
{
if(!IS_PLAYER_GUID(*iter))
if(!iter->IsPlayer())
continue;
if (Player* plr = ObjectAccessor::FindPlayer(*iter))

View file

@ -551,7 +551,7 @@ void Guild::BroadcastToGuild(WorldSession *session, const std::string& msg, uint
for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
{
Player *pl = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
Player *pl = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first));
if (pl && pl->GetSession() && HasRankRight(pl->GetRank(),GR_RIGHT_GCHATLISTEN) && !pl->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow()) )
pl->GetSession()->SendPacket(&data);
@ -568,7 +568,7 @@ void Guild::BroadcastToOfficers(WorldSession *session, const std::string& msg, u
WorldPacket data;
ChatHandler::FillMessageData(&data, session, CHAT_MSG_OFFICER, language, NULL, 0, msg.c_str(), NULL);
Player *pl = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
Player *pl = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first));
if (pl && pl->GetSession() && HasRankRight(pl->GetRank(),GR_RIGHT_OFFCHATLISTEN) && !pl->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow()))
pl->GetSession()->SendPacket(&data);
@ -580,7 +580,7 @@ void Guild::BroadcastPacket(WorldPacket *packet)
{
for(MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
{
Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
Player *player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first));
if (player)
player->GetSession()->SendPacket(packet);
}
@ -592,7 +592,7 @@ void Guild::BroadcastPacketToRank(WorldPacket *packet, uint32 rankId)
{
if (itr->second.RankId == rankId)
{
Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
Player *player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first));
if (player)
player->GetSession()->SendPacket(packet);
}
@ -731,7 +731,7 @@ void Guild::Roster(WorldSession *session /*= NULL*/)
}
for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
{
if (Player *pl = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)))
if (Player *pl = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)))
{
data << uint64(pl->GetGUID());
data << uint8(1);
@ -746,7 +746,7 @@ void Guild::Roster(WorldSession *session /*= NULL*/)
}
else
{
data << uint64(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
data << uint64(ObjectGuid(HIGHGUID_PLAYER, itr->first).GetRawValue());
data << uint8(0);
data << itr->second.Name;
data << uint32(itr->second.RankId);
@ -976,7 +976,7 @@ void Guild::DisplayGuildBankContentUpdate(uint8 TabId, int32 slot1, int32 slot2)
for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
{
Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
Player *player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first));
if (!player)
continue;
@ -1011,7 +1011,7 @@ void Guild::DisplayGuildBankContentUpdate(uint8 TabId, GuildItemPosCountVec cons
for (MemberList::const_iterator itr = members.begin(); itr != members.end(); ++itr)
{
Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
Player *player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first));
if (!player)
continue;

View file

@ -343,7 +343,7 @@ class Guild
void BroadcastWorker(Do& _do, Player* except = NULL)
{
for(MemberList::iterator itr = members.begin(); itr != members.end(); ++itr)
if(Player *player = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER)))
if(Player *player = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first)))
if(player != except)
_do(player);
}

View file

@ -147,38 +147,59 @@ static void AttemptAddMore(Player* _player)
}
}
void WorldSession::HandleLfgSetAutoJoinOpcode( WorldPacket & /*recv_data*/ )
void WorldSession::HandleLfgJoinOpcode( WorldPacket & recv_data )
{
sLog.outDebug("CMSG_LFG_SET_AUTOJOIN");
sLog.outDebug("CMSG_LFG_JOIN");
LookingForGroup_auto_join = true;
uint8 counter1, counter2;
std::string comment;
recv_data >> Unused<uint32>(); // lfg roles
recv_data >> Unused<uint8>(); // unk1 (unused?)
recv_data >> Unused<uint8>(); // unk2 (unused?)
recv_data >> counter1;
for (uint8 i = 0; i < counter1; i++)
recv_data >> Unused<uint32>(); // queue block? (type/zone?)
recv_data >> counter2;
for (uint8 i = 0; i < counter2; i++)
recv_data >> Unused<uint8>(); // unk (unused?)
recv_data >> comment; // lfg comment
if(!_player) // needed because STATUS_AUTHED
return;
AttemptJoin(_player);
}
void WorldSession::HandleLfgClearAutoJoinOpcode( WorldPacket & /*recv_data*/ )
void WorldSession::HandleLfgLeaveOpcode( WorldPacket & /*recv_data*/ )
{
sLog.outDebug("CMSG_LFG_CLEAR_AUTOJOIN");
sLog.outDebug("CMSG_LFG_LEAVE");
LookingForGroup_auto_join = false;
}
void WorldSession::HandleLfmSetAutoFillOpcode( WorldPacket & /*recv_data*/ )
void WorldSession::HandleSearchLfgJoinOpcode( WorldPacket & recv_data )
{
sLog.outDebug("CMSG_LFM_SET_AUTOFILL");
sLog.outDebug("CMSG_SEARCH_LFG_JOIN");
LookingForGroup_auto_add = true;
recv_data >> Unused<uint32>(); // join id?
if(!_player) // needed because STATUS_AUTHED
return;
AttemptAddMore(_player);
}
void WorldSession::HandleLfmClearAutoFillOpcode( WorldPacket & /*recv_data*/ )
void WorldSession::HandleSearchLfgLeaveOpcode( WorldPacket & recv_data )
{
sLog.outDebug("CMSG_LFM_CLEAR_AUTOFILL");
sLog.outDebug("CMSG_SEARCH_LFG_LEAVE");
LookingForGroup_auto_add = false;
recv_data >> Unused<uint32>(); // join id?
}
void WorldSession::HandleLfgClearOpcode( WorldPacket & /*recv_data */ )

View file

@ -261,7 +261,7 @@ bool ChatHandler::HandleGPSCommand(const char* args)
{
uint64 guid = extractGuidFromLink((char*)args);
if(guid)
obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
obj = (WorldObject*)m_session->GetPlayer()->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT);
if(!obj)
{

View file

@ -3407,7 +3407,7 @@ bool ChatHandler::HandleGetDistanceCommand(const char* args)
{
uint64 guid = extractGuidFromLink((char*)args);
if(guid)
obj = (WorldObject*)ObjectAccessor::GetObjectByTypeMask(*m_session->GetPlayer(),guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
obj = (WorldObject*)m_session->GetPlayer()->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT);
if(!obj)
{

View file

@ -453,7 +453,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data )
return;
}
Player *target = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(target_playerguid, 0, HIGHGUID_PLAYER));
Player *target = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, target_playerguid));
if(!target)
return;

View file

@ -205,8 +205,7 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _par
i_id(id), i_InstanceId(InstanceId), m_unloadTimer(0),
m_VisibleDistance(DEFAULT_VISIBILITY_DISTANCE),
m_activeNonPlayersIter(m_activeNonPlayers.end()),
i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this),
m_hiDynObjectGuid(1), m_hiPetGuid(1), m_hiVehicleGuid(1)
i_gridExpiry(expiry), m_parentMap(_parent ? _parent : this)
{
for(unsigned int idx=0; idx < MAX_NUMBER_OF_GRIDS; ++idx)
{
@ -3485,6 +3484,49 @@ void Map::ScriptsProcess()
pSource->PlayDirectSound(step.script->datalong,pTarget);
break;
}
case SCRIPT_COMMAND_CREATE_ITEM:
{
if (!target && !source)
{
sLog.outError("SCRIPT_COMMAND_CREATE_ITEM call for NULL object.");
break;
}
// only Player
if ((!target || target->GetTypeId() != TYPEID_PLAYER) && (!source || source->GetTypeId() != TYPEID_PLAYER))
{
sLog.outError("SCRIPT_COMMAND_CREATE_ITEM call for non-player (TypeIdSource: %u)(TypeIdTarget: %u), skipping.", source ? source->GetTypeId() : 0, target ? target->GetTypeId() : 0);
break;
}
Player* pReceiver = target && target->GetTypeId() == TYPEID_PLAYER ? (Player*)target : (Player*)source;
if (Item* pItem = pReceiver->StoreNewItemInInventorySlot(step.script->datalong, step.script->datalong2))
pReceiver->SendNewItem(pItem, step.script->datalong2, true, false);
break;
}
case SCRIPT_COMMAND_DESPAWN_SELF:
{
if (!target && !source)
{
sLog.outError("SCRIPT_COMMAND_DESPAWN_SELF call for NULL object.");
break;
}
// only creature
if ((!target || target->GetTypeId() != TYPEID_UNIT) && (!source || source->GetTypeId() != TYPEID_UNIT))
{
sLog.outError("SCRIPT_COMMAND_DESPAWN_SELF call for non-creature (TypeIdSource: %u)(TypeIdTarget: %u), skipping.", source ? source->GetTypeId() : 0, target ? target->GetTypeId() : 0);
break;
}
Creature* pCreature = target && target->GetTypeId() == TYPEID_UNIT ? (Creature*)target : (Creature*)source;
pCreature->ForcedDespawn(step.script->datalong);
break;
}
default:
sLog.outError("Unknown script command %u called.",step.script->command);
break;
@ -3498,22 +3540,22 @@ void Map::ScriptsProcess()
return;
}
Creature* Map::GetCreature(uint64 guid)
Creature* Map::GetCreature(ObjectGuid guid)
{
return m_objectsStore.find<Creature>(guid, (Creature*)NULL);
return m_objectsStore.find<Creature>(guid.GetRawValue(), (Creature*)NULL);
}
Vehicle* Map::GetVehicle(uint64 guid)
Vehicle* Map::GetVehicle(ObjectGuid guid)
{
return m_objectsStore.find<Vehicle>(guid, (Vehicle*)NULL);
return m_objectsStore.find<Vehicle>(guid.GetRawValue(), (Vehicle*)NULL);
}
Pet* Map::GetPet(uint64 guid)
Pet* Map::GetPet(ObjectGuid guid)
{
return m_objectsStore.find<Pet>(guid, (Pet*)NULL);
return m_objectsStore.find<Pet>(guid.GetRawValue(), (Pet*)NULL);
}
Corpse* Map::GetCorpse(uint64 guid)
Corpse* Map::GetCorpse(ObjectGuid guid)
{
Corpse * ret = ObjectAccessor::GetCorpseInMap(guid,GetId());
if (!ret)
@ -3523,33 +3565,32 @@ Corpse* Map::GetCorpse(uint64 guid)
return ret;
}
Creature* Map::GetCreatureOrPetOrVehicle(uint64 guid)
Creature* Map::GetCreatureOrPetOrVehicle(ObjectGuid guid)
{
if (IS_PLAYER_GUID(guid))
return NULL;
switch(guid.GetHigh())
{
case HIGHGUID_UNIT: return GetCreature(guid);
case HIGHGUID_PET: return GetPet(guid);
case HIGHGUID_VEHICLE: return GetVehicle(guid);
default: break;
}
if (IS_PET_GUID(guid))
return GetPet(guid);
if (IS_VEHICLE_GUID(guid))
return GetVehicle(guid);
return GetCreature(guid);
return NULL;
}
GameObject* Map::GetGameObject(uint64 guid)
GameObject* Map::GetGameObject(ObjectGuid guid)
{
return m_objectsStore.find<GameObject>(guid, (GameObject*)NULL);
return m_objectsStore.find<GameObject>(guid.GetRawValue(), (GameObject*)NULL);
}
DynamicObject* Map::GetDynamicObject(uint64 guid)
DynamicObject* Map::GetDynamicObject(ObjectGuid guid)
{
return m_objectsStore.find<DynamicObject>(guid, (DynamicObject*)NULL);
return m_objectsStore.find<DynamicObject>(guid.GetRawValue(), (DynamicObject*)NULL);
}
WorldObject* Map::GetWorldObject(uint64 guid)
WorldObject* Map::GetWorldObject(ObjectGuid guid)
{
switch(GUID_HIPART(guid))
switch(guid.GetHigh())
{
case HIGHGUID_PLAYER: return ObjectAccessor::FindPlayer(guid);
case HIGHGUID_GAMEOBJECT: return GetGameObject(guid);
@ -3592,26 +3633,11 @@ uint32 Map::GenerateLocalLowGuid(HighGuid guidhigh)
switch(guidhigh)
{
case HIGHGUID_DYNAMICOBJECT:
if (m_hiDynObjectGuid >= 0xFFFFFFFE)
{
sLog.outError("DynamicObject guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiDynObjectGuid++;
return m_DynObjectGuids.Generate();
case HIGHGUID_PET:
if(m_hiPetGuid>=0x00FFFFFE)
{
sLog.outError("Pet guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiPetGuid++;
return m_PetGuids.Generate();
case HIGHGUID_VEHICLE:
if(m_hiVehicleGuid>=0x00FFFFFF)
{
sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiVehicleGuid++;
return m_VehicleGuids.Generate();
default:
ASSERT(0);
}

View file

@ -396,14 +396,14 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
void RemoveFromActive(Creature* obj);
Creature* GetCreature(uint64 guid);
Vehicle* GetVehicle(uint64 guid);
Pet* GetPet(uint64 guid);
Creature* GetCreatureOrPetOrVehicle(uint64 guid);
GameObject* GetGameObject(uint64 guid);
DynamicObject* GetDynamicObject(uint64 guid);
Corpse* GetCorpse(uint64 guid);
WorldObject* GetWorldObject(uint64 guid);
Creature* GetCreature(ObjectGuid guid);
Vehicle* GetVehicle(ObjectGuid guid);
Pet* GetPet(ObjectGuid guid);
Creature* GetCreatureOrPetOrVehicle(ObjectGuid guid);
GameObject* GetGameObject(ObjectGuid guid);
DynamicObject* GetDynamicObject(ObjectGuid guid);
Corpse* GetCorpse(ObjectGuid guid);
WorldObject* GetWorldObject(ObjectGuid guid);
TypeUnorderedMapContainer<AllMapStoredObjectTypes>& GetObjectsStore() { return m_objectsStore; }
@ -495,9 +495,9 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
std::multimap<time_t, ScriptAction> m_scriptSchedule;
// Map local low guid counters
uint32 m_hiDynObjectGuid;
uint32 m_hiPetGuid;
uint32 m_hiVehicleGuid;
ObjectGuidGenerator<HIGHGUID_DYNAMICOBJECT> m_DynObjectGuids;
ObjectGuidGenerator<HIGHGUID_PET> m_PetGuids;
ObjectGuidGenerator<HIGHGUID_VEHICLE> m_VehicleGuids;
// Type specific code for add/remove to/from grid
template<class T>

View file

@ -28,6 +28,7 @@
#include "PointMovementGenerator.h"
#include "TargetedMovementGenerator.h"
#include "WaypointMovementGenerator.h"
#include "RandomMovementGenerator.h"
#include <cassert>
@ -209,6 +210,19 @@ void MotionMaster::MoveIdle()
push(&si_idleMovement);
}
void MotionMaster::MoveRandom()
{
if (i_owner->GetTypeId() == TYPEID_PLAYER)
{
sLog.outError("Player (GUID: %u) attempt to move random.", i_owner->GetGUIDLow());
}
else
{
DEBUG_LOG("Creature (Entry: %u GUID: %u) move random.", i_owner->GetEntry(), i_owner->GetGUIDLow());
Mutate(new RandomMovementGenerator<Creature>(*i_owner));
}
}
void
MotionMaster::MoveTargetedHome()
{

View file

@ -95,6 +95,7 @@ class MANGOS_DLL_SPEC MotionMaster : private std::stack<MovementGenerator *>
}
void MoveIdle();
void MoveRandom();
void MoveTargetedHome();
void MoveFollow(Unit* target, float dist, float angle);
void MoveChase(Unit* target, float dist = 0.0f, float angle = 0.0f);

View file

@ -304,8 +304,6 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data )
if (GetPlayer()->hasUnitState(UNIT_STAT_DIED))
GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
// TODO: determine if scriptCall is needed for GO and also if scriptCall can be same as current, with modified argument WorldObject*
// can vehicle have gossip? If so, need check for this also.
if (IS_CREATURE_OR_PET_GUID(guid))
{
@ -338,7 +336,16 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data )
return;
}
_player->OnGossipSelect(pGo, gossipListId, menuId);
if (!code.empty())
{
if (!Script->GOGossipSelectWithCode(_player, pGo, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId), code.c_str()))
_player->OnGossipSelect(pGo, gossipListId, menuId);
}
else
{
if (!Script->GOGossipSelect(_player, pGo, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId)))
_player->OnGossipSelect(pGo, gossipListId, menuId);
}
}
}

View file

@ -54,12 +54,12 @@ ObjectAccessor::~ObjectAccessor()
}
Unit*
ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid)
ObjectAccessor::GetUnit(WorldObject const &u, ObjectGuid guid)
{
if(!guid)
if(guid.IsEmpty())
return NULL;
if(IS_PLAYER_GUID(guid))
if(guid.IsPlayer())
return FindPlayer(guid);
if (!u.IsInWorld())
@ -68,7 +68,7 @@ ObjectAccessor::GetUnit(WorldObject const &u, uint64 guid)
return u.GetMap()->GetCreatureOrPetOrVehicle(guid);
}
Corpse* ObjectAccessor::GetCorpseInMap( uint64 guid, uint32 mapid )
Corpse* ObjectAccessor::GetCorpseInMap(ObjectGuid guid, uint32 mapid)
{
Corpse * ret = HashMapHolder<Corpse>::Find(guid);
if(!ret)
@ -79,49 +79,8 @@ Corpse* ObjectAccessor::GetCorpseInMap( uint64 guid, uint32 mapid )
return ret;
}
Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, uint32 typemask)
{
switch(GUID_HIPART(guid))
{
case HIGHGUID_ITEM:
if(typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER)
return ((Player const &)p).GetItemByGuid( guid );
break;
case HIGHGUID_PLAYER:
if(typemask & TYPEMASK_PLAYER)
return FindPlayer(guid);
break;
case HIGHGUID_GAMEOBJECT:
if(typemask & TYPEMASK_GAMEOBJECT)
return p.GetMap()->GetGameObject(guid);
break;
case HIGHGUID_UNIT:
if(typemask & TYPEMASK_UNIT)
return p.GetMap()->GetCreature(guid);
break;
case HIGHGUID_PET:
if(typemask & TYPEMASK_UNIT)
return p.GetMap()->GetPet(guid);
break;
case HIGHGUID_VEHICLE:
if(typemask & TYPEMASK_UNIT)
return p.GetMap()->GetVehicle(guid);
break;
case HIGHGUID_DYNAMICOBJECT:
if(typemask & TYPEMASK_DYNAMICOBJECT)
return p.GetMap()->GetDynamicObject(guid);
break;
case HIGHGUID_TRANSPORT:
case HIGHGUID_CORPSE:
case HIGHGUID_MO_TRANSPORT:
break;
}
return NULL;
}
Player*
ObjectAccessor::FindPlayer(uint64 guid)
ObjectAccessor::FindPlayer(ObjectGuid guid)
{
Player * plr = HashMapHolder<Player>::Find(guid);;
if(!plr || !plr->IsInWorld())
@ -163,11 +122,11 @@ void ObjectAccessor::KickPlayer(uint64 guid)
}
Corpse*
ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid)
ObjectAccessor::GetCorpseForPlayerGUID(ObjectGuid guid)
{
Guard guard(i_corpseGuard);
Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid);
Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid.GetRawValue());
if( iter == i_player2corpse.end() ) return NULL;
assert(iter->second->GetType() != CORPSE_BONES);
@ -234,7 +193,7 @@ ObjectAccessor::AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* ma
}
Corpse*
ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia)
ObjectAccessor::ConvertCorpseForPlayer(ObjectGuid player_guid, bool insignia)
{
Corpse *corpse = GetCorpseForPlayerGUID(player_guid);
if(!corpse)

View file

@ -58,9 +58,9 @@ class HashMapHolder
m_objectMap.erase(o->GetGUID());
}
static T* Find(uint64 guid)
static T* Find(ObjectGuid guid)
{
typename MapType::iterator itr = m_objectMap.find(guid);
typename MapType::iterator itr = m_objectMap.find(guid.GetRawValue());
return (itr != m_objectMap.end()) ? itr->second : NULL;
}
@ -89,18 +89,17 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
typedef UNORDERED_MAP<uint64, Corpse* > Player2CorpsesMapType;
// global (obj used for map only location local guid objects (pets currently)
static Unit* GetUnitInWorld(WorldObject const& obj, uint64 guid);
static Unit* GetUnitInWorld(WorldObject const& obj, ObjectGuid guid);
// FIXME: map local object with global search
static Creature* GetCreatureInWorld(uint64 guid) { return FindHelper<Creature>(guid); }
static GameObject* GetGameObjectInWorld(uint64 guid) { return FindHelper<GameObject>(guid); }
static Creature* GetCreatureInWorld(ObjectGuid guid) { return FindHelper<Creature>(guid); }
static GameObject* GetGameObjectInWorld(ObjectGuid guid) { return FindHelper<GameObject>(guid); }
// possible local search for specific object map
static Object* GetObjectByTypeMask(WorldObject const &, uint64, uint32 typemask);
static Unit* GetUnit(WorldObject const &, uint64);
static Unit* GetUnit(WorldObject const &, ObjectGuid guid);
// Player access
static Player* FindPlayer(uint64 guid);
static Player* FindPlayer(ObjectGuid guid);
static Player* FindPlayerByName(const char *name);
static void KickPlayer(uint64 guid);
@ -112,12 +111,12 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
void SaveAllPlayers();
// Corpse access
Corpse* GetCorpseForPlayerGUID(uint64 guid);
static Corpse* GetCorpseInMap(uint64 guid, uint32 mapid);
Corpse* GetCorpseForPlayerGUID(ObjectGuid guid);
static Corpse* GetCorpseInMap(ObjectGuid guid, uint32 mapid);
void RemoveCorpse(Corpse *corpse);
void AddCorpse(Corpse* corpse);
void AddCorpsesToGrid(GridPair const& gridpair,GridType& grid,Map* map);
Corpse* ConvertCorpseForPlayer(uint64 player_guid, bool insignia = false);
Corpse* ConvertCorpseForPlayer(ObjectGuid player_guid, bool insignia = false);
// For call from Player/Corpse AddToWorld/RemoveFromWorld only
void AddObject(Corpse *object) { HashMapHolder<Corpse>::Insert(object); }
@ -132,11 +131,11 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
// TODO: This methods will need lock in MT environment
// Theoreticaly multiple threads can enter and search in this method but
// in that case linking/delinking other map should be guarded
template <class OBJECT> static OBJECT* FindHelper(uint64 guid)
template <class OBJECT> static OBJECT* FindHelper(ObjectGuid guid)
{
for (std::list<Map*>::const_iterator i = i_mapList.begin() ; i != i_mapList.end(); ++i)
{
if (OBJECT* ret = (*i)->GetObjectsStore().find(guid, (OBJECT*)NULL))
if (OBJECT* ret = (*i)->GetObjectsStore().find(guid.GetRawValue(), (OBJECT*)NULL))
return ret;
}
@ -154,15 +153,15 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton<ObjectAccessor,
LockType i_corpseGuard;
};
inline Unit* ObjectAccessor::GetUnitInWorld(WorldObject const& obj, uint64 guid)
inline Unit* ObjectAccessor::GetUnitInWorld(WorldObject const& obj, ObjectGuid guid)
{
if(!guid)
if(guid.IsEmpty())
return NULL;
if (IS_PLAYER_GUID(guid))
if (guid.IsPlayer())
return FindPlayer(guid);
if (IS_PET_GUID(guid))
if (guid.IsPet())
return obj.IsInWorld() ? obj.GetMap()->GetPet(guid) : NULL;
return GetCreatureInWorld(guid);

View file

@ -17,22 +17,25 @@
*/
#include "ObjectGuid.h"
#include "World.h"
#include <sstream>
char const* ObjectGuid::GetTypeName() const
char const* ObjectGuid::GetTypeName(HighGuid high)
{
switch(GetHigh())
switch(high)
{
case HIGHGUID_ITEM: return "item";
case HIGHGUID_PLAYER: return !IsEmpty() ? "player" : "none";
case HIGHGUID_GAMEOBJECT: return "gameobject";
case HIGHGUID_TRANSPORT: return "transport";
case HIGHGUID_UNIT: return "creature";
case HIGHGUID_PET: return "pet";
case HIGHGUID_VEHICLE: return "vehicle";
case HIGHGUID_DYNAMICOBJECT:return "dynobject";
case HIGHGUID_CORPSE: return "corpse";
case HIGHGUID_MO_TRANSPORT: return "mo_transport";
case HIGHGUID_ITEM: return "Item";
case HIGHGUID_PLAYER: return "Player";
case HIGHGUID_GAMEOBJECT: return "Gameobject";
case HIGHGUID_TRANSPORT: return "Transport";
case HIGHGUID_UNIT: return "Creature";
case HIGHGUID_PET: return "Pet";
case HIGHGUID_VEHICLE: return "Vehicle";
case HIGHGUID_DYNAMICOBJECT:return "DynObject";
case HIGHGUID_CORPSE: return "Corpse";
case HIGHGUID_MO_TRANSPORT: return "MoTransport";
default:
return "<unknown>";
}
@ -48,6 +51,17 @@ std::string ObjectGuid::GetString() const
return str.str();
}
template<HighGuid high>
uint32 ObjectGuidGenerator<high>::Generate()
{
if (m_nextGuid >= ObjectGuid::GetMaxCounter(high)-1)
{
sLog.outError("%s guid overflow!! Can't continue, shutting down server. ",ObjectGuid::GetTypeName(high));
World::StopNow(ERROR_EXIT_CODE);
}
return m_nextGuid++;
}
ByteBuffer& operator<< (ByteBuffer& buf, ObjectGuid const& guid)
{
buf << uint64(guid.GetRawValue());
@ -71,3 +85,13 @@ ByteBuffer &operator>>(ByteBuffer& buf, PackedGuidReader const& guid)
guid.m_guidPtr->Set(buf.readPackGUID());
return buf;
}
template uint32 ObjectGuidGenerator<HIGHGUID_ITEM>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_PLAYER>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_GAMEOBJECT>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_TRANSPORT>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_UNIT>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_PET>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_VEHICLE>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_DYNAMICOBJECT>::Generate();
template uint32 ObjectGuidGenerator<HIGHGUID_CORPSE>::Generate();

View file

@ -41,11 +41,16 @@ enum TypeMask
TYPEMASK_OBJECT = 0x0001,
TYPEMASK_ITEM = 0x0002,
TYPEMASK_CONTAINER = 0x0006, // TYPEMASK_ITEM | 0x0004
TYPEMASK_UNIT = 0x0008,
TYPEMASK_UNIT = 0x0008, // players also have it
TYPEMASK_PLAYER = 0x0010,
TYPEMASK_GAMEOBJECT = 0x0020,
TYPEMASK_DYNAMICOBJECT = 0x0040,
TYPEMASK_CORPSE = 0x0080
TYPEMASK_CORPSE = 0x0080,
// used combinations in Player::GetObjectByTypeMask (TYPEMASK_UNIT case ignore players in call)
TYPEMASK_CREATURE_OR_GAMEOBJECT = TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT,
TYPEMASK_CREATURE_GAMEOBJECT_OR_ITEM = TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM,
TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM = TYPEMASK_UNIT | TYPEMASK_GAMEOBJECT | TYPEMASK_ITEM | TYPEMASK_PLAYER,
};
enum HighGuid
@ -66,7 +71,6 @@ enum HighGuid
//*** Must be replaced by ObjectGuid use ***
#define IS_CREATURE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_UNIT )
#define IS_PET_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PET )
#define IS_VEHICLE_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_VEHICLE )
#define IS_CREATURE_OR_PET_GUID(Guid)( IS_CREATURE_GUID(Guid) || IS_PET_GUID(Guid) )
#define IS_PLAYER_GUID(Guid) ( GUID_HIPART(Guid) == HIGHGUID_PLAYER && Guid!=0 )
#define IS_UNIT_GUID(Guid) ( IS_CREATURE_OR_PET_GUID(Guid) || IS_PLAYER_GUID(Guid) )
@ -128,6 +132,7 @@ class ObjectGuid
ObjectGuid() : m_guid(0) {}
ObjectGuid(uint64 const& guid) : m_guid(guid) {} // NOTE: must be explicit in future for more strict control type conversions
ObjectGuid(HighGuid hi, uint32 entry, uint32 counter) : m_guid(uint64(counter) | (uint64(entry) << 24) | (uint64(hi) << 48)) {}
ObjectGuid(HighGuid hi, uint32 counter) : m_guid(uint64(counter) | (uint64(hi) << 48)) {}
public: // modifiers
PackedGuidReader ReadAsPacked() { return PackedGuidReader(*this); }
@ -136,6 +141,8 @@ class ObjectGuid
// Possible removed in future for more strict control type conversions
void operator= (uint64 const& guid) { m_guid = guid; }
PackedGuid WriteAsPacked() const;
public: // accessors
uint64 const& GetRawValue() const { return m_guid; }
HighGuid GetHigh() const { return HighGuid((m_guid >> 48) & 0x0000FFFF); }
@ -147,11 +154,21 @@ class ObjectGuid
: uint32(m_guid & UI64LIT(0x00000000FFFFFFFF));
}
static uint32 GetMaxCounter(HighGuid high)
{
return HasEntry(high)
? uint32(0x00FFFFFF)
: uint32(0xFFFFFFFF);
}
uint32 GetMaxCounter() const { return GetMaxCounter(GetHigh()); }
bool IsEmpty() const { return m_guid == 0; }
bool IsCreature() const { return GetHigh() == HIGHGUID_UNIT; }
bool IsPet() const { return GetHigh() == HIGHGUID_PET; }
bool IsVehicle() const { return GetHigh() == HIGHGUID_VEHICLE; }
bool IsCreatureOrPet() const { return IsCreature() || IsPet(); }
bool IsCreatureOrVehicle() const { return IsCreature() || IsVehicle(); }
bool IsPlayer() const { return !IsEmpty() && GetHigh() == HIGHGUID_PLAYER; }
bool IsUnit() const { return IsCreatureOrPet() || IsPlayer(); }
bool IsItem() const { return GetHigh() == HIGHGUID_ITEM; }
@ -161,9 +178,9 @@ class ObjectGuid
bool IsTransport() const { return GetHigh() == HIGHGUID_TRANSPORT; }
bool IsMOTransport() const { return GetHigh() == HIGHGUID_MO_TRANSPORT; }
TypeID GetTypeId()
static TypeID GetTypeId(HighGuid high)
{
switch(GetHigh())
switch(high)
{
case HIGHGUID_ITEM: return TYPEID_ITEM;
//case HIGHGUID_CONTAINER: return TYPEID_CONTAINER; HIGHGUID_CONTAINER==HIGHGUID_ITEM currently
@ -180,14 +197,19 @@ class ObjectGuid
}
}
PackedGuid WriteAsPacked() const;
TypeID GetTypeId() const { return GetTypeId(GetHigh()); }
bool operator< (ObjectGuid const& guid) const { return GetRawValue() < guid.GetRawValue(); }
public: // accessors - for debug
char const* GetTypeName() const;
static char const* GetTypeName(HighGuid high);
char const* GetTypeName() const { return !IsEmpty() ? GetTypeName(GetHigh()) : "None"; }
std::string GetString() const;
private: // internal functions
bool HasEntry() const
static bool HasEntry(HighGuid high)
{
switch(GetHigh())
switch(high)
{
case HIGHGUID_ITEM:
case HIGHGUID_PLAYER:
@ -205,6 +227,8 @@ class ObjectGuid
}
}
bool HasEntry() const { return HasEntry(GetHigh()); }
private: // fields
uint64 m_guid;
};
@ -229,6 +253,23 @@ class PackedGuid
ByteBuffer m_packedGuid;
};
template<HighGuid high>
class ObjectGuidGenerator
{
public: // constructors
explicit ObjectGuidGenerator(uint32 start = 1) : m_nextGuid(start) {}
public: // modifiers
void Set(uint32 val) { m_nextGuid = val; }
uint32 Generate();
public: // accessors
uint32 GetNextAfterMaxUsed() const { return m_nextGuid; }
private: // fields
uint32 m_nextGuid;
};
ByteBuffer& operator<< (ByteBuffer& buf, ObjectGuid const& guid);
ByteBuffer& operator>> (ByteBuffer& buf, ObjectGuid& guid);

View file

@ -45,6 +45,8 @@
#include "WaypointManager.h"
#include "GossipDef.h"
#include <limits>
INSTANTIATE_SINGLETON_1(ObjectMgr);
ScriptMapMap sQuestEndScripts;
@ -128,22 +130,30 @@ bool SpellClickInfo::IsFitToRequirements(Player const* player) const
return true;
}
ObjectMgr::ObjectMgr()
template<typename T>
T IdGenerator<T>::Generate()
{
m_hiCharGuid = 1;
m_hiCreatureGuid = 1;
m_hiItemGuid = 1;
m_hiGoGuid = 1;
m_hiCorpseGuid = 1;
m_hiPetNumber = 1;
m_ItemTextId = 1;
m_mailid = 1;
m_equipmentSetGuid = 1;
m_guildId = 1;
m_arenaTeamId = 1;
m_auctionid = 1;
m_groupId = 1;
if (m_nextGuid >= std::numeric_limits<T>::max()-1)
{
sLog.outError("%s guid overflow!! Can't continue, shutting down server. ",m_name);
World::StopNow(ERROR_EXIT_CODE);
}
return m_nextGuid++;
}
template uint32 IdGenerator<uint32>::Generate();
template uint64 IdGenerator<uint64>::Generate();
ObjectMgr::ObjectMgr() :
m_ArenaTeamIds("Arena team ids"),
m_AuctionIds("Auction ids"),
m_EquipmentSetIds("Equipment set ids"),
m_GuildIds("Guild ids"),
m_ItemTextIds("Item text ids"),
m_MailIds("Mail ids"),
m_PetNumbers("Pet numbers"),
m_GroupIds("Group ids")
{
// Only zero condition left, others will be added while loading DB tables
mConditions.resize(1);
}
@ -4360,6 +4370,27 @@ void ObjectMgr::LoadScripts(ScriptMapMap& scripts, char const* tablename)
}
break;
}
case SCRIPT_COMMAND_CREATE_ITEM:
{
if (!GetItemPrototype(tmp.datalong))
{
sLog.outErrorDb("Table `%s` has nonexistent item (entry: %u) in SCRIPT_COMMAND_CREATE_ITEM for script id %u",
tablename, tmp.datalong, tmp.id);
continue;
}
if (!tmp.datalong2)
{
sLog.outErrorDb("Table `%s` SCRIPT_COMMAND_CREATE_ITEM but amount is %u for script id %u",
tablename, tmp.datalong2, tmp.id);
continue;
}
break;
}
case SCRIPT_COMMAND_DESPAWN_SELF:
{
// for later, we might consider despawn by database guid, and define in datalong2 as option to despawn self.
break;
}
}
if (scripts.find(tmp.id) == scripts.end())
@ -5658,7 +5689,7 @@ void ObjectMgr::PackGroupIds()
bar.step();
}
m_groupId = groupId;
m_GroupIds.Set(groupId);
sLog.outString( ">> Group Ids remapped, next group id is %u", groupId );
sLog.outString();
@ -5669,164 +5700,94 @@ void ObjectMgr::SetHighestGuids()
QueryResult *result = CharacterDatabase.Query( "SELECT MAX(guid) FROM characters" );
if( result )
{
m_hiCharGuid = (*result)[0].GetUInt32()+1;
m_CharGuids.Set((*result)[0].GetUInt32()+1);
delete result;
}
result = WorldDatabase.Query( "SELECT MAX(guid) FROM creature" );
if( result )
{
m_hiCreatureGuid = (*result)[0].GetUInt32()+1;
m_CreatureGuids.Set((*result)[0].GetUInt32()+1);
delete result;
}
result = CharacterDatabase.Query( "SELECT MAX(guid) FROM item_instance" );
if( result )
{
m_hiItemGuid = (*result)[0].GetUInt32()+1;
m_ItemGuids.Set((*result)[0].GetUInt32()+1);
delete result;
}
// Cleanup other tables from not existed guids (>=m_hiItemGuid)
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", m_hiItemGuid);
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", m_hiItemGuid);
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", m_hiItemGuid);
CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", m_hiItemGuid);
CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", m_ItemGuids.GetNextAfterMaxUsed());
CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", m_ItemGuids.GetNextAfterMaxUsed());
CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", m_ItemGuids.GetNextAfterMaxUsed());
CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", m_ItemGuids.GetNextAfterMaxUsed());
result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject" );
if( result )
{
m_hiGoGuid = (*result)[0].GetUInt32()+1;
m_GameobjectGuids.Set((*result)[0].GetUInt32()+1);
delete result;
}
result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse" );
if( result )
{
m_auctionid = (*result)[0].GetUInt32()+1;
m_AuctionIds.Set((*result)[0].GetUInt32()+1);
delete result;
}
result = CharacterDatabase.Query( "SELECT MAX(id) FROM mail" );
if( result )
{
m_mailid = (*result)[0].GetUInt32()+1;
m_MailIds.Set((*result)[0].GetUInt32()+1);
delete result;
}
result = CharacterDatabase.Query( "SELECT MAX(id) FROM item_text" );
if( result )
{
m_ItemTextId = (*result)[0].GetUInt32()+1;
m_ItemTextIds.Set((*result)[0].GetUInt32()+1);
delete result;
}
result = CharacterDatabase.Query( "SELECT MAX(guid) FROM corpse" );
if( result )
{
m_hiCorpseGuid = (*result)[0].GetUInt32()+1;
m_CorpseGuids.Set((*result)[0].GetUInt32()+1);
delete result;
}
result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team");
if (result)
{
m_arenaTeamId = (*result)[0].GetUInt32()+1;
m_ArenaTeamIds.Set((*result)[0].GetUInt32()+1);
delete result;
}
result = CharacterDatabase.Query("SELECT MAX(setguid) FROM character_equipmentsets");
if (result)
{
m_equipmentSetGuid = (*result)[0].GetUInt64()+1;
m_EquipmentSetIds.Set((*result)[0].GetUInt64()+1);
delete result;
}
result = CharacterDatabase.Query( "SELECT MAX(guildid) FROM guild" );
if (result)
{
m_guildId = (*result)[0].GetUInt32()+1;
m_GuildIds.Set((*result)[0].GetUInt32()+1);
delete result;
}
result = CharacterDatabase.Query( "SELECT MAX(groupId) FROM groups" );
if (result)
{
m_groupId = (*result)[0].GetUInt32()+1;
m_GroupIds.Set((*result)[0].GetUInt32()+1);
delete result;
}
}
uint32 ObjectMgr::GenerateArenaTeamId()
{
if(m_arenaTeamId>=0xFFFFFFFE)
{
sLog.outError("Arena team ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_arenaTeamId++;
}
uint32 ObjectMgr::GenerateAuctionID()
{
if(m_auctionid>=0xFFFFFFFE)
{
sLog.outError("Auctions ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_auctionid++;
}
uint64 ObjectMgr::GenerateEquipmentSetGuid()
{
if(m_equipmentSetGuid>=0xFFFFFFFFFFFFFFFEll)
{
sLog.outError("EquipmentSet guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_equipmentSetGuid++;
}
uint32 ObjectMgr::GenerateGuildId()
{
if(m_guildId>=0xFFFFFFFE)
{
sLog.outError("Guild ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_guildId++;
}
uint32 ObjectMgr::GenerateGroupId()
{
if(m_groupId>=0xFFFFFFFE)
{
sLog.outError("Group ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_groupId++;
}
uint32 ObjectMgr::GenerateMailID()
{
if(m_mailid>=0xFFFFFFFE)
{
sLog.outError("Mail ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_mailid++;
}
uint32 ObjectMgr::GenerateItemTextID()
{
if(m_ItemTextId>=0xFFFFFFFE)
{
sLog.outError("Item text ids overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_ItemTextId++;
}
uint32 ObjectMgr::CreateItemText(std::string text)
{
uint32 newItemTextId = GenerateItemTextID();
@ -5846,40 +5807,15 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)
switch(guidhigh)
{
case HIGHGUID_ITEM:
if(m_hiItemGuid>=0xFFFFFFFE)
{
sLog.outError("Item guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiItemGuid++;
return m_ItemGuids.Generate();
case HIGHGUID_UNIT:
if(m_hiCreatureGuid>=0x00FFFFFE)
{
sLog.outError("Creature guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiCreatureGuid++;
return m_CreatureGuids.Generate();
case HIGHGUID_PLAYER:
if(m_hiCharGuid>=0xFFFFFFFE)
{
sLog.outError("Players guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiCharGuid++;
return m_CharGuids.Generate();
case HIGHGUID_GAMEOBJECT:
if(m_hiGoGuid>=0x00FFFFFE)
{
sLog.outError("Gameobject guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiGoGuid++;
return m_GameobjectGuids.Generate();
case HIGHGUID_CORPSE:
if(m_hiCorpseGuid>=0xFFFFFFFE)
{
sLog.outError("Corpse guid overflow!! Can't continue, shutting down server. ");
World::StopNow(ERROR_EXIT_CODE);
}
return m_hiCorpseGuid++;
return m_CorpseGuids.Generate();
default:
ASSERT(0);
}
@ -6291,7 +6227,7 @@ void ObjectMgr::LoadPetNumber()
if(result)
{
Field *fields = result->Fetch();
m_hiPetNumber = fields[0].GetUInt32()+1;
m_PetNumbers.Set(fields[0].GetUInt32()+1);
delete result;
}
@ -6299,7 +6235,7 @@ void ObjectMgr::LoadPetNumber()
bar.step();
sLog.outString();
sLog.outString( ">> Loaded the max pet number: %d", m_hiPetNumber-1);
sLog.outString( ">> Loaded the max pet number: %d", m_PetNumbers.GetNextAfterMaxUsed()-1);
}
std::string ObjectMgr::GeneratePetName(uint32 entry)
@ -6319,11 +6255,6 @@ std::string ObjectMgr::GeneratePetName(uint32 entry)
return *(list0.begin()+urand(0, list0.size()-1)) + *(list1.begin()+urand(0, list1.size()-1));
}
uint32 ObjectMgr::GeneratePetNumber()
{
return ++m_hiPetNumber;
}
void ObjectMgr::LoadCorpses()
{
uint32 count = 0;

View file

@ -372,6 +372,24 @@ MANGOS_DLL_SPEC LanguageDesc const* GetLanguageDescByID(uint32 lang);
class PlayerDumpReader;
template<typename T>
class IdGenerator
{
public: // constructors
explicit IdGenerator(char const* _name) : m_name(_name), m_nextGuid(1) {}
public: // modifiers
void Set(T val) { m_nextGuid = val; }
T Generate();
public: // accessors
T GetNextAfterMaxUsed() const { return m_nextGuid; }
private: // fields
char const* m_name;
T m_nextGuid;
};
class ObjectMgr
{
friend class PlayerDumpReader;
@ -653,14 +671,14 @@ class ObjectMgr
void SetHighestGuids();
uint32 GenerateLowGuid(HighGuid guidhigh);
uint32 GenerateArenaTeamId();
uint32 GenerateAuctionID();
uint64 GenerateEquipmentSetGuid();
uint32 GenerateGuildId();
uint32 GenerateGroupId();
uint32 GenerateItemTextID();
uint32 GenerateMailID();
uint32 GeneratePetNumber();
uint32 GenerateArenaTeamId() { return m_ArenaTeamIds.Generate(); }
uint32 GenerateAuctionID() { return m_AuctionIds.Generate(); }
uint64 GenerateEquipmentSetGuid() { return m_EquipmentSetIds.Generate(); }
uint32 GenerateGuildId() { return m_GuildIds.Generate(); }
uint32 GenerateGroupId() { return m_GroupIds.Generate(); }
uint32 GenerateItemTextID() { return m_ItemGuids.Generate(); }
uint32 GenerateMailID() { return m_MailIds.Generate(); }
uint32 GeneratePetNumber() { return m_PetNumbers.Generate(); }
uint32 CreateItemText(std::string text);
void AddItemText(uint32 itemTextId, std::string text) { mItemTexts[itemTextId] = text; }
@ -889,21 +907,21 @@ class ObjectMgr
protected:
// first free id for selected id type
uint32 m_arenaTeamId;
uint32 m_auctionid;
uint64 m_equipmentSetGuid;
uint32 m_guildId;
uint32 m_ItemTextId;
uint32 m_mailid;
uint32 m_hiPetNumber;
uint32 m_groupId;
IdGenerator<uint32> m_ArenaTeamIds;
IdGenerator<uint32> m_AuctionIds;
IdGenerator<uint64> m_EquipmentSetIds;
IdGenerator<uint32> m_GuildIds;
IdGenerator<uint32> m_ItemTextIds;
IdGenerator<uint32> m_MailIds;
IdGenerator<uint32> m_PetNumbers;
IdGenerator<uint32> m_GroupIds;
// first free low guid for selected guid type
uint32 m_hiCharGuid;
uint32 m_hiCreatureGuid;
uint32 m_hiItemGuid;
uint32 m_hiGoGuid;
uint32 m_hiCorpseGuid;
ObjectGuidGenerator<HIGHGUID_PLAYER> m_CharGuids;
ObjectGuidGenerator<HIGHGUID_UNIT> m_CreatureGuids;
ObjectGuidGenerator<HIGHGUID_ITEM> m_ItemGuids;
ObjectGuidGenerator<HIGHGUID_GAMEOBJECT> m_GameobjectGuids;
ObjectGuidGenerator<HIGHGUID_CORPSE> m_CorpseGuids;
QuestMap mQuestTemplates;

View file

@ -17,6 +17,7 @@
*/
#include "ObjectPosSelector.h"
#include "Object.h"
ObjectPosSelector::ObjectPosSelector(float x,float y,float size,float dist)
: m_center_x(x),m_center_y(y),m_size(size),m_dist(dist)

View file

@ -886,10 +886,10 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] =
/*0x359*/ { "MSG_MOVE_START_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
/*0x35A*/ { "MSG_MOVE_STOP_ASCEND", STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes },
/*0x35B*/ { "SMSG_ARENA_TEAM_STATS", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x35C*/ { "CMSG_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgSetAutoJoinOpcode },
/*0x35D*/ { "CMSG_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleLfgClearAutoJoinOpcode },
/*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfmSetAutoFillOpcode },
/*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleLfmClearAutoFillOpcode },
/*0x35C*/ { "CMSG_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleLfgJoinOpcode },
/*0x35D*/ { "CMSG_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleLfgLeaveOpcode },
/*0x35E*/ { "CMSG_SEARCH_LFG_JOIN", STATUS_LOGGEDIN, &WorldSession::HandleSearchLfgJoinOpcode },
/*0x35F*/ { "CMSG_SEARCH_LFG_LEAVE", STATUS_LOGGEDIN, &WorldSession::HandleSearchLfgLeaveOpcode },
/*0x360*/ { "SMSG_UPDATE_LFG_LIST", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x361*/ { "SMSG_LFG_PROPOSAL_DECLINED", STATUS_NEVER, &WorldSession::Handle_ServerSide },
/*0x362*/ { "CMSG_LFG_PROPOSAL_RESULT", STATUS_LOGGEDIN, &WorldSession::Handle_NULL },

View file

@ -17678,12 +17678,13 @@ void Player::HandleStealthedUnitsDetection()
{
if(!hasAtClient)
{
ObjectGuid i_guid = (*i)->GetGUID();
(*i)->SendCreateUpdateToPlayer(this);
m_clientGUIDs.insert((*i)->GetGUID());
m_clientGUIDs.insert(i_guid);
#ifdef MANGOS_DEBUG
if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0)
sLog.outDebug("Object %u (Type: %u) is detected in stealth by player %u. Distance = %f",(*i)->GetGUIDLow(),(*i)->GetTypeId(),GetGUIDLow(),GetDistance(*i));
sLog.outDebug("%s is detected in stealth by player %u. Distance = %f",i_guid.GetString().c_str(),GetGUIDLow(),GetDistance(*i));
#endif
// target aura duration for caster show only if target exist at caster client
@ -18853,12 +18854,14 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* targe
if (target->GetTypeId()==TYPEID_UNIT)
BeforeVisibilityDestroy<Creature>((Creature*)target,this);
ObjectGuid t_guid = target->GetGUID();
target->DestroyForPlayer(this);
m_clientGUIDs.erase(target->GetGUID());
m_clientGUIDs.erase(t_guid);
#ifdef MANGOS_DEBUG
if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0)
sLog.outDebug("Object %u (Type: %u) out of range for player %u. Distance = %f",target->GetGUIDLow(),target->GetTypeId(),GetGUIDLow(),GetDistance(target));
sLog.outDebug("%s out of range for player %u. Distance = %f",t_guid.GetString().c_str(),GetGUIDLow(),GetDistance(target));
#endif
}
}
@ -18887,13 +18890,13 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, WorldObject* targe
}
template<class T>
inline void UpdateVisibilityOf_helper(std::set<uint64>& s64, T* target)
inline void UpdateVisibilityOf_helper(std::set<ObjectGuid>& s64, T* target)
{
s64.insert(target->GetGUID());
}
template<>
inline void UpdateVisibilityOf_helper(std::set<uint64>& s64, GameObject* target)
inline void UpdateVisibilityOf_helper(std::set<ObjectGuid>& s64, GameObject* target)
{
if(!target->IsTransport())
s64.insert(target->GetGUID());
@ -18908,12 +18911,14 @@ void Player::UpdateVisibilityOf(WorldObject const* viewPoint, T* target, UpdateD
{
BeforeVisibilityDestroy<T>(target,this);
ObjectGuid t_guid = target->GetGUID();
target->BuildOutOfRangeUpdateBlock(&data);
m_clientGUIDs.erase(target->GetGUID());
m_clientGUIDs.erase(t_guid);
#ifdef MANGOS_DEBUG
if((sLog.getLogFilter() & LOG_FILTER_VISIBILITY_CHANGES)==0)
sLog.outDebug("Object %u (Type: %u, Entry: %u) is out of range for player %u. Distance = %f",target->GetGUIDLow(),target->GetTypeId(),target->GetEntry(),GetGUIDLow(),GetDistance(target));
sLog.outDebug("%s is out of range for player %u. Distance = %f",t_guid.GetString().c_str(),GetGUIDLow(),GetDistance(target));
#endif
}
}
@ -19539,13 +19544,12 @@ void Player::UpdateForQuestWorldObjects()
WorldPacket packet;
for(ClientGUIDs::const_iterator itr=m_clientGUIDs.begin(); itr!=m_clientGUIDs.end(); ++itr)
{
if(IS_GAMEOBJECT_GUID(*itr))
if (itr->IsGameobject())
{
GameObject *obj = GetMap()->GetGameObject(*itr);
if(obj)
if (GameObject *obj = GetMap()->GetGameObject(*itr))
obj->BuildValuesUpdateBlockForPlayer(&udata,this);
}
else if(IS_CREATURE_GUID(*itr) || IS_VEHICLE_GUID(*itr))
else if (itr->IsCreatureOrVehicle())
{
Creature *obj = GetMap()->GetCreatureOrPetOrVehicle(*itr);
if(!obj)
@ -21705,3 +21709,46 @@ void Player::SetHomebindToLocation(WorldLocation const& loc, uint32 area_id)
CharacterDatabase.PExecute("UPDATE character_homebind SET map = '%u', zone = '%u', position_x = '%f', position_y = '%f', position_z = '%f' WHERE guid = '%u'",
m_homebindMapId, m_homebindAreaId, m_homebindX, m_homebindY, m_homebindZ, GetGUIDLow());
}
Object* Player::GetObjectByTypeMask(ObjectGuid guid, TypeMask typemask)
{
switch(guid.GetHigh())
{
case HIGHGUID_ITEM:
if (typemask & TYPEMASK_ITEM)
return GetItemByGuid(guid.GetRawValue());
break;
case HIGHGUID_PLAYER:
if (GetGUID()==guid.GetRawValue())
return this;
if ((typemask & TYPEMASK_PLAYER) && IsInWorld())
return ObjectAccessor::FindPlayer(guid.GetRawValue());
break;
case HIGHGUID_GAMEOBJECT:
if ((typemask & TYPEMASK_GAMEOBJECT) && IsInWorld())
return GetMap()->GetGameObject(guid);
break;
case HIGHGUID_UNIT:
if ((typemask & TYPEMASK_UNIT) && IsInWorld())
return GetMap()->GetCreature(guid);
break;
case HIGHGUID_PET:
if ((typemask & TYPEMASK_UNIT) && IsInWorld())
return GetMap()->GetPet(guid);
break;
case HIGHGUID_VEHICLE:
if ((typemask & TYPEMASK_UNIT) && IsInWorld())
return GetMap()->GetVehicle(guid);
break;
case HIGHGUID_DYNAMICOBJECT:
if ((typemask & TYPEMASK_DYNAMICOBJECT) && IsInWorld())
return GetMap()->GetDynamicObject(guid);
break;
case HIGHGUID_TRANSPORT:
case HIGHGUID_CORPSE:
case HIGHGUID_MO_TRANSPORT:
break;
}
return NULL;
}

View file

@ -2179,8 +2179,10 @@ class MANGOS_DLL_SPEC Player : public Unit
void RelocateToHomebind() { SetLocationMapId(m_homebindMapId); Relocate(m_homebindX, m_homebindY, m_homebindZ); }
bool TeleportToHomebind(uint32 options = 0) { return TeleportTo(m_homebindMapId, m_homebindX, m_homebindY, m_homebindZ, GetOrientation(), options); }
Object* GetObjectByTypeMask(ObjectGuid guid, TypeMask typemask);
// currently visible objects at player client
typedef std::set<uint64> ClientGUIDs;
typedef std::set<ObjectGuid> ClientGUIDs;
ClientGUIDs m_clientGUIDs;
bool HaveAtClient(WorldObject const* u) { return u==this || m_clientGUIDs.find(u->GetGUID())!=m_clientGUIDs.end(); }

View file

@ -416,18 +416,18 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
// make sure the same guid doesn't already exist and is safe to use
bool incHighest = true;
if (guid != 0 && guid < sObjectMgr.m_hiCharGuid)
if (guid != 0 && guid < sObjectMgr.m_CharGuids.GetNextAfterMaxUsed())
{
result = CharacterDatabase.PQuery("SELECT * FROM characters WHERE guid = '%d'", guid);
if (result)
{
guid = sObjectMgr.m_hiCharGuid; // use first free if exists
guid = sObjectMgr.m_CharGuids.GetNextAfterMaxUsed();
delete result;
}
else incHighest = false;
}
else
guid = sObjectMgr.m_hiCharGuid;
guid = sObjectMgr.m_CharGuids.GetNextAfterMaxUsed();
// normalize the name if specified and check if it exists
if (!normalizePlayerName(name))
@ -536,7 +536,7 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
if(!changetoknth(vals, OBJECT_FIELD_GUID+1, newguid))
ROLLBACK(DUMP_FILE_BROKEN);
for(uint16 field = PLAYER_FIELD_INV_SLOT_HEAD; field < PLAYER_FARSIGHT; field++)
if(!changetokGuid(vals, field+1, items, sObjectMgr.m_hiItemGuid, true))
if (!changetokGuid(vals, field+1, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed(), true))
ROLLBACK(DUMP_FILE_BROKEN);
if(!changenth(line, 3, vals.c_str()))
ROLLBACK(DUMP_FILE_BROKEN);
@ -562,40 +562,40 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
}
case DTT_INVENTORY: // character_inventory t.
{
if(!changenth(line, 1, newguid))
if (!changenth(line, 1, newguid))
ROLLBACK(DUMP_FILE_BROKEN);
// bag, item
if(!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid, true))
if (!changeGuid(line, 2, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed(), true))
ROLLBACK(DUMP_FILE_BROKEN);
if(!changeGuid(line, 4, items, sObjectMgr.m_hiItemGuid))
if (!changeGuid(line, 4, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN);
break;
}
case DTT_ITEM: // item_instance t.
{
// item, owner, data field:item, owner guid
if(!changeGuid(line, 1, items, sObjectMgr.m_hiItemGuid))
if (!changeGuid(line, 1, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN);
if(!changenth(line, 2, newguid))
if (!changenth(line, 2, newguid))
ROLLBACK(DUMP_FILE_BROKEN);
std::string vals = getnth(line,3);
if(!changetokGuid(vals, OBJECT_FIELD_GUID+1, items, sObjectMgr.m_hiItemGuid))
if (!changetokGuid(vals, OBJECT_FIELD_GUID+1, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN);
if(!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid))
if (!changetoknth(vals, ITEM_FIELD_OWNER+1, newguid))
ROLLBACK(DUMP_FILE_BROKEN);
//if(!changetokGuid(vals, ITEM_FIELD_ITEM_TEXT_ID+1, itemTexts, sObjectMgr.m_ItemTextId,true))
//if (!changetokGuid(vals, ITEM_FIELD_ITEM_TEXT_ID+1, itemTexts, sObjectMgr.m_ItemTextIds.GetNextAfterMaxUsed(), true))
// ROLLBACK(DUMP_FILE_BROKEN);
if(!changenth(line, 3, vals.c_str()))
if (!changenth(line, 3, vals.c_str()))
ROLLBACK(DUMP_FILE_BROKEN);
break;
}
case DTT_ITEM_GIFT: // character_gift
{
// guid,item_guid,
if(!changenth(line, 1, newguid))
if (!changenth(line, 1, newguid))
ROLLBACK(DUMP_FILE_BROKEN);
if(!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid))
if (!changeGuid(line, 2, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN);
break;
}
@ -603,8 +603,10 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
{
//store a map of old pet id to new inserted pet id for use by type 5 tables
snprintf(currpetid, 20, "%s", getnth(line, 1).c_str());
if(strlen(lastpetid)==0) snprintf(lastpetid, 20, "%s", currpetid);
if(strcmp(lastpetid,currpetid)!=0)
if (strlen(lastpetid)==0)
snprintf(lastpetid, 20, "%s", currpetid);
if (strcmp(lastpetid,currpetid)!=0)
{
snprintf(newpetid, 20, "%d", sObjectMgr.GeneratePetNumber());
snprintf(lastpetid, 20, "%s", currpetid);
@ -612,15 +614,15 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid));
if(petids_iter == petids.end())
if (petids_iter == petids.end())
{
petids.insert(PetIdsPair(atoi(currpetid), atoi(newpetid)));
}
// item, entry, owner, ...
if(!changenth(line, 1, newpetid))
if (!changenth(line, 1, newpetid))
ROLLBACK(DUMP_FILE_BROKEN);
if(!changenth(line, 3, newguid))
if (!changenth(line, 3, newguid))
ROLLBACK(DUMP_FILE_BROKEN);
break;
@ -631,12 +633,12 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
// lookup currpetid and match to new inserted pet id
std::map<uint32, uint32> :: const_iterator petids_iter = petids.find(atoi(currpetid));
if(petids_iter == petids.end()) // couldn't find new inserted id
if (petids_iter == petids.end()) // couldn't find new inserted id
ROLLBACK(DUMP_FILE_BROKEN);
snprintf(newpetid, 20, "%d", petids_iter->second);
if(!changenth(line, 1, newpetid))
if (!changenth(line, 1, newpetid))
ROLLBACK(DUMP_FILE_BROKEN);
break;
@ -644,29 +646,29 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
case DTT_MAIL: // mail
{
// id,messageType,stationery,mailtemplate,sender,receiver,subject,itemText
if(!changeGuid(line, 1, mails, sObjectMgr.m_mailid))
if (!changeGuid(line, 1, mails, sObjectMgr.m_MailIds.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN);
if(!changenth(line, 6, newguid))
if (!changenth(line, 6, newguid))
ROLLBACK(DUMP_FILE_BROKEN);
if(!changeGuid(line, 8, itemTexts, sObjectMgr.m_ItemTextId))
if (!changeGuid(line, 8, itemTexts, sObjectMgr.m_ItemTextIds.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN);
break;
}
case DTT_MAIL_ITEM: // mail_items
{
// mail_id,item_guid,item_template,receiver
if(!changeGuid(line, 1, mails, sObjectMgr.m_mailid))
if (!changeGuid(line, 1, mails, sObjectMgr.m_MailIds.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN);
if(!changeGuid(line, 2, items, sObjectMgr.m_hiItemGuid))
if (!changeGuid(line, 2, items, sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN);
if(!changenth(line, 4, newguid))
if (!changenth(line, 4, newguid))
ROLLBACK(DUMP_FILE_BROKEN);
break;
}
case DTT_ITEM_TEXT: // item_text
{
// id
if(!changeGuid(line, 1, itemTexts, sObjectMgr.m_ItemTextId))
if (!changeGuid(line, 1, itemTexts, sObjectMgr.m_ItemTextIds.GetNextAfterMaxUsed()))
ROLLBACK(DUMP_FILE_BROKEN);
// add it to cache
@ -686,12 +688,13 @@ DumpReturn PlayerDumpReader::LoadDump(const std::string& file, uint32 account, s
CharacterDatabase.CommitTransaction();
sObjectMgr.m_hiItemGuid += items.size();
sObjectMgr.m_mailid += mails.size();
sObjectMgr.m_ItemTextId += itemTexts.size();
//FIXME: current code with post-updating guids not safe for future per-map threads
sObjectMgr.m_ItemGuids.Set(sObjectMgr.m_ItemGuids.GetNextAfterMaxUsed() + items.size());
sObjectMgr.m_MailIds.Set(sObjectMgr.m_MailIds.GetNextAfterMaxUsed() + mails.size());
sObjectMgr.m_ItemTextIds.Set(sObjectMgr.m_ItemTextIds.GetNextAfterMaxUsed() + itemTexts.size());
if(incHighest)
++sObjectMgr.m_hiCharGuid;
sObjectMgr.m_CharGuids.Set(sObjectMgr.m_CharGuids.GetNextAfterMaxUsed()+1);
fclose(fin);

View file

@ -206,7 +206,7 @@ void PoolGroup<Creature>::Despawn1Object(uint32 guid)
{
sObjectMgr.RemoveCreatureFromGrid(guid, data);
if (Creature* pCreature = ObjectAccessor::GetCreatureInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_UNIT)))
if (Creature* pCreature = ObjectAccessor::GetCreatureInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, guid)))
pCreature->AddObjectToRemoveList();
}
}
@ -219,7 +219,7 @@ void PoolGroup<GameObject>::Despawn1Object(uint32 guid)
{
sObjectMgr.RemoveGameobjectFromGrid(guid, data);
if (GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_GAMEOBJECT)))
if (GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, guid)))
pGameobject->AddObjectToRemoveList();
}
}
@ -403,7 +403,7 @@ template <>
void PoolGroup<GameObject>::ReSpawn1Object(PoolObject* obj)
{
if (GameObjectData const* data = sObjectMgr.GetGOData(obj->guid))
if (GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(MAKE_NEW_GUID(obj->guid, data->id, HIGHGUID_GAMEOBJECT)))
if (GameObject* pGameobject = ObjectAccessor::GetGameObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, obj->guid)))
pGameobject->GetMap()->Add(pGameobject);
}

View file

@ -37,7 +37,7 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode( WorldPacket & recv_data )
uint8 questStatus = DIALOG_STATUS_NONE;
uint8 defstatus = DIALOG_STATUS_NONE;
Object* questgiver = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
Object* questgiver = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT);
if(!questgiver)
{
sLog.outDetail("Error in CMSG_QUESTGIVER_STATUS_QUERY, called for not found questgiver (Typeid: %u GUID: %u)",GuidHigh2TypeId(GUID_HIPART(guid)),GUID_LOPART(guid));
@ -118,7 +118,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_ACCEPT_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), quest, unk1 );
Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER);
Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_PLAYER_OR_ITEM);
// no or incorrect quest giver
if(!pObject
@ -234,7 +234,7 @@ void WorldSession::HandleQuestgiverQueryQuestOpcode( WorldPacket & recv_data )
sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_QUERY_QUEST npc = %u, quest = %u, unk1 = %u", uint32(GUID_LOPART(guid)), quest, unk1 );
// Verify that the guid is valid and is a questgiver or involved in the requested quest
Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM);
Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_GAMEOBJECT_OR_ITEM);
if(!pObject||!pObject->hasQuest(quest) && !pObject->hasInvolvedQuest(quest))
{
_player->PlayerTalkClass->CloseGossip();
@ -278,7 +278,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode( WorldPacket & recv_data )
sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_CHOOSE_REWARD npc = %u, quest = %u, reward = %u",uint32(GUID_LOPART(guid)),quest,reward );
Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT);
if(!pObject)
return;
@ -328,7 +328,7 @@ void WorldSession::HandleQuestgiverRequestRewardOpcode( WorldPacket & recv_data
sLog.outDebug( "WORLD: Received CMSG_QUESTGIVER_REQUEST_REWARD npc = %u, quest = %u",uint32(GUID_LOPART(guid)),quest );
Object* pObject = ObjectAccessor::GetObjectByTypeMask(*_player, guid,TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT);
Object* pObject = _player->GetObjectByTypeMask(guid, TYPEMASK_CREATURE_OR_GAMEOBJECT);
if(!pObject||!pObject->hasInvolvedQuest(quest))
return;
@ -644,7 +644,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
uint8 questStatus = DIALOG_STATUS_NONE;
uint8 defstatus = DIALOG_STATUS_NONE;
if (IS_CREATURE_OR_PET_GUID(*itr))
if (itr->IsCreatureOrPet())
{
// need also pet quests case support
Creature *questgiver = GetPlayer()->GetMap()->GetCreatureOrPetOrVehicle(*itr);
@ -660,7 +660,7 @@ void WorldSession::HandleQuestgiverStatusMultipleQuery(WorldPacket& /*recvPacket
data << uint8(questStatus);
++count;
}
else if(IS_GAMEOBJECT_GUID(*itr))
else if (itr->IsGameobject())
{
GameObject *questgiver = GetPlayer()->GetMap()->GetGameObject(*itr);
if(!questgiver)

View file

@ -58,10 +58,13 @@ bool LoadScriptingModule(char const* libName)
||!(testScript->ScriptsFree =(scriptCallScriptsFree )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ScriptsFree" ))
||!(testScript->ScriptsVersion =(scriptCallScriptsVersion )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"ScriptsVersion" ))
||!(testScript->GossipHello =(scriptCallGossipHello )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipHello" ))
||!(testScript->GOGossipHello =(scriptCallGOGossipHello )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOGossipHello" ))
||!(testScript->GOChooseReward =(scriptCallGOChooseReward )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOChooseReward" ))
||!(testScript->QuestAccept =(scriptCallQuestAccept )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"QuestAccept" ))
||!(testScript->GossipSelect =(scriptCallGossipSelect )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipSelect" ))
||!(testScript->GOGossipSelect =(scriptCallGOGossipSelect )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOGossipSelect" ))
||!(testScript->GossipSelectWithCode=(scriptCallGossipSelectWithCode)MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GossipSelectWithCode"))
||!(testScript->GOGossipSelectWithCode=(scriptCallGOGossipSelectWithCode)MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"GOGossipSelectWithCode"))
||!(testScript->QuestSelect =(scriptCallQuestSelect )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"QuestSelect" ))
||!(testScript->QuestComplete =(scriptCallQuestComplete )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"QuestComplete" ))
||!(testScript->NPCDialogStatus =(scriptCallNPCDialogStatus )MANGOS_GET_PROC_ADDR(testScript->hScriptsLib,"NPCDialogStatus" ))

View file

@ -41,9 +41,12 @@ typedef void(MANGOS_IMPORT * scriptCallScriptsFree) ();
typedef char const* (MANGOS_IMPORT * scriptCallScriptsVersion) ();
typedef bool(MANGOS_IMPORT * scriptCallGossipHello) (Player *player, Creature *_Creature );
typedef bool(MANGOS_IMPORT * scriptCallGOGossipHello) (Player *player, GameObject *_GO);
typedef bool(MANGOS_IMPORT * scriptCallQuestAccept) (Player *player, Creature *_Creature, Quest const *);
typedef bool(MANGOS_IMPORT * scriptCallGossipSelect)(Player *player, Creature *_Creature, uint32 sender, uint32 action);
typedef bool(MANGOS_IMPORT * scriptCallGOGossipSelect)(Player *player, GameObject *_GO, uint32 sender, uint32 action);
typedef bool(MANGOS_IMPORT * scriptCallGossipSelectWithCode)( Player *player, Creature *_Creature, uint32 sender, uint32 action, const char* sCode );
typedef bool(MANGOS_IMPORT * scriptCallGOGossipSelectWithCode)( Player *player, GameObject *_GO, uint32 sender, uint32 action, const char* sCode );
typedef bool(MANGOS_IMPORT * scriptCallQuestSelect)( Player *player, Creature *_Creature, Quest const* );
typedef bool(MANGOS_IMPORT * scriptCallQuestComplete)(Player *player, Creature *_Creature, Quest const*);
typedef uint32(MANGOS_IMPORT * scriptCallNPCDialogStatus)( Player *player, Creature *_Creature);
@ -70,10 +73,13 @@ typedef struct
scriptCallScriptsVersion ScriptsVersion;
scriptCallGossipHello GossipHello;
scriptCallGOGossipHello GOGossipHello;
scriptCallGOChooseReward GOChooseReward;
scriptCallQuestAccept QuestAccept;
scriptCallGossipSelect GossipSelect;
scriptCallGOGossipSelect GOGossipSelect;
scriptCallGossipSelectWithCode GossipSelectWithCode;
scriptCallGOGossipSelectWithCode GOGossipSelectWithCode;
scriptCallQuestSelect QuestSelect;
scriptCallQuestComplete QuestComplete;
scriptCallNPCDialogStatus NPCDialogStatus;

View file

@ -281,7 +281,7 @@ void SocialMgr::BroadcastToFriendListers(Player *player, WorldPacket *packet)
PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(guid);
if(itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND))
{
Player *pFriend = ObjectAccessor::FindPlayer(MAKE_NEW_GUID(itr->first, 0, HIGHGUID_PLAYER));
Player *pFriend = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, itr->first));
// PLAYER see his team only and PLAYER can't see MODERATOR, GAME MASTER, ADMINISTRATOR characters
// MODERATOR, GAME MASTER, ADMINISTRATOR can see all

View file

@ -51,7 +51,9 @@ enum SpellCastTargetFlags
TARGET_FLAG_UNK1 = 0x00004000, // 199 spells, opening object/lock
TARGET_FLAG_CORPSE = 0x00008000, // pguid, resurrection spells
TARGET_FLAG_UNK2 = 0x00010000, // pguid, not used in any spells as of 3.0.3 (can be set dynamically)
TARGET_FLAG_GLYPH = 0x00020000 // used in glyph spells
TARGET_FLAG_GLYPH = 0x00020000, // used in glyph spells
TARGET_FLAG_UNK3 = 0x00040000, //
TARGET_FLAG_UNK4 = 0x00080000 // uint32, loop { vec3, guid -> if guid == 0 break }
};
enum SpellCastFlags

View file

@ -8936,7 +8936,8 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
case 5142: // Increased Lightning Damage
case 5147: // Improved Consecration / Libram of Resurgence
case 5148: // Idol of the Shooting Star
case 6008: // Increased Lightning Damage / Totem of Hex
case 6008: // Increased Lightning Damage
case 8627: // Totem of Hex
{
DoneTotal+=(*i)->GetModifier()->m_amount;
break;
@ -9035,6 +9036,18 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
}
break;
}
case SPELLFAMILY_PRIEST:
{
// Glyph of Smite
if (spellProto->SpellFamilyFlags & UI64LIT(0x00000080))
{
// Holy Fire
if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, UI64LIT(0x00100000), NULL))
if (Aura *aur = GetAura(55692, EFFECT_INDEX_0))
DoneTotalMod *= (aur->GetModifier()->m_amount+100.0f) / 100.0f;
}
break;
}
case SPELLFAMILY_DEATHKNIGHT:
{
// Icy Touch, Howling Blast and Frost Strike

View file

@ -23,18 +23,19 @@
#include "Log.h"
#include "Opcodes.h"
#include "World.h"
#include "ObjectGuid.h"
#include <zlib/zlib.h>
UpdateData::UpdateData() : m_blockCount(0)
{
}
void UpdateData::AddOutOfRangeGUID(std::set<uint64>& guids)
void UpdateData::AddOutOfRangeGUID(std::set<ObjectGuid>& guids)
{
m_outOfRangeGUIDs.insert(guids.begin(),guids.end());
}
void UpdateData::AddOutOfRangeGUID(const uint64 &guid)
void UpdateData::AddOutOfRangeGUID(ObjectGuid const &guid)
{
m_outOfRangeGUIDs.insert(guid);
}
@ -114,10 +115,8 @@ bool UpdateData::BuildPacket(WorldPacket *packet)
buf << (uint8) UPDATETYPE_OUT_OF_RANGE_OBJECTS;
buf << (uint32) m_outOfRangeGUIDs.size();
for(std::set<uint64>::const_iterator i = m_outOfRangeGUIDs.begin(); i != m_outOfRangeGUIDs.end(); ++i)
{
buf.appendPackGUID(*i);
}
for(std::set<ObjectGuid>::const_iterator i = m_outOfRangeGUIDs.begin(); i != m_outOfRangeGUIDs.end(); ++i)
buf << i->WriteAsPacked();
}
buf.append(m_data);

View file

@ -22,7 +22,7 @@
#include "ByteBuffer.h"
class WorldPacket;
class ObjectGuid;
enum OBJECT_UPDATE_TYPE
{
@ -54,18 +54,18 @@ class UpdateData
public:
UpdateData();
void AddOutOfRangeGUID(std::set<uint64>& guids);
void AddOutOfRangeGUID(const uint64 &guid);
void AddOutOfRangeGUID(std::set<ObjectGuid>& guids);
void AddOutOfRangeGUID(ObjectGuid const &guid);
void AddUpdateBlock(const ByteBuffer &block);
bool BuildPacket(WorldPacket *packet);
bool HasData() { return m_blockCount > 0 || !m_outOfRangeGUIDs.empty(); }
void Clear();
std::set<uint64> const& GetOutOfRangeGUIDs() const { return m_outOfRangeGUIDs; }
std::set<ObjectGuid> const& GetOutOfRangeGUIDs() const { return m_outOfRangeGUIDs; }
protected:
uint32 m_blockCount;
std::set<uint64> m_outOfRangeGUIDs;
std::set<ObjectGuid> m_outOfRangeGUIDs;
ByteBuffer m_data;
void Compress(void* dst, uint32 *dst_size, void* src, int src_size);

View file

@ -725,6 +725,8 @@ void World::LoadConfigSettings(bool reload)
setConfig(CONFIG_BOOL_OFFHAND_CHECK_AT_TALENTS_RESET, "OffhandCheckAtTalentsReset", false);
setConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET, "Network.KickOnBadPacket", false);
if(int clientCacheId = sConfig.GetIntDefault("ClientCacheVersion", 0))
{
// overwrite DB/old value

View file

@ -301,6 +301,7 @@ enum eConfigBoolValues
CONFIG_BOOL_ARENA_AUTO_DISTRIBUTE_POINTS,
CONFIG_BOOL_ARENA_QUEUE_ANNOUNCER_JOIN,
CONFIG_BOOL_ARENA_QUEUE_ANNOUNCER_EXIT,
CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET,
CONFIG_BOOL_VALUE_COUNT
};
@ -368,6 +369,8 @@ enum RealmZone
#define SCRIPT_COMMAND_REMOVE_AURA 14 // source (datalong2!=0) or target (datalong==0) unit, datalong = spell_id
#define SCRIPT_COMMAND_CAST_SPELL 15 // source/target cast spell at target/source (script->datalong2: 0: s->t 1: s->s 2: t->t 3: t->s
#define SCRIPT_COMMAND_PLAY_SOUND 16 // source = any object, target=any/player, datalong (sound_id), datalong2 (bitmask: 0/1=anyone/target, 0/2=with distance dependent, so 1|2 = 3 is target with distance dependent)
#define SCRIPT_COMMAND_CREATE_ITEM 17 // source or target must be player, datalong = item entry, datalong2 = amount
#define SCRIPT_COMMAND_DESPAWN_SELF 18 // source or target must be creature, datalong = despawn delay
/// Storage class for commands issued for delayed execution
struct CliCommandHolder

View file

@ -248,15 +248,23 @@ bool WorldSession::Update(uint32 /*diff*/)
break;
}
}
catch(ByteBufferException &)
catch (ByteBufferException &)
{
sLog.outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i. Skipped packet.",
sLog.outError("WorldSession::Update ByteBufferException occured while parsing a packet (opcode: %u) from client %s, accountid=%i.",
packet->GetOpcode(), GetRemoteAddress().c_str(), GetAccountId());
if(sLog.IsOutDebug())
{
sLog.outDebug("Dumping error causing packet:");
packet->hexlike();
}
if (sWorld.getConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET))
{
sLog.outDetail("Disconnecting session [account id %u / address %s] for badly formatted packet.",
GetAccountId(), GetRemoteAddress().c_str());
KickPlayer();
}
}
delete packet;

View file

@ -641,10 +641,10 @@ class MANGOS_DLL_SPEC WorldSession
void HandleSetDungeonDifficultyOpcode(WorldPacket& recv_data);
void HandleSetRaidDifficultyOpcode(WorldPacket& recv_data);
void HandleMoveSetCanFlyAckOpcode(WorldPacket& recv_data);
void HandleLfgSetAutoJoinOpcode(WorldPacket& recv_data);
void HandleLfgClearAutoJoinOpcode(WorldPacket& recv_data);
void HandleLfmSetAutoFillOpcode(WorldPacket& recv_data);
void HandleLfmClearAutoFillOpcode(WorldPacket& recv_data);
void HandleLfgJoinOpcode(WorldPacket& recv_data);
void HandleLfgLeaveOpcode(WorldPacket& recv_data);
void HandleSearchLfgJoinOpcode(WorldPacket& recv_data);
void HandleSearchLfgLeaveOpcode(WorldPacket& recv_data);
void HandleLfgClearOpcode(WorldPacket& recv_data);
void HandleLfmClearOpcode(WorldPacket& recv_data);
void HandleSetLfmOpcode(WorldPacket& recv_data);

View file

@ -713,7 +713,7 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
}
catch (ByteBufferException &)
{
sLog.outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i. Disconnected client.",
sLog.outError("WorldSocket::ProcessIncoming ByteBufferException occured while parsing an instant handled packet (opcode: %u) from client %s, accountid=%i.",
opcode, GetRemoteAddress().c_str(), m_Session?m_Session->GetAccountId():-1);
if(sLog.IsOutDebug())
{
@ -721,7 +721,15 @@ int WorldSocket::ProcessIncoming (WorldPacket* new_pct)
new_pct->hexlike();
}
return -1;
if (sWorld.getConfig(CONFIG_BOOL_KICK_PLAYER_ON_BAD_PACKET))
{
sLog.outDetail("Disconnecting session [account id %i / address %s] for badly formatted packet.",
m_Session?m_Session->GetAccountId():-1, GetRemoteAddress().c_str());
return -1;
}
else
return 0;
}
ACE_NOTREACHED (return 0);

View file

@ -1348,12 +1348,18 @@ Arena.ArenaSeason.InProgress = 1
# Default: 0 (enable Nagle algorithm, less traffic, more latency)
# 1 (TCP_NO_DELAY, disable Nagle algorithm, more traffic but less latency)
#
# Network.KickOnBadPacket
# Kick player on bad packet format.
# Default: 0 - do not kick
# 1 - kick
#
###################################################################################################################
Network.Threads = 1
Network.OutKBuff = -1
Network.OutUBuff = 65536
Network.TcpNodelay = 1
Network.KickOnBadPacket = 0
###################################################################################################################
# CONSOLE, REMOTE ACCESS AND SOAP

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9565"
#define REVISION_NR "9578"
#endif // __REVISION_NR_H__