Example #1
0
nh_bool nhnet_view_replay_start(int fd, struct nh_window_procs *rwinprocs,
                                struct nh_replay_info *info)
{
    int ret;
    json_t *jmsg;
    const char *nextcmd;

    if (!nhnet_active())
        return nh_view_replay_start(fd, rwinprocs, info);

    if (!api_entry())
        return FALSE;

    alt_windowprocs = *rwinprocs;

    jmsg = send_receive_msg("view_start", json_pack("{si}", "gameid", fd));
    if (json_unpack(jmsg, "{si,s:{ss,si,si,si,si}}", "return", &ret, "info",
                    "nextcmd", &nextcmd, "actions", &info->actions, "max_actions",
                    &info->max_actions, "moves", &info->moves, "max_moves",
                    &info->max_moves) == -1) {
        print_error("Incorrect return object in nhnet_view_replay_step");
        ret = 0;
    } else
        strncpy(info->nextcmd, nextcmd, sizeof(info->nextcmd) - 1);

    api_exit();
    return ret;
}
Example #2
0
static void
ccmd_view_start(json_t * params)
{
    int ret, gid, fd;
    struct nh_replay_info info;
    char basename[1024], filename[1024];
    json_t *jmsg;

    if (json_unpack(params, "{si*}", "gameid", &gid) == -1)
        exit_client("Bad set of parameters for view_start");

    if (!db_get_game_filename(0, gid, basename, 1024)) {
        log_msg("Client requested nonexistent game %d for viewing", gid);
        jmsg = json_pack("{si}", "return", FALSE);
        client_msg("view_start", jmsg);
        return;
    }

    snprintf(filename, 1024, "%s/save/%s/%s", settings.workdir,
             user_info.username, basename);
    fd = open(filename, O_RDWR);
    if (fd == -1) {
        snprintf(filename, 1024, "%s/completed/%s", settings.workdir, basename);
        fd = open(filename, O_RDWR);
    }
    if (fd == -1) {
        log_msg("failed to open game %d (file %s) for viewing", gid, basename);
        jmsg = json_pack("{si}", "return", FALSE);
        client_msg("view_start", jmsg);
        return;
    }

    ret = nh_view_replay_start(fd, &server_alt_windowprocs, &info);

    jmsg =
        json_pack("{si,s:{ss,si,si,si,si}}", "return", ret, "info", "nextcmd",
                  info.nextcmd, "actions", info.actions, "max_actions",
                  info.max_actions, "moves", info.moves, "max_moves",
                  info.max_moves);
    client_msg("view_start", jmsg);
}
Example #3
0
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();
}
Example #4
0
static void
timetest(int fd, struct nh_replay_info *rinfo)
{
    char buf[BUFSZ];
    hp_time t_start, t_end;
    long ms;
    int mmax, initial, revpos;

    initial = rinfo->moves;
    nh_view_replay_step(rinfo, REPLAY_GOTO, 0);

    /* run forward */
    gettime(&t_start);
    while (rinfo->actions < rinfo->max_actions) {
        nh_view_replay_step(rinfo, REPLAY_FORWARD, 1);
        curses_update_status(NULL);
        draw_replay_info(rinfo);
        doupdate();
    }
    draw_msgwin();
    gettime(&t_end);
    ms = clock_delta_ms(&t_start, &t_end);
    snprintf(buf, BUFSZ,
             "%d actions replayed with display in %ld ms. (%ld actions/sec)",
             rinfo->max_actions, ms, rinfo->max_actions * 1000 / ms);
    curses_msgwin(buf);

    /* reset the entire replay state to delete checkpoints */
    mmax = rinfo->moves;        /* max_moves may not be available if this is a
                                   replay of a crashed game */
    nh_view_replay_finish();
    nh_view_replay_start(fd, &curses_replay_windowprocs, rinfo);

    /* run forward without showing the map etc. */
    gettime(&t_start);
    nh_view_replay_step(rinfo, REPLAY_GOTO, mmax);
    gettime(&t_end);
    ms = clock_delta_ms(&t_start, &t_end);
    snprintf(buf, BUFSZ,
             "%d actions replayed without display in %ld ms. (%ld actions/sec)",
             rinfo->actions, ms, rinfo->actions * 1000 / ms);
    curses_msgwin(buf);

    /* run backward */
    revpos = rinfo->actions;
    gettime(&t_start);
    while (rinfo->actions > 0 && revpos < rinfo->actions + 1000) {
        nh_view_replay_step(rinfo, REPLAY_BACKWARD, 1);
        curses_update_status(NULL);
        draw_msgwin();
        draw_replay_info(rinfo);
        doupdate();
    }
    gettime(&t_end);
    ms = clock_delta_ms(&t_start, &t_end);
    snprintf(buf, BUFSZ,
             "%d actions replayed backward with display in %ld ms. (%ld actions/sec)",
             revpos - rinfo->actions, ms,
             (revpos - rinfo->actions) * 1000 / ms);
    curses_msgwin(buf);

    nh_view_replay_step(rinfo, REPLAY_GOTO, initial);
}