aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client.c46
-rw-r--r--src/netcosm.h37
-rw-r--r--src/server.c25
3 files changed, 87 insertions, 21 deletions
diff --git a/src/client.c b/src/client.c
index 7639273..96f8150 100644
--- a/src/client.c
+++ b/src/client.c
@@ -53,10 +53,9 @@ static void signal_master(void)
sigprocmask(SIG_SETMASK, &old, NULL);
errno = 0;
- printf("Spinning until completed flag set.\n");
+
/* spin until we're done handling the request */
while(!request_complete) usleep(1);
- printf("Request completely done.\n");
}
void send_master(unsigned char cmd, const void *data, size_t sz)
@@ -144,6 +143,13 @@ void sigusr2_handler(int s, siginfo_t *info, void *vp)
out_raw(buf, len);
exit(EXIT_SUCCESS);
}
+ case REQ_MOVE:
+ {
+ int status;
+ read(from_parent, &status, sizeof(status));
+ if(!status)
+ out("Cannot go that way.\n");
+ }
case REQ_NOP:
break;
default:
@@ -170,7 +176,35 @@ static void client_change_user(const char *user)
static void client_change_room(room_id id)
{
- send_master(REQ_CHANGEROOM, &id, sizeof(id));
+ send_master(REQ_SETROOM, &id, sizeof(id));
+}
+
+static void client_move(const char *dir)
+{
+ struct {
+ const char *text;
+ enum direction_t val;
+ } dirs[] = {
+ { "N", DIR_N },
+ { "NE", DIR_NE },
+ { "E", DIR_E },
+ { "SE", DIR_SE },
+ { "S", DIR_S },
+ { "SW", DIR_SW },
+ { "W", DIR_W },
+ { "NW", DIR_NW },
+ { "UP", DIR_UP },
+ { "DOWN", DIR_DOWN }
+ };
+ for(unsigned i = 0; i < ARRAYLEN(dirs); ++i)
+ {
+ if(!strcmp(dir, dirs[i].text))
+ {
+ send_master(REQ_MOVE, &dirs[i].val, sizeof(dirs[i].val));
+ return;
+ }
+ }
+ out("Unknown direction.\n");
}
#define WSPACE " \t\r\n"
@@ -423,6 +457,12 @@ auth:
{
send_master(REQ_WAIT, NULL, 0);
}
+ else if(!strcmp(tok, "GO"))
+ {
+ char *dir = strtok_r(NULL, WSPACE, &save);
+ all_upper(dir);
+ client_move(dir);
+ }
next_cmd:
diff --git a/src/netcosm.h b/src/netcosm.h
index 8482e90..1712539 100644
--- a/src/netcosm.h
+++ b/src/netcosm.h
@@ -32,24 +32,27 @@
/* child<->master commands */
/* children might not implement all of these */
-#define REQ_NOP 0
-#define REQ_BCASTMSG 1
-#define REQ_LISTCLIENTS 2
-#define REQ_CHANGESTATE 3
-#define REQ_CHANGEUSER 4
-#define REQ_HANG 5
-#define REQ_KICK 6
-#define REQ_WAIT 7
-#define REQ_LOOK 8
-#define REQ_CHANGEROOM 9
+/* meanings might be different for the server and child, see comments */
+
+#define REQ_NOP 0 /* server, child: do nothing */
+#define REQ_BCASTMSG 1 /* server: broadcast text; child: print following text */
+#define REQ_LISTCLIENTS 2 /* server: list childs */
+#define REQ_CHANGESTATE 3 /* server: change child state flag */
+#define REQ_CHANGEUSER 4 /* server: change child login name */
+#define REQ_HANG 5 /* <UNIMP> server: loop forever */
+#define REQ_KICK 6 /* server: kick PID with message; child: print message, quit */
+#define REQ_WAIT 7 /* server: sleep 10s */
+#define REQ_LOOK 8 /* server: send child room description */
+#define REQ_SETROOM 9 /* server: set child room */
+#define REQ_MOVE 10 /* server: move child based on direction; child: success or failure */
/* child states */
-#define STATE_INIT 0
-#define STATE_AUTH 1
-#define STATE_CHECKING 2
-#define STATE_LOGGEDIN 3
-#define STATE_ADMIN 4
-#define STATE_FAILED 5
+#define STATE_INIT 0 /* initial state */
+#define STATE_AUTH 1 /* at login screen */
+#define STATE_CHECKING 2 /* checking password */
+#define STATE_LOGGEDIN 3 /* logged in as user */
+#define STATE_ADMIN 4 /* logged in w/ admin privs */
+#define STATE_FAILED 5 /* failed a password attempt */
/* for convenience when writing world specs */
#define NONE_N NULL
@@ -90,6 +93,8 @@ struct verb_t {
typedef int room_id;
+#define ROOM_NONE -1
+
/* the data we get from a world module */
struct roomdata_t {
const char *uniq_id;
diff --git a/src/server.c b/src/server.c
index f82502d..598dd8d 100644
--- a/src/server.c
+++ b/src/server.c
@@ -215,13 +215,33 @@ static void req_send_desc(unsigned char *data, size_t len, struct child_data *se
write(sender->outpipe[1], &newline, 1);
}
-static void req_change_room(unsigned char *data, size_t len, struct child_data *sender)
+static void req_set_room(unsigned char *data, size_t len, struct child_data *sender)
{
room_id id = *((room_id*)data);
sender->room = id;
}
+static void req_move_room(unsigned char *data, size_t len, struct child_data *sender)
+{
+ enum direction_t dir = *((enum direction_t*)data);
+ struct room_t *current = room_get(sender->room);
+
+ /* TODO: checking */
+ room_id new = current->adjacent[dir];
+ int status;
+ if(new != ROOM_NONE)
+ {
+ sender->room = new;
+ status = 1;
+ }
+ else
+ {
+ status = 0;
+ }
+ write(sender->outpipe[1], &status, sizeof(status));
+}
+
static const struct child_request {
unsigned char code;
@@ -247,7 +267,8 @@ static const struct child_request {
{ REQ_KICK, true, CHILD_ALL, req_kick_client, NULL, REQ_NOP },
{ REQ_WAIT, false, CHILD_NONE, NULL, req_wait, REQ_NOP },
{ REQ_LOOK, false, CHILD_NONE, NULL, req_send_desc, REQ_BCASTMSG },
- { REQ_CHANGEROOM, true, CHILD_NONE, NULL, req_change_room, REQ_NOP },
+ { REQ_SETROOM, true, CHILD_NONE, NULL, req_set_room, REQ_NOP },
+ { REQ_MOVE, true, CHILD_NONE, NULL, req_move_room, REQ_MOVE },
};
void sig_printf(const char *fmt, ...)