diff options
-rw-r--r-- | Changelog-Trunk.txt | 7 | ||||
-rw-r--r-- | db/item_delay.txt | 1 | ||||
-rw-r--r-- | src/map/itemdb.c | 11 | ||||
-rw-r--r-- | src/map/pc.c | 41 |
4 files changed, 36 insertions, 24 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 5835f95f8..8525fe027 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -1,5 +1,12 @@ Date Added +2010/11/29 + * Resolved issues with item delay system. [Ai4rei] + - Fixed random crashes caused by map_session_data corruption due to out-of-bounds access to item_delay array (bugreport:4568, since r14455). + - Fixed item delay database not being compatible with @reloaditemdb. Item delays are now reset upon reloading, much like a restart would do (bugreport:4589). + - Fixed trailing commented lines in db/item_delay.txt could cause 'too many entries' error to be displayed. + - Fixed last entity of a cash food item not being recognized as cash food, thus not receiving use delay, due to access to deleted inventory slot (since r14426). + - These changes also fix a warning regarding variable 'i' in pc_useitem being potentionally uninitialized (bugreport:4559). 2010/11/28 * Added an option to re-roll the /dice emotion server-side, to prevent cheats during events (bugreport:4194). [Ai4rei] * Added emotion_type enumeration for clif_emotion constants. [Ai4rei] diff --git a/db/item_delay.txt b/db/item_delay.txt index 716d60ebc..a0b1389bd 100644 --- a/db/item_delay.txt +++ b/db/item_delay.txt @@ -1,6 +1,5 @@ // Item Delay Database // Max number of entries is defined in itemdb.h as MAX_ITEMDELAYS -// WARNING: Adding/removing/modifying entries here and then using @reloaditemdb will cause problems/inconsistencies! // // Structure: // Item ID,Delay in Milliseconds diff --git a/src/map/itemdb.c b/src/map/itemdb.c index d1eed4b27..8eb173a85 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -27,8 +27,6 @@ static struct item_group itemgroup_db[MAX_ITEMGROUP]; struct item_data dummy_item; //This is the default dummy item used for non-existant items. [Skotlex] -int item_delays = 0; - /*========================================== * 名前で検索用 *------------------------------------------*/ @@ -667,7 +665,7 @@ static int itemdb_read_itemtrade(void) static int itemdb_read_itemdelay(void) { FILE *fp; - int nameid, j; + int nameid, j, item_delays = 0; char line[1024], *str[10], *p; struct item_data *id; @@ -679,12 +677,12 @@ static int itemdb_read_itemdelay(void) while(fgets(line, sizeof(line), fp)) { + if (line[0] == '/' && line[1] == '/') + continue; if (item_delays == MAX_ITEMDELAYS) { ShowError("itemdb_read_itemdelay: Too many entries specified in %s/item_delay.txt! Increase MAX_ITEMDELAYS in itemdb.h!\n", db_path); break; } - if (line[0] == '/' && line[1] == '/') - continue; memset(str, 0, sizeof(str)); for (j = 0, p = line; j < 2 && p; j++) { str[j] = p; @@ -1075,7 +1073,10 @@ void itemdb_reload(void) // readjust itemdb pointer cache for each player iter = mapit_geteachpc(); for( sd = (struct map_session_data*)mapit_first(iter); mapit_exists(iter); sd = (struct map_session_data*)mapit_next(iter) ) + { + memset(sd->item_delay, 0, sizeof(sd->item_delay)); // reset item delays pc_setinventorydata(sd); + } mapit_free(iter); } diff --git a/src/map/pc.c b/src/map/pc.c index deb266e78..bb0eee4bf 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -66,8 +66,6 @@ char motd_text[MOTD_LINE_SIZE][256]; // Message of the day buffer [Valaris] struct duel duel_list[MAX_DUEL]; int duel_count = 0; -extern int item_delays; // [Paradox924X] - //Links related info to the sd->hate_mob[]/sd->feel_map[] entries const struct sg_data sg_info[3] = { { SG_SUN_ANGER, SG_SUN_BLESS, SG_SUN_COMFORT, "PC_FEEL_SUN", "PC_HATE_MOB_SUN", is_day_of_sun }, @@ -532,11 +530,6 @@ int pc_setinventorydata(struct map_session_data *sd) for(i=0;i<MAX_INVENTORY;i++) { id = sd->status.inventory[i].nameid; sd->inventory_data[i] = id?itemdb_search(id):NULL; - if(sd->inventory_data[i] && sd->inventory_data[i]->delay > 0) { // Load delays - sd->item_delay[item_delays].nameid = sd->inventory_data[i]->nameid; - sd->item_delay[item_delays].tick = 0; - ++item_delays; - } } return 0; } @@ -3662,7 +3655,7 @@ int pc_isUseitem(struct map_session_data *sd,int n) *------------------------------------------*/ int pc_useitem(struct map_session_data *sd,int n) { - unsigned int delay, tick = gettick(); + unsigned int tick = gettick(); int amount, i, nameid; struct script_code *script; @@ -3691,13 +3684,6 @@ int pc_useitem(struct map_session_data *sd,int n) // Store information for later use before it is lost (via pc_delitem) [Paradox924X] nameid = sd->inventory_data[n]->nameid; - delay = sd->inventory_data[n]->delay; - - if( sd->inventory_data[n]->delay > 0 ) { // Check if there is a delay on this item [Paradox924X] - ARR_FIND(0, item_delays, i, sd->item_delay[i].nameid == nameid); - if( i < item_delays && DIFF_TICK(sd->item_delay[i].tick, tick) > 0 ) - return 0; // Delay has not expired yet - } //Since most delay-consume items involve using a "skill-type" target cursor, //perform a skill-use check before going through. [Skotlex] @@ -3706,6 +3692,27 @@ int pc_useitem(struct map_session_data *sd,int n) if( sd->inventory_data[n]->flag.delay_consume && ( sd->ud.skilltimer != -1 /*|| !status_check_skilluse(&sd->bl, &sd->bl, ALL_RESURRECTION, 0)*/ ) ) return 0; + if( sd->inventory_data[n]->delay > 0 ) { // Check if there is a delay on this item [Paradox924X] + ARR_FIND(0, MAX_ITEMDELAYS, i, sd->item_delay[i].nameid == nameid || !sd->item_delay[i].nameid); + if( i < MAX_ITEMDELAYS ) + { + if( sd->item_delay[i].nameid ) + {// found + if( DIFF_TICK(sd->item_delay[i].tick, tick) > 0 ) + return 0; // Delay has not expired yet + } + else + {// not yet used item (all slots are initially empty) + sd->item_delay[i].nameid = nameid; + } + sd->item_delay[i].tick = tick + sd->inventory_data[n]->delay; + } + else + {// should not happen + ShowError("pc_useitem: Exceeded item delay array capacity! (nameid=%d, char_id=%d)\n", nameid, sd->status.char_id); + } + } + sd->itemid = sd->status.inventory[n].nameid; sd->itemindex = n; if(sd->catch_target_class != -1) //Abort pet catching. @@ -3741,10 +3748,8 @@ int pc_useitem(struct map_session_data *sd,int n) //Update item use time. sd->canuseitem_tick = tick + battle_config.item_use_interval; - if( itemdb_iscashfood(sd->status.inventory[n].nameid) ) + if( itemdb_iscashfood(nameid) ) sd->canusecashfood_tick = tick + battle_config.cashfood_use_interval; - if( delay > 0 && i < item_delays ) - sd->item_delay[i].tick = tick + delay; run_script(script,0,sd->bl.id,fake_nd->bl.id); potion_flag = 0; |