Exemplo n.º 1
0
/**
 * Wait for the socket threads to finish.
 *
 * Closes the socket first, if it hasn't already been done.
 */
void socket_thread_stop(void)
{
    client_socket_close(&csocket);

    SDL_WaitThread(output_thread, NULL);
    SDL_WaitThread(input_thread, NULL);

    input_thread = output_thread = NULL;
}
Exemplo n.º 2
0
/**
 * Deinitialize the client sockets.
 */
void client_socket_deinitialize(void)
{
    if (csocket.sc != NULL) {
        client_socket_close(&csocket);
    }

#ifdef WIN32
    WSACleanup();
#endif
}
Exemplo n.º 3
0
void wid_game_map_go_back_to_editor (void)
{
    client_socket_close(0, 0);
    wid_game_map_client_hide();
    wid_game_map_client_wid_destroy();

    level_pos_t level_pos;
    level_pos.x = 66;
    level_pos.y = 66;

    wid_editor(level_pos);
}
Exemplo n.º 4
0
/**
 * Worker for the writer thread. It waits for enqueued outgoing packets
 * and sends them to the server as fast as it can.
 *
 * If any error is detected, the socket is closed and the thread exits. It is
 * up to them main thread to detect this and join() the worker threads.
 */
static int writer_thread_loop(void *dummy)
{
    command_buffer *buf = NULL;

    while (!abort_thread) {
        SDL_LockMutex(output_buffer_mutex);

        while (output_queue_start == NULL && !abort_thread) {
            SDL_CondWait(output_buffer_cond, output_buffer_mutex);
        }

        buf = command_buffer_dequeue(&output_queue_start, &output_queue_end);
        SDL_UnlockMutex(output_buffer_mutex);
        size_t written = 0;

        while (buf != NULL && written < buf->len && !abort_thread) {
            size_t amt;
            bool success = socket_write(csocket.sc, (const void *) (buf->data +
                    written), buf->len - written, &amt);
            if (!success) {
                break;
            }

            written += amt;
            network_graph_update(NETWORK_GRAPH_TYPE_GAME,
                    NETWORK_GRAPH_TRAFFIC_TX, amt);
        }

        if (buf != NULL) {
            command_buffer_free(buf);
            buf = NULL;
        }
    }

    client_socket_close(&csocket);
    return 0;
}
Exemplo n.º 5
0
static int reader_thread_loop(void *dummy)
{
    static uint8_t *readbuf = NULL;
    static int readbuf_size = 256;
    int readbuf_len = 0;
    int header_len = 0;
    int cmd_len = -1;

    if (!readbuf) {
        readbuf = emalloc(readbuf_size);
    }

    while (!abort_thread) {
        int toread;

        /* First, try to read a command length sequence */
        if (readbuf_len < 2) {
            /* Three-byte length? */
            if (readbuf_len > 0 && (readbuf[0] & 0x80)) {
                toread = 3 - readbuf_len;
            } else {
                toread = 2 - readbuf_len;
            }
        } else if (readbuf_len == 2 && (readbuf[0] & 0x80)) {
            toread = 1;
        } else {
            /* If we have a finished header, get the packet size from it. */
            if (readbuf_len <= 3) {
                uint8_t *p = readbuf;

                header_len = (*p & 0x80) ? 3 : 2;
                cmd_len = 0;

                if (header_len == 3) {
                    cmd_len += ((int) (*p++) & 0x7f) << 16;
                }

                cmd_len += ((int) (*p++)) << 8;
                cmd_len += ((int) (*p++));
            }

            toread = cmd_len + header_len - readbuf_len;

            if (readbuf_len + toread > readbuf_size) {
                uint8_t *tmp = readbuf;

                readbuf_size = readbuf_len + toread;
                readbuf = emalloc(readbuf_size);
                memcpy(readbuf, tmp, readbuf_len);
                efree(tmp);
            }
        }

        size_t amt;
        bool success = socket_read(csocket.sc, (void *) (readbuf + readbuf_len),
                toread, &amt);
        if (!success) {
            break;
        }

        readbuf_len += amt;
        network_graph_update(NETWORK_GRAPH_TYPE_GAME, NETWORK_GRAPH_TRAFFIC_RX,
                amt);

        /* Finished with a command? */
        if (readbuf_len == cmd_len + header_len && !abort_thread) {
            command_buffer *buf = command_buffer_new(readbuf_len - header_len,
                    readbuf + header_len);

            SDL_LockMutex(input_buffer_mutex);
            command_buffer_enqueue(buf, &input_queue_start, &input_queue_end);
            SDL_CondSignal(input_buffer_cond);
            SDL_UnlockMutex(input_buffer_mutex);

            cmd_len = -1;
            header_len = 0;
            readbuf_len = 0;
        }
    }

    client_socket_close(&csocket);

    if (readbuf != NULL) {
        efree(readbuf);
        readbuf = NULL;
    }

    return -1;
}