From bbc69c87b96710a51b19b94aee1cedbb0f555336 Mon Sep 17 00:00:00 2001 From: FlavioJS Date: Fri, 23 Jan 2009 17:49:44 +0000 Subject: * Changed npc_get_new_npc_id to ensure that it never returns invalid/used ids. - npc_get_new_npc_id is used to generate ids for npcs/mobs/homunculus/mercenaries/pets. If the server runs for long enough (years to months or less, depending on settings), the auxiliary variable npc_id will eventually overflow and go negative, then go through the range of object ids, then through the range of account ids. This can lead to all sorts of random crashes and memory leaks. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13481 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 7 +++++++ src/map/npc.c | 22 +++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 0d1d1fb1e..da42dc784 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -3,6 +3,13 @@ Date Added AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. +2009/01/23 + * Changed npc_get_new_npc_id to ensure that it never returns invalid/used ids. [FlavioJS] + - npc_get_new_npc_id is used to generate ids for npcs/mobs/homunculus/mercenaries/pets. + If the server runs for long enough (years to months or less, depending on settings), + the auxiliary variable npc_id will eventually overflow and go negative, then go + through the range of object ids, then through the range of account ids. + This can lead to all sorts of random crashes and memory leaks. 2009/01/22 * Changed val4 of SC_BLADESTOP from a block_list pointer to an id. [FlavioJS] 2009/01/21 diff --git a/src/map/npc.c b/src/map/npc.c index 37cf06157..a95b490d9 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -51,7 +51,27 @@ static int npc_script=0; static int npc_mob=0; static int npc_delay_mob=0; static int npc_cache_mob=0; -int npc_get_new_npc_id(void){ return npc_id++; } + +/// Returns a new npc id that isn't being used in id_db. +/// Fatal error if nothing is available. +int npc_get_new_npc_id(void) +{ + if( npc_id >= START_NPC_NUM && map_id2bl(npc_id) == NULL ) + return npc_id++;// available + {// find next id + int base_id = npc_id; + while( base_id != ++npc_id ) + { + if( npc_id < START_NPC_NUM ) + npc_id = START_NPC_NUM; + if( map_id2bl(npc_id) == NULL ) + return npc_id++;// available + } + // full loop, nothing available + ShowFatalError("npc_get_new_npc_id: All ids are taken. Exiting..."); + exit(1); + } +} static DBMap* ev_db; // const char* event_name -> struct event_data* static DBMap* npcname_db; // const char* npc_name -> struct npc_data* -- cgit v1.2.3-70-g09d2