diff options
| author | Franklin Wei <git@fwei.tk> | 2016-01-24 19:01:04 -0500 |
|---|---|---|
| committer | Franklin Wei <git@fwei.tk> | 2016-01-24 19:01:04 -0500 |
| commit | 6e3d6b3186bc07003d17ad7c54bb013c9b5d6dcf (patch) | |
| tree | c4edcb9e261dd8f819f52a992406749a7490eb7a /src | |
| parent | b346e948cb167c18efc33f32f0e7cfb21050fc96 (diff) | |
| download | netcosm-6e3d6b3186bc07003d17ad7c54bb013c9b5d6dcf.zip netcosm-6e3d6b3186bc07003d17ad7c54bb013c9b5d6dcf.tar.gz netcosm-6e3d6b3186bc07003d17ad7c54bb013c9b5d6dcf.tar.bz2 netcosm-6e3d6b3186bc07003d17ad7c54bb013c9b5d6dcf.tar.xz | |
objects partially work, can't serialize yet
Diffstat (limited to 'src')
| -rw-r--r-- | src/client.c | 14 | ||||
| -rw-r--r-- | src/globals.h | 1 | ||||
| -rw-r--r-- | src/room.c | 40 | ||||
| -rw-r--r-- | src/room.h | 24 | ||||
| -rw-r--r-- | src/server_reqs.c | 39 | ||||
| -rw-r--r-- | src/server_reqs.h | 1 | ||||
| -rw-r--r-- | src/util.c | 9 | ||||
| -rw-r--r-- | src/util.h | 1 |
8 files changed, 101 insertions, 28 deletions
diff --git a/src/client.c b/src/client.c index fef7fab..260d73d 100644 --- a/src/client.c +++ b/src/client.c @@ -419,6 +419,12 @@ void client_look(void) send_master(REQ_GETROOMDESC, NULL, 0); } +void client_look_at(char *obj) +{ + all_lower(obj); + send_master(REQ_LOOKAT, obj, strlen(obj) + 1); +} + #define WSPACE " \t\r\n" void client_main(int fd, struct sockaddr_in *addr, int total, int to, int from) @@ -689,7 +695,13 @@ auth: } else if(!strcmp(tok, "LOOK")) { - client_look(); + char *what = strtok_r(NULL, " ", &save); + if(!what) + client_look(); + else + { + client_look_at(what); + } } else if(!strcmp(tok, "WAIT")) { diff --git a/src/globals.h b/src/globals.h index 9944996..fcf6784 100644 --- a/src/globals.h +++ b/src/globals.h @@ -29,6 +29,7 @@ #include <arpa/telnet.h> #include <assert.h> #include <bsd/stdlib.h> // for arc4random +#include <bsd/string.h> // for strlcat #include <ctype.h> #include <errno.h> #include <fcntl.h> @@ -145,49 +145,36 @@ void world_free(void) struct object_t *obj_new(void) { - struct object_t *new = calloc(1, sizeof(struct object_t)); + struct object_t *obj = calloc(1, sizeof(struct object_t)); /* generate a unique 128-bit id for this object */ /* 64 bits are used to store a nanosecond-resolution timestamp */ /* 64 random bits are also used */ uint64_t timestamp; struct timeval tv; gettimeofday(&tv, NULL); - timestamp = (obj_id)tv.tv_sec * (obj_id)1000000 + (obj_id)tv.tv_usec; + timestamp = (uint64_t)tv.tv_sec * (uint64_t)1000000 + (uint64_t)tv.tv_usec; uint64_t rand_bits; arc4random_buf(&rand_bits, sizeof(rand_bits)); - new->id = ((obj_id)timestamp << 64) | (obj_id)rand_bits; + obj->id.halves[0] = timestamp; + obj->id.halves[1] = rand_bits; - unsigned char bytes[16]; - memcpy(bytes, &new->id, sizeof(bytes)); - debugf("UUID: "); - for(unsigned i = 0; i < sizeof(bytes); ++i) - { - if(i == 4 || i == 6 || i == 8 || i == 10) - debugf("-"); - debugf("%02x", bytes[15 - i]); - } - debugf("\n"); - - return new; + return obj; } bool obj_add(room_id room, struct object_t *obj) { - return !hash_insert(room_get(room)->objects, &obj->id, obj); + return !hash_insert(room_get(room)->objects, obj->name, obj); } -static SIMP_HASH(obj_id, obj_hash); -static SIMP_EQUAL(obj_id, obj_equal); - #define OBJMAP_SIZE 8 /* initialize the room's hash tables */ static void room_init_maps(struct room_t *room) { room->users = hash_init((userdb_size() / 2) + 1, hash_djb, compare_strings); - room->objects = hash_init(OBJMAP_SIZE, obj_hash, obj_equal); + room->objects = hash_init(OBJMAP_SIZE, hash_djb, compare_strings); } /** @@ -349,3 +336,16 @@ void world_init(const struct roomdata_t *data, size_t sz, const char *name) hash_free(map); } + +struct object_t *room_obj_iterate(room_id room, void **save) +{ + if(room != ROOM_NONE) + return hash_iterate(room_get(room)->objects, save, NULL); + else + return hash_iterate(NULL, save, NULL); +} + +struct object_t *room_obj_get(room_id room, const char *name) +{ + return hash_lookup(room_get(room)->objects, name); +} @@ -25,7 +25,11 @@ typedef enum room_id { ROOM_NONE = -1 } room_id; -typedef unsigned __int128 obj_id; +typedef struct int128 { + uint64_t halves[2]; +} int128; + +typedef int128 obj_id; typedef struct child_data user_t; @@ -58,7 +62,7 @@ struct object_t { bool list; void (*hook_serialize)(int fd, struct object_t*); - void (*hook_take)(struct object_t*, user_t *user); + bool (*hook_take)(struct object_t*, user_t *user); void (*hook_drop)(struct object_t*, user_t *user); void (*hook_use)(struct object_t*, user_t *user); void (*hook_destroy)(struct object_t*); @@ -79,7 +83,7 @@ struct room_t { room_id adjacent[NUM_DIRECTIONS]; /* hash maps */ - void *objects; /* obj_id -> object */ + void *objects; /* object name -> object */ void *verbs; void *users; /* username -> child_data */ }; @@ -96,7 +100,17 @@ bool room_user_del(room_id id, struct child_data *child); /* returns a new object with a unique id */ struct object_t *obj_new(void); -/* new should point to a new object allocated with obj_new */ -bool obj_add(room_id room, struct object_t *new); +/* new should point to a new object allocated with obj_new(), with + * 'name' properly set */ +bool obj_add(room_id room, struct object_t *obj); + +/* on the first call, room should be a valid room id, and *save should + * point to a void pointer. On subsequent calls, room should be + * ROOM_NONE, and *save should remain unchanged from the previous + * call */ +struct object_t *room_obj_iterate(room_id room, void **save); + +/* obj should be all lowercase */ +struct object_t *room_obj_get(room_id room, const char *obj); void world_free(void); diff --git a/src/server_reqs.c b/src/server_reqs.c index d10acde..7f82236 100644 --- a/src/server_reqs.c +++ b/src/server_reqs.c @@ -135,8 +135,25 @@ static void req_send_desc(unsigned char *data, size_t datalen, struct child_data struct room_t *room = room_get(sender->room); send_packet(sender, REQ_BCASTMSG, room->data.desc, strlen(room->data.desc)); - send_packet(sender, REQ_PRINTNEWLINE, NULL, 0); + + /* list objects */ + char buf[MSG_MAX]; + buf[0] = 0; + void *save = NULL; + room_id id = sender->room; + while(1) + { + struct object_t *obj = room_obj_iterate(id, &save); + id = ROOM_NONE; + if(!obj) + break; + strlcat(buf, "There is a(n) ", sizeof(buf)); + strlcat(buf, obj->name, sizeof(buf)); + strlcat(buf, " here.\n", sizeof(buf)); + } + + send_packet(sender, REQ_BCASTMSG, buf, strlen(buf)); } static void req_send_roomname(unsigned char *data, size_t datalen, struct child_data *sender) @@ -236,6 +253,23 @@ static void req_kick_always(unsigned char *data, size_t datalen, send_packet(child, REQ_KICK, data, datalen); } +static void req_look_at(unsigned char *data, size_t datalen, struct child_data *sender) +{ + (void) datalen; + struct object_t *obj = room_obj_get(sender->room, (const char*)data); + if(obj) + { + const char *desc = obj->hook_desc(obj, sender); + send_packet(sender, REQ_BCASTMSG, (void*)desc, strlen(desc)); + send_packet(sender, REQ_PRINTNEWLINE, NULL, 0); + } + else + { + const char *msg = "I don't know what that is.\n"; + send_packet(sender, REQ_BCASTMSG, (void*)msg, strlen(msg)); + } +} + static const struct child_request { unsigned char code; @@ -264,7 +298,8 @@ static const struct child_request { { REQ_GETUSERDATA, true, CHILD_NONE, NULL, req_send_user, }, { REQ_DELUSERDATA, true, CHILD_NONE, NULL, req_del_user, }, { REQ_ADDUSERDATA, true, CHILD_NONE, NULL, req_add_user, }, - { REQ_KICKALL, true, CHILD_ALL_BUT_SENDER, req_kick_always, NULL }, + { REQ_KICKALL, true, CHILD_ALL_BUT_SENDER, req_kick_always, NULL, }, + { REQ_LOOKAT, true, CHILD_NONE, NULL, req_look_at, }, //{ REQ_ROOMMSG, true, CHILD_ALL, req_send_room_msg, NULL, }, }; diff --git a/src/server_reqs.h b/src/server_reqs.h index 6ab093b..f148c3e 100644 --- a/src/server_reqs.h +++ b/src/server_reqs.h @@ -38,6 +38,7 @@ #define REQ_PRINTNEWLINE 16 /* child: print a newline */ #define REQ_ALLDONE 17 /* child: break out of send_master() */ #define REQ_KICKALL 18 /* server: kick everyone except the sender */ +#define REQ_LOOKAT 19 /* server: send object description */ /* child states, sent as an int to the master */ #define STATE_INIT 0 /* initial state */ @@ -57,3 +57,12 @@ void all_upper(char *s) s++; } } + +void all_lower(char *s) +{ + while(*s) + { + *s = tolower(*s); + s++; + } +} @@ -24,3 +24,4 @@ void __attribute__((noreturn,format(printf,1,2))) error(const char *fmt, ...); void __attribute__((format(printf,4,5))) debugf_real(const char*, int, const char*, const char *fmt, ...); void remove_cruft(char*); void all_upper(char*); +void all_lower(char*); |