Example #1
0
nh_bool nhnet_exit_game(int exit_type)
{
    json_t *jmsg;
    int ret;

    if (!nhnet_active())
        return nh_exit_game(exit_type);

    xmalloc_cleanup();

    if (!api_entry())
        return 0;

    jmsg = json_pack("{si}", "exit_type", exit_type);
    jmsg = send_receive_msg("exit_game", jmsg);
    if (json_unpack(jmsg, "{si!}", "return", &ret) == -1) {
        print_error("Incorrect return object in nhnet_exit_game");
        ret = 0;
    }
    json_decref(jmsg);

    current_game = 0;

    api_exit();
    return ret;
}
Example #2
0
boolean nh_exit_game(int exit_type)
{
    boolean log_disabled = iflags.disable_log;
    
    if (!api_entry_checkpoint()) { /* not sure anything in here can actually call panic */
	iflags.disable_log = log_disabled;
	return TRUE; /* terminate was called, so exit is successful */
    }
    
    program_state.forced_exit = TRUE;
    
    /* clean up after viewing a game replay */
    if (program_state.viewing)
	nh_view_replay_finish();
	
    xmalloc_cleanup();
    iflags.disable_log = TRUE;
    if (program_state.game_running) {
	switch (exit_type) {
	    case EXIT_REQUEST_SAVE:
		dosave(); /* will ask "really save?" and, if 'y', eventually call terminate. */
		break;
		
	    case EXIT_FORCE_SAVE:
		dosave0(TRUE);
		terminate();
		break;
		
	    case EXIT_REQUEST_QUIT:
		done2();
		break;
		    
	    case EXIT_FORCE_QUIT:
		done(QUIT);
		break; /* not reached */
		
	    case EXIT_PANIC:
		/* freeing things should be safe */
		freedynamicdata();
		dlb_cleanup();
		panic("UI problem.");
		break;
	}
	
	iflags.disable_log = log_disabled;
	api_exit();
	return FALSE;
    }
    
    iflags.disable_log = log_disabled;
    /* calling terminate() will get us out of nested contexts safely, eg:
     * UI_cmdloop -> nh_command -> UI_update_screen (problem happens here) -> nh_exit_game
     * will jump all the way back to UI_cmdloop */
    terminate();
    
    api_exit(); /* not reached */
    return TRUE;
}
Example #3
0
void nh_lib_exit(void)
{
    int i;
    
    xmalloc_cleanup();
    
    for (i = 0; i < PREFIX_COUNT; i++) {
	free(fqn_prefix[i]);
	fqn_prefix[i] = NULL;
    }
    
    cleanup_opt_struct();
}
Example #4
0
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;
}
Example #5
0
void nhnet_lib_exit(void)
{
    if (nhnet_connected())
        nhnet_disconnect();

    xmalloc_cleanup();
    conn_err = FALSE;

#ifdef WIN32
    WSACleanup();
#else
    /* restore previous signale handler for SIGPIPE */
    sigaction(SIGPIPE, &oldaction, NULL);
#endif
}
Example #6
0
void nhnet_view_replay_finish(void)
{
    if (!nhnet_active())
        return nh_view_replay_finish();

    xmalloc_cleanup();

    alt_windowprocs = windowprocs;

    if (!api_entry())
        return;

    send_receive_msg("view_finish", json_object());

    api_exit();
}
Example #7
0
static void
vraw_printf(const char *line, va_list the_args)
{
    if (!strchr(line, '%'))
        raw_print(line);
    else {
        /* We can't use msgvprintf here because the game might not be
           running. We use xmvasprintf instead (vasprintf would be a little more
           appropriate but might not be available), then transfer to the stack,
           so that there are no untracked allocations when we make the API
           call. */
        struct xmalloc_block *xm_temp = NULL;
        const char *fmtline = xmvasprintf(&xm_temp, line, the_args);
        char fmtline_onstack[strlen(fmtline) + 1];
        strcpy(fmtline_onstack, fmtline);
        xmalloc_cleanup(&xm_temp);

        raw_print(fmtline_onstack);
    }
}
Example #8
0
void nhnet_disconnect(void)
{
    json_t *msg;
    if (sockfd != -1) {
	in_connect_disconnect = TRUE;
	msg = send_receive_msg("shutdown", json_object());
	in_connect_disconnect = FALSE;
	if (msg)
	    json_decref(msg);
	close(sockfd);
    }
    sockfd = -1;
    connection_id = 0;
    current_game = 0;
    conn_err = FALSE;
    net_active = FALSE;
    xmalloc_cleanup();
    free_option_lists();
    memset(&nhnet_server_ver, 0, sizeof(nhnet_server_ver));
}
Example #9
0
/* perform the command given by cmdidx (in index into cmdlist in cmd.c)
 * returns -1 if the command completes */
int command_input(int cmdidx, int rep, struct nh_cmd_arg *arg)
{
    boolean didmove = FALSE;
    
    if (multi >= 0 && occupation)
	handle_occupation();
    else if (multi == 0 || (multi > 0 && cmdidx != -1)) {
	saved_cmd = cmdidx;
	do_command(cmdidx, rep, TRUE, arg);
    } else if (multi > 0) {
	/* allow interruption of multi-turn commands */
	if (rep == -1) {
	    nomul(0, NULL);
	    return READY_FOR_INPUT;
	}
	
	if (flags.mv) {
	    if (multi < COLNO && !--multi)
		flags.travel = iflags.travel1 = flags.mv = flags.run = 0;
	    if (!domove(u.dx, u.dy, 0)) {
		/* Don't use a move when travelling into an obstacle. */
		flags.move = FALSE;
		nomul(0, NULL);
	    }
	} else
	    do_command(saved_cmd, multi, FALSE, arg);
    }
    /* no need to do anything here for multi < 0 */
    
    if (u.utotype)		/* change dungeon level */
	deferred_goto();	/* after rhack() */
    /* !flags.move here: multiple movement command stopped */
    else if (!flags.move || !flags.mv)
	iflags.botl = 1;

    if (vision_full_recalc)
	vision_recalc(0);	/* vision! */
    /* when running in non-tport mode, this gets done through domove() */
    if ((!flags.run || iflags.runmode == RUN_TPORT) &&
	    (multi && (!flags.travel ? !(multi % 7) : !(moves % 7L)))) {
	if (flags.run)
	    iflags.botl = 1;
	flush_screen();
    }
    
    didmove = flags.move;
    if (didmove) {
	you_moved();
    } /* actual time passed */

    /****************************************/
    /* once-per-player-input things go here */
    /****************************************/
    xmalloc_cleanup();
    iflags.next_msg_nonblocking = FALSE;

    /* prepare for the next move */
    flags.move = 1;
    pre_move_tasks(didmove);
    do_delay_msg();
    if (multi == 0 && !occupation) {
	flush_screen(); /* Flush screen buffer */
	maybe_tutorial();
    }
    
    return -1;
}