int commandloop(void) { const char *cmd; int gamestate, count; struct nh_cmd_arg cmdarg; gamestate = READY_FOR_INPUT; game_is_running = TRUE; while (gamestate < GAME_OVER) { count = 0; cmd = NULL; if (gamestate == READY_FOR_INPUT) cmd = get_command(&count, &cmdarg); else if (gamestate == MULTI_IN_PROGRESS && interrupt_multi) count = -1; interrupt_multi = FALSE; /* could have been set while no multi was in progress */ gamestate = nh_command(cmd, count, &cmdarg); } game_is_running = FALSE; return gamestate; }
int nhnet_command(const char *cmd, int rep, struct nh_cmd_arg *arg) { int ret; json_t *jmsg, *jarg; if (!nhnet_active()) return nh_command(cmd, rep, arg); if (!api_entry()) return ERR_NETWORK_ERROR; xmalloc_cleanup(); switch (arg->argtype) { case CMD_ARG_DIR: jarg = json_pack("{si,si}", "argtype", arg->argtype, "d", arg->d); break; case CMD_ARG_POS: jarg = json_pack("{si,si,si}", "argtype", arg->argtype, "x", arg->pos.x, "y", arg->pos.y); break; case CMD_ARG_OBJ: jarg = json_pack("{si,si}", "argtype", arg->argtype, "invlet", arg->invlet); break; case CMD_ARG_NONE: default: jarg = json_pack("{si}", "argtype", arg->argtype); break; } jmsg = json_pack("{ss,so,si}", "command", cmd ? cmd : "", "arg", jarg, "count", rep); jmsg = send_receive_msg("game_command", jmsg); if (json_unpack(jmsg, "{si!}", "return", &ret) == -1) { print_error("Incorrect return object in nhnet_command"); ret = 0; } json_decref(jmsg); api_exit(); return ret; }
void replay_commandloop(int fd) { int key, move, count; char buf[BUFSZ], qbuf[BUFSZ]; nh_bool ret, firsttime = TRUE; struct nh_replay_info rinfo; struct nh_cmd_arg noarg; struct nh_cmd_desc *cmd; create_game_windows(); if (!nh_view_replay_start(fd, &curses_replay_windowprocs, &rinfo)) return; load_keymap(); while (1) { draw_msgwin(); curses_update_status(NULL); draw_sidebar(); draw_replay_info(&rinfo); if (firsttime) show_replay_help(); firsttime = FALSE; key = get_map_key(TRUE); switch (key) { /* step forward */ case KEY_RIGHT: case ' ': ret = nh_view_replay_step(&rinfo, REPLAY_FORWARD, 1); draw_replay_info(&rinfo); if (ret == FALSE) { key = curses_msgwin("You have reached the end of this game. " "Go back or press ESC to exit."); if (key == KEY_ESC) goto out; } break; /* step backward */ case KEY_LEFT: nh_view_replay_step(&rinfo, REPLAY_BACKWARD, 1); draw_replay_info(&rinfo); break; case KEY_ESC: goto out; case 'g': strncpy(qbuf, "What move do you want to jump to?", BUFSZ); if (rinfo.max_moves > 0) sprintf(qbuf + strlen(qbuf), " (Max: %d)", rinfo.max_moves); curses_getline(qbuf, buf); if (buf[0] == '\033' || !(move = atoi(buf))) break; nh_view_replay_step(&rinfo, REPLAY_GOTO, move); break; case KEY_F(12): /* timetest! */ if (allow_timetest()) timetest(fd, &rinfo); break; default: count = 0; noarg.argtype = CMD_ARG_NONE; cmd = keymap[key]; if (!cmd) break; if (cmd->flags & CMD_UI) handle_internal_cmd(&cmd, &noarg, &count); if (cmd) nh_command(cmd->name, count, &noarg); break; } } out: nh_view_replay_finish(); free_keymap(); destroy_game_windows(); cleanup_messages(); }
static void ccmd_game_command(json_t * params) { json_t *jarg; int count, result, gid; const char *cmd; struct nh_cmd_arg arg; if (json_unpack (params, "{ss,so,si*}", "command", &cmd, "arg", &jarg, "count", &count) == -1) exit_client("Bad set of parameters for game_command"); if (json_unpack(jarg, "{si*}", "argtype", &arg.argtype) == -1) exit_client("Bad parameter arg in game_command"); switch (arg.argtype) { case CMD_ARG_DIR: if (json_unpack(jarg, "{si*}", "d", &arg.d) == -1) exit_client("Bad direction arg in game_command"); break; case CMD_ARG_POS: if (json_unpack(jarg, "{si,si*}", "x", &arg.pos.x, "y", &arg.pos.y) == -1) exit_client("Bad position arg in game_command"); break; case CMD_ARG_OBJ: if (json_unpack(jarg, "{si*}", "invlet", &arg.invlet) == -1) exit_client("Bad invlet arg in game_command"); break; case CMD_ARG_NONE: default: break; } if (cmd[0] == '\0') cmd = NULL; result = nh_command(cmd, count, &arg); gid = gameid; if (result >= GAME_OVER) { close(gamefd); log_msg("Game %d (by %s) closed: game %s.", gameid, user_info.username, result == GAME_SAVED ? "saved" : "ended"); gamefd = -1; gameid = 0; } client_msg("game_command", json_pack("{si}", "return", result)); db_update_game(gameid, player_info.moves, player_info.z, player_info.level_desc); /* move the finished game to its final resting place */ if (result == GAME_OVER) { char basename[1024], filename[1024], final_name[1024]; int len; char buf[BUFSZ]; /* get the topten entry for the current game */ struct nh_topten_entry *tte = nh_get_topten(&len, buf, NULL, 0, 0, 0); if (!db_get_game_filename(user_info.uid, gid, basename, 1024)) return; snprintf(filename, 1024, "%s/save/%s/%s", settings.workdir, user_info.username, basename); snprintf(final_name, 1024, "%s/completed/%s", settings.workdir, basename); rename(filename, final_name); db_add_topten_entry(gid, tte->points, tte->hp, tte->maxhp, tte->deaths, tte->end_how, tte->death, tte->entrytxt); } }