aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2016-03-26 20:47:42 -0400
committerFranklin Wei <git@fwei.tk>2016-03-26 20:47:42 -0400
commitf6ced470369099e3d837e661b59f9dc539ebde70 (patch)
tree19b10984b9670f21a421f61d11a29fb83b51db6f /src
parenteb8b5907df2cf3c4b593197d40d10e83e6943ee3 (diff)
downloadnetcosm-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.c50
-rw-r--r--src/hash.h9
-rw-r--r--src/multimap.c4
-rw-r--r--src/room.c4
-rw-r--r--src/server_reqs.c13
5 files changed, 70 insertions, 10 deletions
diff --git a/src/hash.c b/src/hash.c
index 59c05bf..290c668 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -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)
diff --git a/src/hash.h b/src/hash.h
index 9ea3627..5a8b965 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -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;
diff --git a/src/room.c b/src/room.c
index 9cc8c8c..a78d978 100644
--- a/src/room.c
+++ b/src/room.c
@@ -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;
}