aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2016-03-29 11:47:35 -0400
committerFranklin Wei <git@fwei.tk>2016-03-29 11:47:35 -0400
commit8426162eb0a463118e77e3fe32b96552565584a1 (patch)
tree0ca533cd57581fbc71f26e2d5bf0fe108ee9ba95
parent2687778cf7c099e47de410d62d26d874f4dcebba (diff)
downloadnetcosm-8426162eb0a463118e77e3fe32b96552565584a1.zip
netcosm-8426162eb0a463118e77e3fe32b96552565584a1.tar.gz
netcosm-8426162eb0a463118e77e3fe32b96552565584a1.tar.bz2
netcosm-8426162eb0a463118e77e3fe32b96552565584a1.tar.xz
add things
-rw-r--r--Makefile2
-rw-r--r--src/client.c10
-rw-r--r--src/client_reqs.c4
-rw-r--r--src/room.h3
-rw-r--r--src/server.c7
-rw-r--r--src/server_reqs.c30
-rw-r--r--src/util.h2
-rw-r--r--src/world.c48
-rw-r--r--src/world.h2
-rw-r--r--worlds/test.c69
10 files changed, 151 insertions, 26 deletions
diff --git a/Makefile b/Makefile
index f905e72..f9fc032 100644
--- a/Makefile
+++ b/Makefile
@@ -39,7 +39,7 @@ DEBUGFLAGS = -g
CFLAGS = $(OPTFLAGS) $(DEBUGFLAGS) $(WARNFLAGS) -std=c99 $(INCLUDES)
-LDFLAGS = -lev -lcrypto -lbsd
+LDFLAGS = -lev -lcrypto
HEADERS = src/*.h export/include/*.h
diff --git a/src/client.c b/src/client.c
index 90a166b..45139e8 100644
--- a/src/client.c
+++ b/src/client.c
@@ -46,9 +46,9 @@ void out_raw(const void *buf, size_t len)
error("out() called from master");
if(!len)
return;
-
+
try_again:
-
+
while(output_locked);
/* something weird happened and the value changed between the loop and here */
@@ -102,7 +102,9 @@ void __attribute__((format(printf,1,2))) out(const char *fmt, ...)
if(is_newline)
++ptr; /* skip the newline */
- while(*ptr == ' ')
+
+ /* skip following spaces */
+ while(*ptr == ' ')
++ptr;
last_space = 0;
pos = 0;
@@ -186,7 +188,7 @@ tryagain:
}
}
-/* still not encrypted, but a bit more secure than echoing the password! */
+/* still not encrypted, but a bit better than echoing the password! */
char *client_read_password(void)
{
telnet_echo_off();
diff --git a/src/client_reqs.c b/src/client_reqs.c
index 40d1c61..a1cf947 100644
--- a/src/client_reqs.c
+++ b/src/client_reqs.c
@@ -82,9 +82,7 @@ bool poll_requests(void)
int status = *((int*)data);
reqdata_type = TYPE_BOOLEAN;
- returned_reqdata.boolean = status;
- if(!status)
- out("You cannot go that way.\n");
+ returned_reqdata.boolean = (status == 1);
break;
}
case REQ_GETUSERDATA:
diff --git a/src/room.h b/src/room.h
index 0b68734..c0304c7 100644
--- a/src/room.h
+++ b/src/room.h
@@ -42,6 +42,7 @@ struct roomdata_t {
char *name;
char *desc;
+ /* unmutable properties, changes will have no effect */
const char * const adjacent[NUM_DIRECTIONS];
void (* const hook_init)(room_id id);
@@ -51,6 +52,8 @@ struct roomdata_t {
*/
/* NOTE: struct child_data is aliased as "user_t"!!! */
+
+ /* return false to deny entering/leaving a room */
bool (* const hook_enter)(room_id room, struct child_data *user);
bool (* const hook_leave)(room_id room, struct child_data *user);
void (* const hook_serialize)(room_id room, int fd);
diff --git a/src/server.c b/src/server.c
index f0b56ec..ba7d916 100644
--- a/src/server.c
+++ b/src/server.c
@@ -408,16 +408,19 @@ int server_main(int argc, char *argv[])
server_socket = server_bind();
userdb_init(USERFILE);
-
+
+ /* also perform first-time setup */
check_userfile();
+
load_worldfile();
+ /* initialize request map */
reqmap_init();
/* save some time after a fork() */
client_init();
- /* this initial size very low to make iteration faster */
+ /* this initial size is set very low to make iteration faster */
child_map = hash_init(16, pid_hash, pid_equal);
hash_setfreedata_cb(child_map, free_child_data);
hash_setfreekey_cb(child_map, free);
diff --git a/src/server_reqs.c b/src/server_reqs.c
index 4a147ae..eadae9f 100644
--- a/src/server_reqs.c
+++ b/src/server_reqs.c
@@ -150,7 +150,7 @@ static void req_send_desc(unsigned char *data, size_t datalen, struct child_data
send_packet(sender, REQ_BCASTMSG, (void*)room->data.desc, strlen(room->data.desc));
send_packet(sender, REQ_PRINTNEWLINE, NULL, 0);
-
+
/* list objects */
char buf[MSG_MAX];
buf[0] = 0;
@@ -230,20 +230,32 @@ static void req_set_room(unsigned char *data, size_t datalen, struct child_data
static void req_move_room(unsigned char *data, size_t datalen, struct child_data *sender)
{
(void) data; (void) datalen; (void) sender;
+
+ int status = 0;
+
enum direction_t dir = *((enum direction_t*)data);
struct room_t *current = room_get(sender->room);
- room_user_del(sender->room, sender);
-
- /* TODO: checking */
+ /* TODO: bounds checking on `dir' */
room_id new = current->adjacent[dir];
- int status = 0;
- if(new != ROOM_NONE)
+ struct room_t *new_room = room_get(new);
+
+ if((!new_room->data.hook_enter ||
+ (new_room->data.hook_enter && new_room->data.hook_enter(new, sender))) &&
+ (!current->data.hook_leave ||
+ (current->data.hook_leave && current->data.hook_leave(sender->room, sender))))
{
- child_set_room(sender, new);
- status = 1;
+ room_user_del(sender->room, sender);
+
+ if(new != ROOM_NONE)
+ {
+
+ child_set_room(sender, new);
+ status = 1;
+ }
+ else
+ send_msg(sender, "You cannot go that way.\n");
}
-
send_packet(sender, REQ_MOVE, &status, sizeof(status));
}
diff --git a/src/util.h b/src/util.h
index 6de6945..147e7c0 100644
--- a/src/util.h
+++ b/src/util.h
@@ -47,3 +47,5 @@ void write_size(int fd, size_t);
size_t read_size(int fd);
bool is_vowel(char c);
+
+size_t strlcat(char *dst, const char *src, size_t siz);
diff --git a/src/world.c b/src/world.c
index a854e49..a06b08e 100644
--- a/src/world.c
+++ b/src/world.c
@@ -29,6 +29,9 @@ static struct room_t *world;
static size_t world_sz;
static char *world_name;
+/* map of room names -> rooms */
+static void *world_map = NULL;
+
struct room_t *room_get(room_id id)
{
return world + id;
@@ -124,8 +127,22 @@ void world_save(const char *fname)
world[i].data.hook_serialize(i, fd);
}
+ /* write the object counter so future objects will have sequential ids */
write_uint64(fd, obj_get_idcounter());
+ /* now write the map of room names to ids */
+ void *ptr = world_map, *save;
+ for(unsigned int i = 0; i < world_sz; ++i)
+ {
+ void *key;
+ struct room_t *room = hash_iterate(ptr, &save, &key);
+ if(!room)
+ break;
+ ptr = NULL;
+ write_string(fd, key);
+ write_roomid(fd, &room->id);
+ }
+
close(fd);
}
@@ -230,6 +247,18 @@ bool world_load(const char *fname, const struct roomdata_t *data, size_t data_sz
obj_set_idcounter(read_uint64(fd));
+ /* read in the room name -> room map */
+
+ world_map = hash_init(world_sz * 2, hash_djb, compare_strings);
+
+ for(unsigned int i = 0; i < world_sz; ++i)
+ {
+ const char *key = read_string(fd);
+ room_id id = read_roomid(fd);
+ debugf("'%s' -> %d\n", key, id);
+ hash_insert(world_map, key, world + id);
+ }
+
close(fd);
return true;
}
@@ -245,7 +274,7 @@ void world_init(const struct roomdata_t *data, size_t sz, const char *name)
world_sz = 0;
world_name = strdup(name);
- void *map = hash_init(sz / 2 + 1, hash_djb, compare_strings);
+ world_map = hash_init(sz * 2, hash_djb, compare_strings);
for(size_t i = 0; i < sz; ++i)
{
@@ -258,7 +287,7 @@ void world_init(const struct roomdata_t *data, size_t sz, const char *name)
world[i].data.desc = strdup(world[i].data.desc);
debugf("Loading room '%s'\n", world[i].data.uniq_id);
- if(hash_insert(map, world[i].data.uniq_id, world + i))
+ if(hash_insert(world_map, world[i].data.uniq_id, world + i))
error("Duplicate room ID '%s'", world[i].data.uniq_id);
for(int dir = 0; dir < NUM_DIRECTIONS; ++dir)
@@ -266,7 +295,7 @@ void world_init(const struct roomdata_t *data, size_t sz, const char *name)
const char *adjacent_room = world[i].data.adjacent[dir];
if(adjacent_room)
{
- struct room_t *room = hash_lookup(map, adjacent_room);
+ struct room_t *room = hash_lookup(world_map, adjacent_room);
if(room)
world[i].adjacent[dir] = room->id;
}
@@ -284,7 +313,7 @@ void world_init(const struct roomdata_t *data, size_t sz, const char *name)
const char *adjacent_room = world[i].data.adjacent[dir];
if(adjacent_room)
{
- struct room_t *room = hash_lookup(map, adjacent_room);
+ struct room_t *room = hash_lookup(world_map, adjacent_room);
if(room)
world[i].adjacent[dir] = room->id;
else
@@ -339,8 +368,6 @@ void world_init(const struct roomdata_t *data, size_t sz, const char *name)
}
hash_free(dir_map);
-
- hash_free(map);
}
static void *verb_map = NULL;
@@ -368,3 +395,12 @@ void *world_verb_map(void)
init_map();
return verb_map;
}
+
+room_id room_get_id(const char *uniq_id)
+{
+ struct room_t *room = hash_lookup(world_map, uniq_id);
+ if(!room)
+ return ROOM_NONE;
+ else
+ return room->id;
+}
diff --git a/src/world.h b/src/world.h
index 5d9ccae..7749a63 100644
--- a/src/world.h
+++ b/src/world.h
@@ -59,3 +59,5 @@ void world_free(void);
/* this goes in world_ and not room_ */
struct room_t *room_get(room_id id);
+
+room_id room_get_id(const char *uniq_id);
diff --git a/worlds/test.c b/worlds/test.c
index c99fa33..64dcfdb 100644
--- a/worlds/test.c
+++ b/worlds/test.c
@@ -1,5 +1,7 @@
#include <world_api.h>
+/* implements dunnet in NetCosm */
+
/************ ROOM DEFINITIONS ************/
static void deadend_init(room_id id)
@@ -84,6 +86,32 @@ static void hidden_init(room_id id)
room_obj_add_alias(id, new, "bracelet");
}
+static bool building_enter(room_id id, user_t *user)
+{
+ if(multimap_lookup(userdb_lookup(user->user)->objects, "shiny brass key", NULL))
+ return true;
+ else
+ {
+ send_msg(user, "You don't have a key that can open this door.\n");
+ return false;
+ }
+}
+
+static void mailroom_init(room_id id)
+{
+ struct object_t *new = obj_new("/generic/notake");
+ new->name = strdup("bins");
+ new->hidden = true;
+
+ /* insert IAC NOP to prevent the extra whitespace from being dropped */
+ new->userdata = strdup("All of the bins are empty. Looking closely you can see that there are names written at the bottom of each bin, but most of them are faded away so that you cannot read them. You can only make out three names:\n\377\361 Jeffrey Collier\n\377\361 Robert Toukmond\n\377\361 Thomas Stock\n");
+ room_obj_add(id, new);
+}
+
+static void computer_room_init(room_id id)
+{
+}
+
const struct roomdata_t netcosm_world[] = {
{
"dead_end",
@@ -180,8 +208,47 @@ const struct roomdata_t netcosm_world[] = {
"building_front",
"Building Front",
"You are at the end of the road. There is a building in front of you to the northeast, and the road leads back to the southwest.",
- { NONE_N, NONE_NE, NONE_E, NONE_SE, NONE_S, "nesw_road", NONE_W, NONE_NW, NONE_UP, NONE_DN, NONE_IN, NONE_OT },
+ { NONE_N, "building_hallway", NONE_E, NONE_SE, NONE_S, "nesw_road", NONE_W, NONE_NW, NONE_UP, NONE_DN, "building_hallway", NONE_OT },
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
NULL,
+ },
+
+ {
+ "building_hallway",
+ "Old Building hallway",
+ "You are in the hallway of an old building. There are rooms to the east and west, and doors leading out to the north and south.",
+ { NONE_N, NONE_NE, "mailroom", NONE_SE, "building_front", NONE_SW, "computer_room", NONE_NW, NONE_UP, NONE_DN, NONE_IN, "building_front" },
+ NULL,
+ building_enter,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ },
+
+ {
+ "mailroom",
+ "Mailroom",
+ "You are in a mailroom. There are many bins where the mail is usually kept. The exit is to the west.",
+ { NONE_N, NONE_NE, NONE_E, NONE_SE, NONE_S, NONE_SW, "building_hallway", NONE_NW, NONE_UP, NONE_DN, NONE_IN, NONE_OT },
+ mailroom_init,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ },
+
+ {
+ "computer_room",
+ "Computer room",
+ "You are in a computer room. It seems like most of the equipment has been removed. There is a VAX 11/780 in front of you, however, with one of the cabinets wide open. A sign on the front of the machine says: This VAX is named 'pokey'. To type on the console, use the 'type' command. The exit is to the east.\nThe panel lights are steady and motionless.",
+ { NONE_N, NONE_NE, "building_hallway", NONE_SE, NONE_S, NONE_SW, NONE_W, NONE_NW, NONE_UP, NONE_DN, NONE_IN, NONE_OT },
+ computer_room_init,
NULL,
NULL,
NULL,