[11310] Make .npc add/.gobject add commands work safe.

Reserve at server startup some guods follow last used in static DB spawns guid
for creatures/gameobjects for use in .npc add/.gobject add commands.
This allow safe select guids not used in all map copies. Guids for temporary spawns
used from range frollow after reserved guids range.

This also let select new static spawns guids (added in game chat command) near to already used static guids.
So it let avoid gaps in static guids lists.

Amount reserved guids set in new GuidReserveSize.* config options.
This commit is contained in:
VladimirMangos 2011-04-03 21:15:24 +04:00
parent c93256e477
commit b92ebd994f
12 changed files with 76 additions and 18 deletions

View file

@ -24,7 +24,7 @@ CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL,
`cache_id` int(10) default '0', `cache_id` int(10) default '0',
`required_11234_01_mangos_command` bit(1) default NULL `required_11310_01_mangos_mangos_string` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
-- --
@ -3867,7 +3867,8 @@ INSERT INTO `mangos_string` VALUES
(1206,'dot damage',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1206,'dot damage',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1500,'%u - [%s] AutoSpawn: %u MaxLimit: %u Creatures: %u GameObjecs: %u Pools %u Chance: %f %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1500,'%u - [%s] AutoSpawn: %u MaxLimit: %u Creatures: %u GameObjecs: %u Pools %u Chance: %f %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1501,'%u - |cffffffff|Hpool:%u|h[%s]|h|r AutoSpawn: %u MaxLimit: %u Creatures: %u GameObjecs: %u Pools %u %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), (1501,'%u - |cffffffff|Hpool:%u|h[%s]|h|r AutoSpawn: %u MaxLimit: %u Creatures: %u GameObjecs: %u Pools %u %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1502,'%u - [%s] AutoSpawn: %u MaxLimit: %u Creatures: %u GameObjecs: %u Pools %u %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); (1502,'%u - [%s] AutoSpawn: %u MaxLimit: %u Creatures: %u GameObjecs: %u Pools %u %s',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL),
(1503,'Can not add spawn because no free guids for static spawn in reserved guids range. Need restart server before command will can used. Also look GuidReserveSize.* config options.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
/*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */; /*!40000 ALTER TABLE `mangos_string` ENABLE KEYS */;
UNLOCK TABLES; UNLOCK TABLES;

View file

@ -0,0 +1,6 @@
ALTER TABLE db_version CHANGE COLUMN required_11234_01_mangos_command required_11310_01_mangos_mangos_string bit;
DELETE FROM mangos_string WHERE entry IN (1503);
INSERT INTO mangos_string VALUES
(1503,'Can not add spawn because no free guids for static spawn in reserved guids range. Need restart server before command will can used. Also look GuidReserveSize.* config options.',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);

View file

@ -935,7 +935,8 @@ enum MangosStrings
LANG_POOL_CHANCE_POOL_LIST_CONSOLE = 1500, LANG_POOL_CHANCE_POOL_LIST_CONSOLE = 1500,
LANG_POOL_POOL_LIST_CHAT = 1501, LANG_POOL_POOL_LIST_CHAT = 1501,
LANG_POOL_POOL_LIST_CONSOLE = 1502, LANG_POOL_POOL_LIST_CONSOLE = 1502,
// Room for more Level 2 1503-1599 not used LANG_NO_FREE_STATIC_GUID_FOR_SPAWN = 1503,
// Room for more Level 2 1504-1599 not used
// FREE IDS 1600-9999 // FREE IDS 1600-9999

View file

@ -1086,7 +1086,15 @@ bool ChatHandler::HandleGameObjectAddCommand(char* args)
Map *map = chr->GetMap(); Map *map = chr->GetMap();
GameObject* pGameObj = new GameObject; GameObject* pGameObj = new GameObject;
uint32 db_lowGUID = map->GenerateLocalLowGuid(HIGHGUID_GAMEOBJECT);
// used guids from specially reserved range (can be 0 if no free values)
uint32 db_lowGUID = sObjectMgr.GenerateStaticGameobjectLowGuid();
if (!db_lowGUID)
{
SendSysMessage(LANG_NO_FREE_STATIC_GUID_FOR_SPAWN);
SetSentErrorMessage(true);
return false;
}
if (!pGameObj->Create(db_lowGUID, gInfo->id, map, chr->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, GO_ANIMPROGRESS_DEFAULT, GO_STATE_READY)) if (!pGameObj->Create(db_lowGUID, gInfo->id, map, chr->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, GO_ANIMPROGRESS_DEFAULT, GO_STATE_READY))
{ {
@ -1556,7 +1564,16 @@ bool ChatHandler::HandleNpcAddCommand(char* args)
Creature* pCreature = new Creature; Creature* pCreature = new Creature;
if (!pCreature->Create(map->GenerateLocalLowGuid(HIGHGUID_UNIT), pos, id)) // used guids from specially reserved range (can be 0 if no free values)
uint32 lowguid = sObjectMgr.GenerateStaticCreatureLowGuid();
if (!lowguid)
{
SendSysMessage(LANG_NO_FREE_STATIC_GUID_FOR_SPAWN);
SetSentErrorMessage(true);
return false;
}
if (!pCreature->Create(lowguid, pos, id))
{ {
delete pCreature; delete pCreature;
return false; return false;

View file

@ -77,8 +77,8 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode)
i_gridExpiry(expiry), m_TerrainData(sTerrainMgr.LoadTerrain(id)), i_gridExpiry(expiry), m_TerrainData(sTerrainMgr.LoadTerrain(id)),
i_data(NULL), i_script_id(0) i_data(NULL), i_script_id(0)
{ {
m_CreatureGuids.Set(sObjectMgr.GetFirstCreatureLowGuid()); m_CreatureGuids.Set(sObjectMgr.GetFirstTemporaryCreatureLowGuid());
m_GameObjectGuids.Set(sObjectMgr.GetFirstGameObjectLowGuid()); m_GameObjectGuids.Set(sObjectMgr.GetFirstTemporaryGameObjectLowGuid());
for(unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j) for(unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j)
{ {

View file

@ -141,8 +141,8 @@ template uint32 IdGenerator<uint32>::Generate();
template uint64 IdGenerator<uint64>::Generate(); template uint64 IdGenerator<uint64>::Generate();
ObjectMgr::ObjectMgr() : ObjectMgr::ObjectMgr() :
m_CreatureFirstGuid(1), m_FirstTemporaryCreatureGuid(1),
m_GameObjectFirstGuid(1), m_FirstTemporaryGameObjectGuid(1),
m_ArenaTeamIds("Arena team ids"), m_ArenaTeamIds("Arena team ids"),
m_AuctionIds("Auction ids"), m_AuctionIds("Auction ids"),
@ -5606,7 +5606,7 @@ void ObjectMgr::SetHighestGuids()
result = WorldDatabase.Query( "SELECT MAX(guid) FROM creature" ); result = WorldDatabase.Query( "SELECT MAX(guid) FROM creature" );
if( result ) if( result )
{ {
m_CreatureFirstGuid = (*result)[0].GetUInt32()+1; m_FirstTemporaryCreatureGuid = (*result)[0].GetUInt32()+1;
delete result; delete result;
} }
@ -5635,7 +5635,7 @@ void ObjectMgr::SetHighestGuids()
result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject" ); result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject" );
if( result ) if( result )
{ {
m_GameObjectFirstGuid = (*result)[0].GetUInt32()+1; m_FirstTemporaryGameObjectGuid = (*result)[0].GetUInt32()+1;
delete result; delete result;
} }
@ -5687,6 +5687,13 @@ void ObjectMgr::SetHighestGuids()
m_GroupIds.Set((*result)[0].GetUInt32()+1); m_GroupIds.Set((*result)[0].GetUInt32()+1);
delete result; delete result;
} }
// setup reserved ranges for static guids spawn
m_StaticCreatureGuids.Set(m_FirstTemporaryCreatureGuid);
m_FirstTemporaryCreatureGuid += sWorld.getConfig(CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE);
m_StaticGamebjectGuids.Set(m_FirstTemporaryGameObjectGuid);
m_FirstTemporaryGameObjectGuid += sWorld.getConfig(CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT);
} }
void ObjectMgr::LoadGameObjectLocales() void ObjectMgr::LoadGameObjectLocales()

View file

@ -719,8 +719,12 @@ class ObjectMgr
void SetHighestGuids(); void SetHighestGuids();
// used for set initial guid counter for map local guids // used for set initial guid counter for map local guids
uint32 GetFirstCreatureLowGuid() const { return m_CreatureFirstGuid; } uint32 GetFirstTemporaryCreatureLowGuid() const { return m_FirstTemporaryCreatureGuid; }
uint32 GetFirstGameObjectLowGuid() const { return m_GameObjectFirstGuid; } uint32 GetFirstTemporaryGameObjectLowGuid() const { return m_FirstTemporaryGameObjectGuid; }
// used in .npc add/.gobject add commands for adding static spawns
uint32 GenerateStaticCreatureLowGuid() { if (m_StaticCreatureGuids.GetNextAfterMaxUsed() >= m_FirstTemporaryCreatureGuid) return 0; return m_StaticCreatureGuids.Generate(); }
uint32 GenerateStaticGameobjectLowGuid() { if (m_StaticGamebjectGuids.GetNextAfterMaxUsed() >= m_FirstTemporaryGameObjectGuid) return 0; return m_StaticGamebjectGuids.Generate(); }
uint32 GeneratePlayerLowGuid() { return m_CharGuids.Generate(); } uint32 GeneratePlayerLowGuid() { return m_CharGuids.Generate(); }
uint32 GenerateItemLowGuid() { return m_ItemGuids.Generate(); } uint32 GenerateItemLowGuid() { return m_ItemGuids.Generate(); }
@ -1045,8 +1049,12 @@ class ObjectMgr
IdGenerator<uint32> m_GroupIds; IdGenerator<uint32> m_GroupIds;
// initial free low guid for selected guid type for map local guids // initial free low guid for selected guid type for map local guids
uint32 m_CreatureFirstGuid; uint32 m_FirstTemporaryCreatureGuid;
uint32 m_GameObjectFirstGuid; uint32 m_FirstTemporaryGameObjectGuid;
// guids from reserved range for use in .npc add/.gobject add commands for adding new static spawns (saved in DB) from client.
ObjectGuidGenerator<HIGHGUID_UNIT> m_StaticCreatureGuids;
ObjectGuidGenerator<HIGHGUID_GAMEOBJECT> m_StaticGamebjectGuids;
// first free low guid for selected guid type // first free low guid for selected guid type
ObjectGuidGenerator<HIGHGUID_PLAYER> m_CharGuids; ObjectGuidGenerator<HIGHGUID_PLAYER> m_CharGuids;

View file

@ -837,6 +837,11 @@ void World::LoadConfigSettings(bool reload)
setConfigMinMax(CONFIG_UINT32_CHARDELETE_MIN_LEVEL, "CharDelete.MinLevel", 0, 0, getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL)); setConfigMinMax(CONFIG_UINT32_CHARDELETE_MIN_LEVEL, "CharDelete.MinLevel", 0, 0, getConfig(CONFIG_UINT32_MAX_PLAYER_LEVEL));
setConfigPos(CONFIG_UINT32_CHARDELETE_KEEP_DAYS, "CharDelete.KeepDays", 30); setConfigPos(CONFIG_UINT32_CHARDELETE_KEEP_DAYS, "CharDelete.KeepDays", 30);
if (configNoReload(reload, CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE, "GuidReserveSize.Creature", 100))
setConfigPos(CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE, "GuidReserveSize.Creature", 100);
if (configNoReload(reload, CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT, "GuidReserveSize.Gameobject", 100))
setConfigPos(CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT, "GuidReserveSize.Gameobject", 100);
///- Read the "Data" directory from the config file ///- Read the "Data" directory from the config file
std::string dataPath = sConfig.GetStringDefault("DataDir", "./"); std::string dataPath = sConfig.GetStringDefault("DataDir", "./");

View file

@ -185,6 +185,8 @@ enum eConfigUInt32Values
CONFIG_UINT32_CHARDELETE_KEEP_DAYS, CONFIG_UINT32_CHARDELETE_KEEP_DAYS,
CONFIG_UINT32_CHARDELETE_METHOD, CONFIG_UINT32_CHARDELETE_METHOD,
CONFIG_UINT32_CHARDELETE_MIN_LEVEL, CONFIG_UINT32_CHARDELETE_MIN_LEVEL,
CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE,
CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT,
CONFIG_UINT32_VALUE_COUNT CONFIG_UINT32_VALUE_COUNT
}; };

View file

@ -847,7 +847,7 @@ AllowTwoSide.AddFriend = 0
TalentsInspecting = 1 TalentsInspecting = 1
################################################################################################################### ###################################################################################################################
# CREATURE SETTINGS # CREATURE AND GAMEOBJECT SETTINGS
# #
# ThreatRadius # ThreatRadius
# Radius for creature to evade after being pulled away from combat start point # Radius for creature to evade after being pulled away from combat start point
@ -935,6 +935,14 @@ TalentsInspecting = 1
# Distance from player to listen text that creature (or other world object) yell # Distance from player to listen text that creature (or other world object) yell
# Default: 300 # Default: 300
# #
# GuidReserveSize.Creature
# GuidReserveSize.Gameobject
# Amount guids reserved for .npc add/.gobject add directly after last used in DB static spawned creature/gameobject guid
# Commands .npc add/.gobject add can be used only for guids from this reserve and required server restart if all guids
# from reserve used before above commands can be used in like case. Less size increase amount guids for dynamic spawns
# in game from other side
# Default: 100
#
################################################################################################################### ###################################################################################################################
ThreatRadius = 100 ThreatRadius = 100
@ -969,6 +977,9 @@ Rate.Creature.Elite.RARE.HP = 1
ListenRange.Say = 40 ListenRange.Say = 40
ListenRange.TextEmote = 40 ListenRange.TextEmote = 40
ListenRange.Yell = 300 ListenRange.Yell = 300
GuidReserveSize.Creature = 100
GuidReserveSize.Gameobject = 100
################################################################################################################### ###################################################################################################################
# CHAT SETTINGS # CHAT SETTINGS

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "11309" #define REVISION_NR "11310"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__

View file

@ -1,6 +1,6 @@
#ifndef __REVISION_SQL_H__ #ifndef __REVISION_SQL_H__
#define __REVISION_SQL_H__ #define __REVISION_SQL_H__
#define REVISION_DB_CHARACTERS "required_11299_02_characters_pet_aura" #define REVISION_DB_CHARACTERS "required_11299_02_characters_pet_aura"
#define REVISION_DB_MANGOS "required_11234_01_mangos_command" #define REVISION_DB_MANGOS "required_11310_01_mangos_mangos_string"
#define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version" #define REVISION_DB_REALMD "required_10008_01_realmd_realmd_db_version"
#endif // __REVISION_SQL_H__ #endif // __REVISION_SQL_H__