Example #1
0
/* start_game: Start a new game
 * parameters: name, role, race, gend, align, playmode
 */
static void
ccmd_start_game(json_t * params)
{
    char filename[1024], basename[1024], path[1024];
    json_t *j_msg;
    const char *name;
    int role, race, gend, align, mode, fd, ret;
    long t;

    if (json_unpack
        (params, "{ss,si,si,si,si,si*}", "name", &name, "role", &role, "race",
         &race, "gender", &gend, "alignment", &align, "mode", &mode) == -1)
        exit_client("Bad set of parameters for start_game");

    /* reset cached display data from a previous game */
    reset_cached_diplaydata();

    if (mode == MODE_WIZARD && !user_info.can_debug)
        mode = MODE_EXPLORE;

    t = (long)time(NULL);
    snprintf(path, 1024, "%s/save/%s/", settings.workdir, user_info.username);
    snprintf(basename, 1024, "%ld_%s.nhgame", t, name);
    snprintf(filename, 1024, "%s%s", path, basename);

    mkdir(path, 0755);  /* should already exist unless something went wrong
                           while upgrading */
    fd = open(filename, O_EXCL | O_CREAT | O_RDWR, 0600);
    if (fd == -1)
        exit_client("Could not create the logfile");

    ret = nh_start_game(fd, name, role, race, gend, align, mode);
    if (ret) {
        struct nh_roles_info *ri = nh_get_roles();
        const char *rolename = (gend &&
                                ri->rolenames_f[role]) ? ri->
            rolenames_f[role] : ri->rolenames_m[role];
        gamefd = fd;
        gameid =
            db_add_new_game(user_info.uid, basename, rolename,
                            ri->racenames[race], ri->gendnames[gend],
                            ri->alignnames[align], mode, name,
                            player_info.level_desc);
        log_msg("%s has started a new game (%d) as %s", user_info.username,
                gameid, name);
        j_msg = json_pack("{si,si}", "return", ret, "gameid", gameid);
    } else {
        close(fd);
        unlink(filename);
        j_msg = json_pack("{si,si}", "return", ret, "gameid", -1);
    }

    client_msg("start_game", j_msg);
}
Example #2
0
struct nh_roles_info *nhnet_get_roles(void)
{
    struct nh_roles_info *ri = NULL;
    json_t *jmsg, *jroles_m, *jroles_f, *jraces, *jgenders, *jaligns, *jmatrix;
    nh_bool *matrix;
    int i, size;

    if (!nhnet_active())
        return nh_get_roles();

    if (!api_entry())
        return NULL;

    jmsg = send_receive_msg("get_roles", json_object());
    ri = xmalloc(sizeof(struct nh_roles_info));
    if (json_unpack(jmsg, "{si,si,si,si,si,si,si,si,so,so,so,so,so,so}",
                    "num_roles", &ri->num_roles, "num_races", &ri->num_races,
                    "num_genders", &ri->num_genders, "num_aligns", &ri->num_aligns,
                    "def_role", &ri->def_role, "def_race", &ri->def_race,
                    "def_gend", &ri->def_gend, "def_align", &ri->def_align,
                    "rolenames_m", &jroles_m, "rolenames_f", &jroles_f,
                    "racenames", &jraces, "gendnames", &jgenders,
                    "alignnames", &jaligns, "matrix", &jmatrix) == -1 ||
            !json_is_array(jroles_m) || !json_is_array(jroles_f) ||
            !json_is_array(jraces)   || !json_is_array(jgenders) ||
            !json_is_array(jaligns)  || !json_is_array(jmatrix)  ||
            json_array_size(jroles_m) != ri->num_roles ||
            json_array_size(jroles_f) != ri->num_roles ||
            json_array_size(jraces)   != ri->num_races ||
            json_array_size(jgenders) != ri->num_genders ||
            json_array_size(jaligns)  != ri->num_aligns) {
        print_error("Incorrect return object in nhnet_get_roles");
        ri = NULL;
    } else {
        ri->rolenames_m = read_string_array(jroles_m);
        ri->rolenames_f = read_string_array(jroles_f);
        ri->racenames = read_string_array(jraces);
        ri->gendnames = read_string_array(jgenders);
        ri->alignnames = read_string_array(jaligns);

        size = json_array_size(jmatrix);
        matrix = xmalloc(size * sizeof(nh_bool));
        for (i = 0; i < size; i++)
            matrix[i] = json_integer_value(json_array_get(jmatrix, i));
        ri->matrix = matrix;
    }

    json_decref(jmsg);
    api_exit();
    return ri;
}
Example #3
0
static void
ccmd_get_roles(json_t * params)
{
    int i, len;
    struct nh_roles_info *ri;
    json_t *jmsg, *jarr, *j_tmp;
    void *iter;

    iter = json_object_iter(params);
    if (iter)
        exit_client("non-empty parameter list for get_roles");

    ri = nh_get_roles();
    jmsg =
        json_pack("{si,si,si,si,si,si,si,si}", "num_roles", ri->num_roles,
                  "num_races", ri->num_races, "num_genders", ri->num_genders,
                  "num_aligns", ri->num_aligns, "def_role", ri->def_role,
                  "def_race", ri->def_race, "def_gend", ri->def_gend,
                  "def_align", ri->def_align);

    /* rolenames_m */
    jarr = json_array();
    for (i = 0; i < ri->num_roles; i++) {
        j_tmp =
            ri->rolenames_m[i] ? json_string(ri->rolenames_m[i]) : json_null();
        json_array_append_new(jarr, j_tmp);
    }
    json_object_set_new(jmsg, "rolenames_m", jarr);

    /* rolenames_f */
    jarr = json_array();
    for (i = 0; i < ri->num_roles; i++) {
        j_tmp =
            ri->rolenames_f[i] ? json_string(ri->rolenames_f[i]) : json_null();
        json_array_append_new(jarr, j_tmp);
    }
    json_object_set_new(jmsg, "rolenames_f", jarr);

    /* racenames */
    jarr = json_array();
    for (i = 0; i < ri->num_races; i++) {
        j_tmp = ri->racenames[i] ? json_string(ri->racenames[i]) : json_null();
        json_array_append_new(jarr, j_tmp);
    }
    json_object_set_new(jmsg, "racenames", jarr);

    /* gendnames */
    jarr = json_array();
    for (i = 0; i < ri->num_genders; i++) {
        j_tmp = ri->gendnames[i] ? json_string(ri->gendnames[i]) : json_null();
        json_array_append_new(jarr, j_tmp);
    }
    json_object_set_new(jmsg, "gendnames", jarr);

    /* alignnames */
    jarr = json_array();
    for (i = 0; i < ri->num_aligns; i++) {
        j_tmp =
            ri->alignnames[i] ? json_string(ri->alignnames[i]) : json_null();
        json_array_append_new(jarr, j_tmp);
    }
    json_object_set_new(jmsg, "alignnames", jarr);

    /* matrix */
    len = ri->num_roles * ri->num_races * ri->num_genders * ri->num_aligns;
    jarr = json_array();
    for (i = 0; i < len; i++) {
        json_array_append_new(jarr, json_integer(ri->matrix[i]));
    }
    json_object_set_new(jmsg, "matrix", jarr);

    client_msg("get_roles", jmsg);
}
Example #4
0
static void
process_args(int argc, char *argv[])
{
    int i;
    const struct nh_roles_info *ri = nh_get_roles();

    /*
     * Process options.
     */
    while (argc > 1 && argv[1][0] == '-') {
        argv++;
        argc--;
        switch (argv[0][1]) {
        case '-':
            if (!strcmp(argv[0], "--help")) {
                puts("Usage: nethack4 [--interface PLUGIN] [OPTIONS]");
                puts("");
                puts("-k          connection-only mode");
                puts("-D          start games in wizard mode");
                puts("-X          start games in explore mode");
                puts("-u name     specify player name");
                puts("-p role     specify role");
                puts("-r race     specify race");
                puts("-@          specify a random character");
                puts("-H dir      override the playfield location");
                puts("-U dir      override the user directory");
                puts("-Z          disable suspending the process");
                puts("");
                puts("PLUGIN can be any libuncursed plugin that is installed");
                puts("on your system; examples may include 'tty' and 'sdl'.");
                exit(0);
            } else if (!strcmp(argv[0], "--version")) {
                printf("NetHack 4 version %d.%d.%d\n",
                       VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL);
                exit(0);
            }
            break;

        case 'k':
            ui_flags.connection_only = 1;
            break;

        case 'D':
            ui_flags.playmode = MODE_WIZARD;
            break;

        case 'X':
            ui_flags.playmode = MODE_EXPLORE;
            break;

        case 'u':
            if (argv[0][2])
                strncpy(cmdline_name, argv[0] + 2,
                        sizeof (cmdline_name) - 1);
            else if (argc > 1) {
                argc--;
                argv++;
                strncpy(cmdline_name, argv[0], sizeof (cmdline_name) - 1);
            } else
                printf("Player name expected after -u");
            break;

        case 'p':      /* profession (role) */
            if (argv[0][2]) {
                i = str2role(ri, &argv[0][2]);
                if (i >= 0)
                    cmdline_role = i;
            } else if (argc > 1) {
                argc--;
                argv++;
                i = str2role(ri, argv[0]);
                if (i >= 0)
                    cmdline_role = i;
            }
            break;

        case 'r':      /* race */
            if (argv[0][2]) {
                i = str2race(ri, &argv[0][2]);
                if (i >= 0)
                    cmdline_race = i;
            } else if (argc > 1) {
                argc--;
                argv++;
                i = str2race(ri, argv[0]);
                if (i >= 0)
                    cmdline_race = i;
            }
            break;

        case '@':
            random_player = TRUE;
            break;

        case 'H':
#ifdef UNIX
            if (setregid(getgid(), getgid()) < 0)
                exit(14);
#endif
            if (argv[0][2]) {
                override_hackdir = argv[0] + 2;
            } else if (argc > 1) {
                argc--;
                argv++;
                override_hackdir = argv[0];
            }
            break;

        case 'U':
#ifdef UNIX
            if (setregid(getgid(), getgid()) < 0)
                exit(14);
#endif
            if (argv[0][2]) {
                override_userdir = argv[0] + 2;
            } else if (argc > 1) {
                argc--;
                argv++;
                override_userdir = argv[0];
            }
            break;

        case 'Z':
            ui_flags.no_stop = 1;
            break;

        default:
            i = str2role(ri, argv[0]);
            if (i >= 0)
                cmdline_role = i;
        }
    }
}
Example #5
0
nh_bool player_selection(int *out_role, int *out_race, int *out_gend,
			 int *out_align, int randomall, nh_bool tutorial)
{
    struct nh_menuitem *items;
    int icount, size;
    int i, k, n, listlen, id;
    char pick4u = 'n', thisch, lastch = 0;
    char pbuf[QBUFSZ], plbuf[QBUFSZ];
    struct nh_listitem list[LISTSZ]; /* need enough space for lists of roles or races */
    char listbuffers[LISTSZ][256];
    int pick_list[2];
    int initrole, initrace, initgend, initalign;
    const struct nh_roles_info *ri = nh_get_roles();
    
    if (tutorial)
	return tutorial_player_selection(out_role, out_race, out_gend, out_align);
    
    initrole = *out_role; initrace = *out_race;
    initalign = *out_align; initgend = *out_gend;
    if (initrole == ROLE_NONE) initrole = ri->def_role;
    if (initrace == ROLE_NONE) initrace = ri->def_race;
    if (initgend == ROLE_NONE) initgend = ri->def_gend;
    if (initalign == ROLE_NONE) initalign = ri->def_align;
    
    validate_character_presets(ri, &initrole, &initrace, &initgend, &initalign);
    
    for (i = 0; i < LISTSZ; i++) {
	listbuffers[i][0] = '\0';
	list[i].caption = listbuffers[i];
    }
    
    srandom(time(NULL));
    
    /* Should we randomly pick for the player? */
    if (!randomall &&
	(initrole == ROLE_NONE || initrace == ROLE_NONE ||
	    initgend == ROLE_NONE || initalign == ROLE_NONE)) {
	char *prompt = nh_build_plselection_prompt(pbuf, QBUFSZ, initrole,
			    initrace, initgend, initalign);

	pick4u = curses_yn_function(prompt, "ynq", 'y');	
	if (pick4u != 'y' && pick4u != 'n')
	    return FALSE;
    }

    nh_root_plselection_prompt(plbuf, QBUFSZ - 1,
		    initrole, initrace, initgend, initalign);
    icount = 0; size = 10;
    items = malloc(sizeof(struct nh_menuitem) * size);

    /* Select a role, if necessary */
    /* if pre-selected race/gender/alignment are still set after
     * validate_character_presets we know they're OK */
    if (initrole < 0) {
	listlen = get_valid_roles(ri, initrace, initgend, initalign, list, LISTSZ);
	
	/* Process the choice */
	if (pick4u == 'y' || initrole == ROLE_RANDOM || randomall) {
	    /* Pick a random role */
	    initrole = list[random() % listlen].id;
	} else {
	    /* Prompt for a role */
	    for (i = 0; i < listlen; i++) {
		id = list[i].id + 1; /* list[i].id starts at 0 */
		thisch = tolower((unsigned char)*list[i].caption);
		if (thisch == lastch)
		    thisch = toupper((unsigned char)thisch);
		add_menu_item(items, size, icount, id, list[i].caption + 2, thisch, 0);
		lastch = thisch;
	    }
	    pick_list[0] = id = list[random() % listlen].id+1;
	    add_menu_item(items, size, icount, id, "随机", '*', 0);
	    add_menu_item(items, size, icount, -1, "退出", 'q', 0);
	    
	    sprintf(pbuf, "为你的%s选择一个角色", plbuf);
	    n = curses_display_menu(items, icount, pbuf, PICK_ONE, pick_list);

	    /* Process the choice */
	    if (n == -1 || pick_list[0] == -1)
		goto give_up;		/* Selected quit */

	    initrole = pick_list[0] - 1;
	    icount = 0;
	}
	nh_root_plselection_prompt(plbuf, QBUFSZ - 1,
		    initrole, initrace, initgend, initalign);
    }
    
    /* Select a race, if necessary */
    if (initrace < 0) {
	listlen = get_valid_races(ri, initrole, initgend, initalign, list, LISTSZ);
	
	if (pick4u == 'y' || initrace == ROLE_RANDOM || randomall) {
	    initrace = list[random() % listlen].id;
	} else {	/* pick4u == 'n' */
	    /* Count the number of valid races */
	    k = list[0].id;	/* valid race */

	    /* Permit the user to pick, if there is more than one */
	    if (listlen > 1) {
		for (i = 0; i < listlen; i++) {
		    id = list[i].id + 1;
		    add_menu_item(items, size, icount, id, list[i].caption + 2,
				  list[i].caption[0], 0);
		}
		pick_list[0] = id = list[random() % listlen].id+1;
		add_menu_item(items, size, icount, id, "随机", '*', 0);
		add_menu_item(items, size, icount, -1, "退出", 'q', 0);

		sprintf(pbuf, "为你的%s选择一个种族", plbuf);
		n = curses_display_menu(items, icount, pbuf, PICK_ONE, pick_list);
		
		if (n == -1 || pick_list[0] == -1)
		    goto give_up;		/* Selected quit */

		k = pick_list[0] - 1;
		icount = 0;
	    }
	    initrace = k;
	}
	nh_root_plselection_prompt(plbuf, QBUFSZ - 1,
		    initrole, initrace, initgend, initalign);
    }

    /* Select a gender, if necessary */
    if (initgend < 0) {
	listlen = get_valid_genders(ri, initrole, initrace, initalign, list, LISTSZ);

	if (pick4u == 'y' || initgend == ROLE_RANDOM || randomall) {
	    initgend = list[random() % listlen].id;
	} else {	/* pick4u == 'n' */
	    /* Count the number of valid genders */
	    k = list[0].id;	/* valid gender */

	    /* Permit the user to pick, if there is more than one */
	    if (listlen > 1) {
		for (i = 0; i < listlen; i++) {
		    id = list[i].id + 1;
		    add_menu_item(items, size, icount, id, list[i].caption + 2,
				  list[i].caption[0], 0);
		}
		pick_list[0] = id = list[random() % listlen].id+1;
		add_menu_item(items, size, icount, id, "随机", '*', 0);
		add_menu_item(items, size, icount, -1, "退出", 'q', 0);

		sprintf(pbuf, "为你的%s选择一个性别", plbuf);
		n = curses_display_menu(items, icount, pbuf, PICK_ONE, pick_list);
		
		if (n == -1 || pick_list[0] == -1)
		    goto give_up;		/* Selected quit */

		k = pick_list[0] - 1;
		icount = 0;
	    }
	    initgend = k;
	}
	nh_root_plselection_prompt(plbuf, QBUFSZ - 1,
		    initrole, initrace, initgend, initalign);
    }

    /* Select an alignment, if necessary */
    if (initalign < 0) {
	listlen = get_valid_aligns(ri, initrole, initrace, initgend, list, LISTSZ);
	
	if (pick4u == 'y' || initalign == ROLE_RANDOM || randomall) {
	    initalign = list[random() % listlen].id;
	} else {	/* pick4u == 'n' */
	    /* Count the number of valid alignments */
	    k = list[0].id;	/* valid alignment */

	    /* Permit the user to pick, if there is more than one */
	    if (listlen > 1) {
		for (i = 0; i < listlen; i++) {
		    id = list[i].id + 1;
		    add_menu_item(items, size, icount, id, list[i].caption + 2,
				  list[i].caption[0], 0);
		}
		pick_list[0] = id = list[random() % listlen].id+1;
		add_menu_item(items, size, icount, id, "随机", '*', 0);
		add_menu_item(items, size, icount, -1, "退出", 'q', 0);
		
		sprintf(pbuf, "为你的%s选择一个阵营", plbuf);
		n = curses_display_menu(items, icount, pbuf, PICK_ONE, pick_list);
		
		if (n == -1 || pick_list[0] == -1)
		    goto give_up;		/* Selected quit */

		k = pick_list[0] - 1;
	    }
	    initalign = k;
	}
    }
    
    *out_role = initrole;
    *out_race = initrace;
    *out_gend = initgend;
    *out_align = initalign;
    
    free(items);
    return TRUE;
    
give_up:
    free(items);
    return FALSE;
}
Example #6
0
static nh_bool tutorial_player_selection(int *out_role, int *out_race,
					 int *out_gend, int *out_align)
{
    const struct nh_roles_info *ri;
    struct nh_menuitem items[4];	/* 3 options + quit */
    int pick_list[2];
    int result;

    ri = nh_get_roles();
    if (!ri)
	return FALSE;

    set_menuitem(&items[0], 1, MI_NORMAL,
		 "lawful female dwarf Valkyrie (uses melee and thrown weapons)",
		 'v', 0);
    set_menuitem(&items[1], 2, MI_NORMAL,
		 "chaotic male elf Wizard      (relies mostly on spells)",
		 'w', 0);
    set_menuitem(&items[2], 3, MI_NORMAL,
		 "neutral female human Ranger  (good with ranged combat)",
		 'R', 0);
    set_menuitem(&items[3], 4, MI_NORMAL,
		 "quit",
		 'q', 0);

    result = curses_display_menu(items, 4, "Choose a character", PICK_ONE, pick_list);
    if (result == -1 || pick_list[0] == -1)
	return FALSE;

    switch (pick_list[0]) {
    case 1:
	if (!find_role(ri, "Valkyrie", out_role) ||
	    !find_race(ri, "dwarf", out_race) ||
	    !find_gend(ri, "female", out_gend) ||
	    !find_align(ri, "lawful", out_align))
	    return FALSE;
	break;
    case 2:
	if (!find_role(ri, "Wizard", out_role) ||
	    !find_race(ri, "elf", out_race) ||
	    !find_gend(ri, "male", out_gend) ||
	    !find_align(ri, "chaotic", out_align))
	    return FALSE;
	break;
    case 3:
	if (!find_role(ri, "Ranger", out_role) ||
	    !find_race(ri, "human", out_race) ||
	    !find_gend(ri, "female", out_gend) ||
	    !find_align(ri, "neutral", out_align))
	    return FALSE;
	break;
    case 4:
    default:
	return FALSE;
	break;
    }

    if (!is_valid_character(ri, *out_role, *out_race, *out_gend, *out_align))
	return FALSE;

    return TRUE;
}