Games-FrozenBubble

 view release on metacpan or  search on metacpan

server/net.c_tmp  view on Meta::CPAN

                || (incoming_data_buffers_count[fd] > 0 && incoming_data_buffers[fd][incoming_data_buffers_count[fd]-1] == '\n'))) {
                char buf[INCOMING_DATA_BUFSIZE];
                ssize_t len;
                ssize_t offset = incoming_data_buffers_count[fd];
                incoming_data_buffers_count[fd] = 0;
                memcpy(buf, incoming_data_buffers[fd], offset);
                len = recv(fd, buf + offset, INCOMING_DATA_BUFSIZE - 1 - offset, MSG_DONTWAIT);
                if (len == -1 && errno != EAGAIN) {
                        l2(OUTPUT_TYPE_DEBUG, "[%d] System error on recv: %s", fd, strerror(errno));
                        conn_terminated(fd, "system error on recv");
                        return;

                } else if (len == 0) {
                        conn_terminated(fd, "peer shutdown");
                        return;

                } else {

                        char* ptr;
                        char* eol;

                        if (len == -1)
                                len = 0;

                        last_data_in[fd] = current_time;
                        if (minute_for_talk_flood[fd] != current_time/60) {
                                minute_for_talk_flood[fd] = current_time/60;
                                amount_talk_flood[fd] = 0;
                        }

                        len += offset;
                        // If we don't have a newline, it means we are seeing a partial send. Buffer
                        // them, since we can't synchronously wait for newline now or else we'd offer a
                        // nice easy shot for DOS (and beside, this would slow down the whole rest).
                        if (buf[len-1] != '\n') {
                                if (len == INCOMING_DATA_BUFSIZE - 1) {
                                        send_line_log_push(fd, fl_client_nolf);
                                        conn_terminated(fd, "too much data without LF");
                                        return;
                                }
                                l2(OUTPUT_TYPE_DEBUG, "[%d] buffering %zd bytes (this is normal)", fd, len);
                                memcpy(incoming_data_buffers[fd], buf, len);
                                incoming_data_buffers_count[fd] = len;
                                return;
                        }

                        /* string operations will need a NULL conn_terminated string */
                        buf[len] = '\0';
                        ptr = buf;

                        while (1) {
                                if (!(eol = strchr(ptr, '\n'))) {
                                        // the bad bad guy sent a 0 byte before the \n
                                        if (!prio)
                                                send_line_log_push(fd, fl_client_nulbyte);
                                        conn_terminated(fd, "NUL byte before newline");
                                        return;
                                }

                                if (prio) {
                                        // prio e.g. in game; we split messages because p and ! must be treated specially (see game::process_msg_prio)
                                        process_msg_prio(fd, ptr, eol - ptr + 1);
                                        len -= eol - ptr + 1;
                                        if (len == 0) {
                                                prio_processed = 1;
                                                break;
                                        }
                                        ptr = eol + 1;

                                } else {
                                        eol[0] = '\0';
                                        if (process_msg(fd, ptr)) {
                                                conn_terminated(fd, "process_msg said to shutdown this connection");
                                                return;
                                        }

                                        // process_msg > talk (flooding) > conn_terminated
                                        if (interrupt_loop_processing)
                                            return;

                                        if (eol + 1 - ptr < len) {
                                                ssize_t remaining = len - (eol + 1 - ptr);
                                                l2(OUTPUT_TYPE_DEBUG, "multiple non-prio messages for %d, buffering (%zd bytes)", fd, remaining);
                                                memcpy(incoming_data_buffers[fd], eol + 1, remaining);
                                                incoming_data_buffers_count[fd] = remaining;
                                                need_another_run = 1;
                                        }
                                        /* must handle only one message, because we might have multiple and subsequent might need to be
                                           treated as prio message if the one before is about starting the game */
                                        break;
                                }
                        }
                }
                return;
        }
        if (prio) {
                // 5 seconds is in game gracetime after which player is kicked out
                if (current_time - last_data_in[fd] > 5) {
                        conn_terminated(fd, "no activity within gracetime (during game, gracetime of 5 secs)");
                }
        } else {
                if (current_time - last_data_in[fd] > gracetime) {
                        send_line_log_push(fd, fl_client_noactivity);
                        conn_terminated(fd, "no activity within gracetime (not during game)");
                }
        }
}

static void handle_incoming_data(gpointer data, gpointer user_data)
{
        handle_incoming_data_generic(data, user_data, 0);
}
static void handle_incoming_data_prio(gpointer data, gpointer user_data)
{
        handle_incoming_data_generic(data, user_data, 1);
}

static void handle_udp_request(void)
{
        static char ok_input_beginning_base[] = "FB/%d.";
        static char * ok_input_beginning = NULL;



( run in 2.629 seconds using v1.01-cache-2.11-cpan-71847e10f99 )