From b92ebd994f2a5b1e765dac07457968e4bbf9b52e Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 3 Apr 2011 21:15:24 +0400 Subject: [PATCH] [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. --- sql/mangos.sql | 5 +++-- sql/updates/11310_01_mangos_mangos_string.sql | 6 ++++++ src/game/Language.h | 3 ++- src/game/Level2.cpp | 21 +++++++++++++++++-- src/game/Map.cpp | 4 ++-- src/game/ObjectMgr.cpp | 15 +++++++++---- src/game/ObjectMgr.h | 16 ++++++++++---- src/game/World.cpp | 5 +++++ src/game/World.h | 2 ++ src/mangosd/mangosd.conf.dist.in | 13 +++++++++++- src/shared/revision_nr.h | 2 +- src/shared/revision_sql.h | 2 +- 12 files changed, 76 insertions(+), 18 deletions(-) create mode 100644 sql/updates/11310_01_mangos_mangos_string.sql diff --git a/sql/mangos.sql b/sql/mangos.sql index 806559f37..c6dfb86f0 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -24,7 +24,7 @@ CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, `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'; -- @@ -3867,7 +3867,8 @@ INSERT INTO `mangos_string` VALUES (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), (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 */; UNLOCK TABLES; diff --git a/sql/updates/11310_01_mangos_mangos_string.sql b/sql/updates/11310_01_mangos_mangos_string.sql new file mode 100644 index 000000000..3cf40a9e1 --- /dev/null +++ b/sql/updates/11310_01_mangos_mangos_string.sql @@ -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); diff --git a/src/game/Language.h b/src/game/Language.h index b4f6f475b..63406946b 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -935,7 +935,8 @@ enum MangosStrings LANG_POOL_CHANCE_POOL_LIST_CONSOLE = 1500, LANG_POOL_POOL_LIST_CHAT = 1501, 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 diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 04f4d8a4c..28b511892 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1086,7 +1086,15 @@ bool ChatHandler::HandleGameObjectAddCommand(char* args) Map *map = chr->GetMap(); 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)) { @@ -1556,7 +1564,16 @@ bool ChatHandler::HandleNpcAddCommand(char* args) 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; return false; diff --git a/src/game/Map.cpp b/src/game/Map.cpp index 9f6315517..b4e4bf5f2 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -77,8 +77,8 @@ Map::Map(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode) i_gridExpiry(expiry), m_TerrainData(sTerrainMgr.LoadTerrain(id)), i_data(NULL), i_script_id(0) { - m_CreatureGuids.Set(sObjectMgr.GetFirstCreatureLowGuid()); - m_GameObjectGuids.Set(sObjectMgr.GetFirstGameObjectLowGuid()); + m_CreatureGuids.Set(sObjectMgr.GetFirstTemporaryCreatureLowGuid()); + m_GameObjectGuids.Set(sObjectMgr.GetFirstTemporaryGameObjectLowGuid()); for(unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j) { diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 47a9e2950..92049d4e4 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -141,8 +141,8 @@ template uint32 IdGenerator::Generate(); template uint64 IdGenerator::Generate(); ObjectMgr::ObjectMgr() : - m_CreatureFirstGuid(1), - m_GameObjectFirstGuid(1), + m_FirstTemporaryCreatureGuid(1), + m_FirstTemporaryGameObjectGuid(1), m_ArenaTeamIds("Arena team ids"), m_AuctionIds("Auction ids"), @@ -5606,7 +5606,7 @@ void ObjectMgr::SetHighestGuids() result = WorldDatabase.Query( "SELECT MAX(guid) FROM creature" ); if( result ) { - m_CreatureFirstGuid = (*result)[0].GetUInt32()+1; + m_FirstTemporaryCreatureGuid = (*result)[0].GetUInt32()+1; delete result; } @@ -5635,7 +5635,7 @@ void ObjectMgr::SetHighestGuids() result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject" ); if( result ) { - m_GameObjectFirstGuid = (*result)[0].GetUInt32()+1; + m_FirstTemporaryGameObjectGuid = (*result)[0].GetUInt32()+1; delete result; } @@ -5687,6 +5687,13 @@ void ObjectMgr::SetHighestGuids() m_GroupIds.Set((*result)[0].GetUInt32()+1); 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() diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index d0ba3ede9..b4e8f4d9a 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -719,8 +719,12 @@ class ObjectMgr void SetHighestGuids(); // used for set initial guid counter for map local guids - uint32 GetFirstCreatureLowGuid() const { return m_CreatureFirstGuid; } - uint32 GetFirstGameObjectLowGuid() const { return m_GameObjectFirstGuid; } + uint32 GetFirstTemporaryCreatureLowGuid() const { return m_FirstTemporaryCreatureGuid; } + 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 GenerateItemLowGuid() { return m_ItemGuids.Generate(); } @@ -1045,8 +1049,12 @@ class ObjectMgr IdGenerator m_GroupIds; // initial free low guid for selected guid type for map local guids - uint32 m_CreatureFirstGuid; - uint32 m_GameObjectFirstGuid; + uint32 m_FirstTemporaryCreatureGuid; + 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 m_StaticCreatureGuids; + ObjectGuidGenerator m_StaticGamebjectGuids; // first free low guid for selected guid type ObjectGuidGenerator m_CharGuids; diff --git a/src/game/World.cpp b/src/game/World.cpp index 7445c2d20..d3d9e516f 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -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)); 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 std::string dataPath = sConfig.GetStringDefault("DataDir", "./"); diff --git a/src/game/World.h b/src/game/World.h index d38248912..32ef77b79 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -185,6 +185,8 @@ enum eConfigUInt32Values CONFIG_UINT32_CHARDELETE_KEEP_DAYS, CONFIG_UINT32_CHARDELETE_METHOD, CONFIG_UINT32_CHARDELETE_MIN_LEVEL, + CONFIG_UINT32_GUID_RESERVE_SIZE_CREATURE, + CONFIG_UINT32_GUID_RESERVE_SIZE_GAMEOBJECT, CONFIG_UINT32_VALUE_COUNT }; diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in index 61ffd07a9..d8bc43aaa 100644 --- a/src/mangosd/mangosd.conf.dist.in +++ b/src/mangosd/mangosd.conf.dist.in @@ -847,7 +847,7 @@ AllowTwoSide.AddFriend = 0 TalentsInspecting = 1 ################################################################################################################### -# CREATURE SETTINGS +# CREATURE AND GAMEOBJECT SETTINGS # # ThreatRadius # 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 # 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 @@ -969,6 +977,9 @@ Rate.Creature.Elite.RARE.HP = 1 ListenRange.Say = 40 ListenRange.TextEmote = 40 ListenRange.Yell = 300 +GuidReserveSize.Creature = 100 +GuidReserveSize.Gameobject = 100 + ################################################################################################################### # CHAT SETTINGS diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 1fa9d3cb3..b54e95b7c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "11309" + #define REVISION_NR "11310" #endif // __REVISION_NR_H__ diff --git a/src/shared/revision_sql.h b/src/shared/revision_sql.h index 60c45bc1a..9d99ff707 100644 --- a/src/shared/revision_sql.h +++ b/src/shared/revision_sql.h @@ -1,6 +1,6 @@ #ifndef __REVISION_SQL_H__ #define __REVISION_SQL_H__ #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" #endif // __REVISION_SQL_H__