diff options
| author | Franklin Wei <git@fwei.tk> | 2016-03-26 20:47:42 -0400 |
|---|---|---|
| committer | Franklin Wei <git@fwei.tk> | 2016-03-26 20:47:42 -0400 |
| commit | f6ced470369099e3d837e661b59f9dc539ebde70 (patch) | |
| tree | 19b10984b9670f21a421f61d11a29fb83b51db6f /src | |
| parent | eb8b5907df2cf3c4b593197d40d10e83e6943ee3 (diff) | |
| download | netcosm-f6ced470369099e3d837e661b59f9dc539ebde70.zip netcosm-f6ced470369099e3d837e661b59f9dc539ebde70.tar.gz netcosm-f6ced470369099e3d837e661b59f9dc539ebde70.tar.bz2 netcosm-f6ced470369099e3d837e661b59f9dc539ebde70.tar.xz | |
fix drop bug
Diffstat (limited to 'src')
| -rw-r--r-- | src/hash.c | 50 | ||||
| -rw-r--r-- | src/hash.h | 9 | ||||
| -rw-r--r-- | src/multimap.c | 4 | ||||
| -rw-r--r-- | src/room.c | 4 | ||||
| -rw-r--r-- | src/server_reqs.c | 13 |
5 files changed, 70 insertions, 10 deletions
@@ -328,6 +328,56 @@ bool hash_remove(void *ptr, const void *key) return false; } +/* return an opaque pointer to a particular key/value pair */ +struct hash_export_node hash_get_internal_node(void *ptr, const void *key) +{ + if(ptr) + { + struct hash_map *map = ptr; + CHECK_SENTINEL(map); + unsigned hash = map->hash(key) % map->table_sz; + + struct hash_node *iter = map->table[hash], *last = NULL;; + + while(iter) + { + if(map->compare(key, iter->key) == 0) + { + struct hash_export_node ret; + ret.hash = hash; + ret.last = last; + ret.node = iter; + ret.next = iter->next; + return ret; + } + last = iter; + iter = iter->next; + } + /* fall through */ + } + + struct hash_export_node ret; + ret.node = NULL; + return ret; +} + +void hash_del_internal_node(void *ptr, const struct hash_export_node *node) +{ + if(ptr) + { + if(node->node) + { + struct hash_map *map = ptr; + CHECK_SENTINEL(map); + + if(node->last) + ((struct hash_node*)node->last)->next = node->next; + else + map->table[node->hash] = node->next; + } + } +} + void *hash_getkeyptr(void *ptr, const void *key) { if(ptr) @@ -102,3 +102,12 @@ void *hash_dup(void*); /* sets the callback for when duplicating a data node */ void hash_setdupdata_cb(void*, void *(*cb)(void*)); + +struct hash_export_node { + unsigned hash; + void *last, *node, *next; +}; + +struct hash_export_node hash_get_internal_node(void *ptr, const void *key); + +void hash_del_internal_node(void *ptr, const struct hash_export_node *node); diff --git a/src/multimap.c b/src/multimap.c index 033b511..28a509c 100644 --- a/src/multimap.c +++ b/src/multimap.c @@ -192,6 +192,8 @@ size_t multimap_delete(void *ptr, const void *key, const void *val) struct multimap_node *node = hash_lookup(map->hash_tab, key); + struct hash_export_node internal_node = hash_get_internal_node(map->hash_tab, key); + if(!node) return 0; @@ -227,7 +229,7 @@ size_t multimap_delete(void *ptr, const void *key, const void *val) if(!node->n_pairs) { - hash_remove(map->hash_tab, key); + hash_del_internal_node(map->hash_tab, &internal_node); } return deleted; @@ -175,7 +175,6 @@ size_t room_obj_count_noalias(room_id id) bool room_obj_del_by_ptr(room_id room, struct object_t *obj) { - debugf("room_obj_del_by_ptr: deleting object %s\n", obj->name); struct obj_alias_t *iter = obj->alias_list; struct object_t tmp; @@ -183,13 +182,10 @@ bool room_obj_del_by_ptr(room_id room, struct object_t *obj) while(iter) { - debugf(" deleting alias %s\n", iter->alias); multimap_delete(room_get(room)->objects, iter->alias, &tmp); iter = iter->next; } - debugf("After deleting aliases of object: %s:\n", obj->name); - return multimap_delete(room_get(room)->objects, obj->name, &tmp); } diff --git a/src/server_reqs.c b/src/server_reqs.c index fffdee1..f76b8a7 100644 --- a/src/server_reqs.c +++ b/src/server_reqs.c @@ -466,14 +466,17 @@ static void req_drop(unsigned char *data, size_t datalen, struct child_data *sen const struct multimap_list *next = iter->next; struct object_t *obj = iter->val; - if(!obj->class->hook_drop || (obj->class->hook_drop && obj->class->hook_drop(obj, sender))) + room_obj_add(sender->room, obj_dup(obj)); + userdb_del_obj_by_ptr(sender->user, obj); + + if(obj->class->hook_drop && !obj->class->hook_drop(obj, sender)) { - send_msg(sender, "Dropped.\n"); - room_obj_add(sender->room, obj_dup(obj)); - userdb_del_obj_by_ptr(sender->user, obj); + send_msg(sender, "You cannot drop that.\n"); + userdb_add_obj(sender->user, obj_dup(obj)); + room_obj_del_by_ptr(sender->room, obj); } else - send_msg(sender, "You cannot drop that.\n"); + send_msg(sender, "Dropped.\n"); iter = next; } |