Remove crash bug when purging a dropped item in a wtrigger.

We're leveraging the lookup table, because it's a safer way
to see if an object has been free'd than looking at the object
itself (which while it may work may just as well fail).

Fixes #83
This commit is contained in:
Thomas Arp
2020-03-01 01:19:06 +01:00
parent 140cdc5d22
commit d5a11618f1
3 changed files with 40 additions and 19 deletions

View File

@@ -52,11 +52,12 @@ static void wear_message(struct char_data *ch, struct obj_data *obj, int where);
static void perform_put(struct char_data *ch, struct obj_data *obj, struct obj_data *cont) static void perform_put(struct char_data *ch, struct obj_data *obj, struct obj_data *cont)
{ {
long object_id = obj_script_id(obj);
if (!drop_otrigger(obj, ch)) if (!drop_otrigger(obj, ch))
return; return;
if (!obj) /* object might be extracted by drop_otrigger */ if (!has_obj_by_uid_in_lookup_table(object_id)) /* object might be extracted by drop_otrigger */
return; return;
if ((GET_OBJ_VAL(cont, 0) > 0) && if ((GET_OBJ_VAL(cont, 0) > 0) &&
@@ -416,9 +417,12 @@ static void perform_drop_gold(struct char_data *ch, int amount, byte mode, room_
act("$p suddenly appears in a puff of orange smoke!", 0, 0, obj, 0, TO_ROOM); act("$p suddenly appears in a puff of orange smoke!", 0, 0, obj, 0, TO_ROOM);
} else { } else {
char buf[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH];
long object_id = obj_script_id(obj);
if (!drop_wtrigger(obj, ch)) { if (!drop_wtrigger(obj, ch)) {
if (has_obj_by_uid_in_lookup_table(object_id))
extract_obj(obj); extract_obj(obj);
return; return;
} }
@@ -447,13 +451,20 @@ static int perform_drop(struct char_data *ch, struct obj_data *obj,
{ {
char buf[MAX_STRING_LENGTH]; char buf[MAX_STRING_LENGTH];
int value; int value;
long object_id = obj_script_id(obj);
if (!drop_otrigger(obj, ch)) if (!drop_otrigger(obj, ch))
return 0; return 0;
if (!has_obj_by_uid_in_lookup_table(object_id))
return 0; // item was extracted by script
if ((mode == SCMD_DROP) && !drop_wtrigger(obj, ch)) if ((mode == SCMD_DROP) && !drop_wtrigger(obj, ch))
return 0; return 0;
if (!has_obj_by_uid_in_lookup_table(object_id))
return 0; // item was extracted by script
if (OBJ_FLAGGED(obj, ITEM_NODROP) && !PRF_FLAGGED(ch, PRF_NOHASSLE)) { if (OBJ_FLAGGED(obj, ITEM_NODROP) && !PRF_FLAGGED(ch, PRF_NOHASSLE)) {
snprintf(buf, sizeof(buf), "You can't %s $p, it must be CURSED!", sname); snprintf(buf, sizeof(buf), "You can't %s $p, it must be CURSED!", sname);
act(buf, FALSE, ch, obj, 0, TO_CHAR); act(buf, FALSE, ch, obj, 0, TO_CHAR);

View File

@@ -2994,12 +2994,18 @@ void init_lookup_table(void)
} }
} }
static struct char_data *find_char_by_uid_in_lookup_table(long uid) static struct lookup_table_t *find_element_by_uid_in_lookup_table(long uid)
{ {
int bucket = (int) (uid & (BUCKET_COUNT - 1)); int bucket = (int) (uid & (BUCKET_COUNT - 1));
struct lookup_table_t *lt = &lookup_table[bucket]; struct lookup_table_t *lt = &lookup_table[bucket];
for (;lt && lt->uid != uid ; lt = lt->next) ; for (;lt && lt->uid != uid ; lt = lt->next) ;
return lt;
}
static struct char_data *find_char_by_uid_in_lookup_table(long uid)
{
struct lookup_table_t *lt = find_element_by_uid_in_lookup_table(uid);
if (lt) if (lt)
return (struct char_data *)(lt->c); return (struct char_data *)(lt->c);
@@ -3010,10 +3016,7 @@ static struct char_data *find_char_by_uid_in_lookup_table(long uid)
static struct obj_data *find_obj_by_uid_in_lookup_table(long uid) static struct obj_data *find_obj_by_uid_in_lookup_table(long uid)
{ {
int bucket = (int) (uid & (BUCKET_COUNT - 1)); struct lookup_table_t *lt = find_element_by_uid_in_lookup_table(uid);
struct lookup_table_t *lt = &lookup_table[bucket];
for (;lt && lt->uid != uid ; lt = lt->next) ;
if (lt) if (lt)
return (struct obj_data *)(lt->c); return (struct obj_data *)(lt->c);
@@ -3022,6 +3025,13 @@ static struct obj_data *find_obj_by_uid_in_lookup_table(long uid)
return NULL; return NULL;
} }
int has_obj_by_uid_in_lookup_table(long uid)
{
struct lookup_table_t *lt = find_element_by_uid_in_lookup_table(uid);
return lt != NULL;
}
void add_to_lookup_table(long uid, void *c) void add_to_lookup_table(long uid, void *c)
{ {
int bucket = (int) (uid & (BUCKET_COUNT - 1)); int bucket = (int) (uid & (BUCKET_COUNT - 1));
@@ -3054,9 +3064,7 @@ void remove_from_lookup_table(long uid)
if (uid == 0) if (uid == 0)
return; return;
for (;lt;lt = lt->next) flt = find_element_by_uid_in_lookup_table(uid);
if (lt->uid == uid)
flt = lt;
if (flt) { if (flt) {
for (lt = &lookup_table[bucket];lt->next != flt;lt = lt->next) for (lt = &lookup_table[bucket];lt->next != flt;lt = lt->next)

View File

@@ -449,6 +449,8 @@ void wld_command_interpreter(room_data *room, char *argument);
// id helpers // id helpers
extern long char_script_id(char_data *ch); extern long char_script_id(char_data *ch);
extern long obj_script_id(obj_data *obj); extern long obj_script_id(obj_data *obj);
extern int has_obj_by_uid_in_lookup_table(long uid);
#define room_script_id(room) ((long)(room)->number + ROOM_ID_BASE) #define room_script_id(room) ((long)(room)->number + ROOM_ID_BASE)
#endif /* _DG_SCRIPTS_H_ */ #endif /* _DG_SCRIPTS_H_ */