mirror of
https://github.com/tbamud/tbamud.git
synced 2025-09-22 05:50:48 +02:00
Merge pull request #84 from tbamud/crash-bug-in-object-drop-script
Crash bug in object drop script
This commit is contained in:
commit
1f520546b2
4 changed files with 56 additions and 26 deletions
|
@ -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)
|
||||
{
|
||||
long object_id = obj_script_id(obj);
|
||||
|
||||
if (!drop_otrigger(obj, ch))
|
||||
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;
|
||||
|
||||
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);
|
||||
} else {
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
long object_id = obj_script_id(obj);
|
||||
|
||||
if (!drop_wtrigger(obj, ch)) {
|
||||
if (has_obj_by_uid_in_lookup_table(object_id))
|
||||
extract_obj(obj);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -447,13 +451,20 @@ static int perform_drop(struct char_data *ch, struct obj_data *obj,
|
|||
{
|
||||
char buf[MAX_STRING_LENGTH];
|
||||
int value;
|
||||
long object_id = obj_script_id(obj);
|
||||
|
||||
if (!drop_otrigger(obj, ch))
|
||||
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))
|
||||
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)) {
|
||||
snprintf(buf, sizeof(buf), "You can't %s $p, it must be CURSED!", sname);
|
||||
act(buf, FALSE, ch, obj, 0, TO_CHAR);
|
||||
|
|
|
@ -2994,12 +2994,23 @@ void init_lookup_table(void)
|
|||
}
|
||||
}
|
||||
|
||||
static struct char_data *find_char_by_uid_in_lookup_table(long uid)
|
||||
static inline struct lookup_table_t *get_bucket_head(long uid)
|
||||
{
|
||||
int bucket = (int) (uid & (BUCKET_COUNT - 1));
|
||||
struct lookup_table_t *lt = &lookup_table[bucket];
|
||||
return &lookup_table[bucket];
|
||||
}
|
||||
|
||||
static inline struct lookup_table_t *find_element_by_uid_in_lookup_table(long uid)
|
||||
{
|
||||
struct lookup_table_t *lt = get_bucket_head(uid);
|
||||
|
||||
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)
|
||||
return (struct char_data *)(lt->c);
|
||||
|
@ -3010,10 +3021,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)
|
||||
{
|
||||
int bucket = (int) (uid & (BUCKET_COUNT - 1));
|
||||
struct lookup_table_t *lt = &lookup_table[bucket];
|
||||
|
||||
for (;lt && lt->uid != uid ; lt = lt->next) ;
|
||||
struct lookup_table_t *lt = find_element_by_uid_in_lookup_table(uid);
|
||||
|
||||
if (lt)
|
||||
return (struct obj_data *)(lt->c);
|
||||
|
@ -3022,10 +3030,16 @@ static struct obj_data *find_obj_by_uid_in_lookup_table(long uid)
|
|||
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)
|
||||
{
|
||||
int bucket = (int) (uid & (BUCKET_COUNT - 1));
|
||||
struct lookup_table_t *lt = &lookup_table[bucket];
|
||||
struct lookup_table_t *lt = get_bucket_head(uid);
|
||||
|
||||
if (lt && lt->uid == uid) {
|
||||
log("add_to_lookup updating existing value for uid=%ld (%p -> %p)", uid, lt->c, c);
|
||||
|
@ -3036,6 +3050,7 @@ void add_to_lookup_table(long uid, void *c)
|
|||
for (;lt && lt->next; lt = lt->next)
|
||||
if (lt->next->uid == uid) {
|
||||
log("add_to_lookup updating existing value for uid=%ld (%p -> %p)", uid, lt->next->c, c);
|
||||
lt->next->c = c;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -3054,9 +3069,7 @@ void remove_from_lookup_table(long uid)
|
|||
if (uid == 0)
|
||||
return;
|
||||
|
||||
for (;lt;lt = lt->next)
|
||||
if (lt->uid == uid)
|
||||
flt = lt;
|
||||
flt = find_element_by_uid_in_lookup_table(uid);
|
||||
|
||||
if (flt) {
|
||||
for (lt = &lookup_table[bucket];lt->next != flt;lt = lt->next)
|
||||
|
|
|
@ -449,6 +449,8 @@ void wld_command_interpreter(room_data *room, char *argument);
|
|||
// id helpers
|
||||
extern long char_script_id(char_data *ch);
|
||||
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)
|
||||
|
||||
#endif /* _DG_SCRIPTS_H_ */
|
||||
|
|
|
@ -462,6 +462,7 @@ int receive_mtrigger(char_data *ch, char_data *actor, obj_data *obj)
|
|||
trig_data *t;
|
||||
char buf[MAX_INPUT_LENGTH];
|
||||
int ret_val;
|
||||
long object_id = obj_script_id(obj);
|
||||
|
||||
if (!SCRIPT_CHECK(ch, MTRIG_RECEIVE) || AFF_FLAGGED(ch, AFF_CHARM))
|
||||
return 1;
|
||||
|
@ -471,9 +472,10 @@ int receive_mtrigger(char_data *ch, char_data *actor, obj_data *obj)
|
|||
(rand_number(1, 100) <= GET_TRIG_NARG(t))){
|
||||
|
||||
ADD_UID_VAR(buf, t, char_script_id(actor), "actor", 0);
|
||||
ADD_UID_VAR(buf, t, obj_script_id(obj), "object", 0);
|
||||
ADD_UID_VAR(buf, t, object_id, "object", 0);
|
||||
ret_val = script_driver(&ch, t, MOB_TRIGGER, TRIG_NEW);
|
||||
if (DEAD(actor) || DEAD(ch) || obj->carried_by != actor)
|
||||
// check for purged item before dereferencing.
|
||||
if (DEAD(actor) || DEAD(ch) || !has_obj_by_uid_in_lookup_table(object_id) || obj->carried_by != actor)
|
||||
return 0;
|
||||
else
|
||||
return ret_val;
|
||||
|
@ -1118,6 +1120,7 @@ int drop_wtrigger(obj_data *obj, char_data *actor)
|
|||
trig_data *t;
|
||||
char buf[MAX_INPUT_LENGTH];
|
||||
int ret_val;
|
||||
long object_id = obj_script_id(obj);
|
||||
|
||||
if (!actor || !SCRIPT_CHECK(&world[IN_ROOM(actor)], WTRIG_DROP))
|
||||
return 1;
|
||||
|
@ -1127,9 +1130,10 @@ int drop_wtrigger(obj_data *obj, char_data *actor)
|
|||
if (TRIGGER_CHECK(t, WTRIG_DROP) &&
|
||||
(rand_number(1, 100) <= GET_TRIG_NARG(t))) {
|
||||
ADD_UID_VAR(buf, t, char_script_id(actor), "actor", 0);
|
||||
ADD_UID_VAR(buf, t, obj_script_id(obj), "object", 0);
|
||||
ADD_UID_VAR(buf, t, object_id, "object", 0);
|
||||
ret_val = script_driver(&room, t, WLD_TRIGGER, TRIG_NEW);
|
||||
if (obj->carried_by != actor)
|
||||
// check for purged object before dereferencing.
|
||||
if (!has_obj_by_uid_in_lookup_table(object_id) || obj->carried_by != actor)
|
||||
return 0;
|
||||
else
|
||||
return ret_val;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue