static void
resize_curses_msgwin(struct gamewin *gw)
{
    int linecount;
    char **lines;
    struct win_msgwin *wmw = (struct win_msgwin *)gw->extra;

    layout_curses_msgwin(wmw, &linecount, &lines, 1);
    free_wrap(lines);

    gw->win = newdialog(wmw->layout_height, wmw->layout_width,
                        wmw->context == krc_notification ? 2 : 1, NULL);
}
static void
draw_curses_msgwin(struct gamewin *gw)
{
    int i;

    int linecount;
    char **lines;
    struct win_msgwin *wmw = (struct win_msgwin *)gw->extra;

    layout_curses_msgwin(wmw, &linecount, &lines, 0);

    for (i = 0; i < linecount; i++)
        mvwaddstr(gw->win, 1 + i, 2, lines[i]);
    wnoutrefresh(gw->win);

    free_wrap(lines);
}
Beispiel #3
0
int
network_motd(void)
{
    char errmsg[256];
    char motdmsg[4096];
    int fd = -1;

    if (settings.show_motd == MOTD_TRUE) {

        fd = connect_server(MOTD_SERVER, MOTD_PORT, FALSE,
                            errmsg, sizeof errmsg);
        if (fd == -1)
            fd = connect_server(MOTD_SERVER, MOTD_PORT, TRUE,
                                errmsg, sizeof errmsg);
        
        errmsg[sizeof errmsg - 1] = '\0';

        if (fd == -1) {
            strcpy(motdmsg, "Could not connect to <" MOTD_SERVER "> to "
                   "receive a Message of the Day: ");
            strcat(motdmsg, errmsg);
        } else {
            /* We want to receive until the connection closes (which causes
               either EPIPE on abnormal shutdown, or 0 on normal shutdown). So
               continue until we get an error message other than EINTR or the
               buffer fills (indicating a malicious connection; I'm not planning
               on sending malicious packets from motd.nethack4.org, especially
               as I wrote this code and so know it wouldn't work, but it's worth
               allowing for the possibility that someone else intercepts the
               connection). */
            int recvlen = 0;
            int rv;
            while (recvlen < sizeof motdmsg &&
                   (((rv = recv(fd, motdmsg + recvlen,
                                (sizeof motdmsg) - recvlen, 0))) > 0 ||
                    errno == EINTR))
                recvlen += rv < 0 ? 0 : rv;
            if (recvlen >= sizeof motdmsg)
                recvlen = -1 + sizeof motdmsg;

            motdmsg[recvlen] = '\0';
        }

        close(fd);
    } else if (settings.show_motd == MOTD_FALSE) {
        return 1;
    } else {
        /* It's a bad idea to do network connections without asking the user for
           permission first. (Arguably we could make an exception for
           connection-only mode, but that connects to localhost, which is not
           quite the same thing as connecting to the Internet, so I'd rather
           make absolutely sure we aren't doing connections unsolicited.)

           Note that nothing is sent (other than the fact that the connection
           exists); the nethack4 binary just creates the connection, then reads
           from it. */
        strcpy(motdmsg, "The Message of the Day system connects to the "
               "Internet to receive gameplay tips and announcements (such "
               "as tournament information or release announcements). Do you "
               "want to turn it on? (You can change this later with the "
               "\x0enetwork_motd\x0f option.)");
    }

    /* SI/SO in the output indicate bold text. This isn't implemented yet.  Also
       strip out all other unprintable characters for security reasons. We just
       use the ASCII space-to-tilde range for printables; we're not expecting
       any control characters but SI/SO, not even newlines. */
    char *f, *t;
    f = t = motdmsg;
    while (*f) {
        if (*f >= ' ' && *f <= '~')
            *(t++) = *f;
        f++;
    }
    *t = '\0';

    int outcount;
    char **outlines;
    wrap_text(COLNO-6, motdmsg, &outcount, &outlines);

    struct nh_menulist menu;
    int i;

    init_menulist(&menu);

    for (i = 0; i < outcount; i++)
        add_menu_txt(&menu, outlines[i], MI_TEXT);

    free_wrap(outlines);

    if (settings.show_motd == MOTD_ASK) {
        add_menu_txt(&menu, "", MI_TEXT);
        add_menu_item(&menu, 1,
                      "Yes, I'd like announcements and gameplay tips",
                      'y', FALSE);
        add_menu_item(&menu, 2,
                      "No, please don't connect to the MotD server",
                      'n', FALSE);

        curses_display_menu(&menu, "Message of the Day", PICK_ONE,
                            PLHINT_ANYWHERE, &i, curses_menu_callback);

        if (i == 1) {
            curses_set_option("networkmotd",
                              (union nh_optvalue){.e = MOTD_TRUE});
Beispiel #4
0
static void
curses_print_message_core(int turn, const char *msg, nh_bool canblock)
{
    int hsize, vsize, maxlen;
    nh_bool died;

    if (!msghistory)
        alloc_hist_array();

    if (turn != prevturn)
        start_of_turn_curline = last_redraw_curline = curline;

    if (turn < prevturn)        /* going back in time can happen during replay */
        prune_messages(turn);

    if (!*msg)
        return; /* empty message. done. */

    if (action > prevaction) {
        /* re-enable output if it was stopped and start a new line */
        stopprint = FALSE;
        newline();
    }
    prevturn = turn;
    prevaction = action;

    store_message(turn, msg);

    if (stopprint)
        return;

    /* 
     * generally we want to put as many messages on one line as possible to
     * maximize space usage. A new line is begun after each player turn or if
     * more() is called via pause_messages(). "You die" also deserves its own line.
     * 
     * If the message area is only one line high, space for "--More--" must be
     * reserved at the end of the line, otherwise  --More-- is shown on a new line.
     */

    getmaxyx(msgwin, vsize, hsize);

    maxlen = hsize;
    if (maxlen >= COLNO)
        maxlen = COLNO - 1;
    if (vsize == 1)
        maxlen -= 8;    /* for "--More--" */

    died = !strncmp(msg, "You die", 7);
    if (strlen(msglines[curline]) + strlen(msg) + 1 < maxlen && !died) {
        if (msglines[curline][0])
            strcat(msglines[curline], "  ");
        strcat(msglines[curline], msg);
    } else {
        int idx, output_count;
        char **output;

        wrap_text(maxlen, msg, &output_count, &output);

        for (idx = 0; idx < output_count; idx++) {
            if (strlen(msglines[curline]) > 0)
                fresh_message_line(canblock);
            if (stopprint)
                break;  /* may get set in more() */
            strcpy(msglines[curline], output[idx]);
        }

        free_wrap(output);
    }

    draw_msgwin();
}