Exemplo n.º 1
0
static int init_level(void)
{
    demo_play_init(USER_REPLAY_FILE, level, mode,
                   curr.score, curr.balls, curr.times);

    /*
     * Init both client and server, then process the first batch
     * of commands generated by the server to sync client to
     * server.
     */

    if (game_client_init(level_file(level)) &&
        game_server_init(level_file(level), level_time(level), goal_e))
    {
        game_client_sync(demo_fp);
        audio_music_fade_to(2.0f, level_song(level));
        return 1;
    }

    demo_play_stop(1);
    return 0;
}
void server(int port)
{
    linked_list_t *mapcycle_list = NULL;
    parse_mapcycle(&mapcycle_list);
    node_t *current_map = mapcycle_list->head;
    char port_game[100];
    char port_chat[100];
    char port_map[100];
    sprintf(port_game, "%d", port);
    sprintf(port_chat, "%d", port + 1);
    sprintf(port_map,  "%d", port + 2);
    signal(SIGTERM, sighandler);
    signal(SIGINT, sighandler);
    //node_t *current_map = mapcycle_list->head->next;
    while(server_running){
        printf("[SERVER] NEW GAME\n");
        player_list = malloc(sizeof(linked_list_t));
        observer_list = malloc(sizeof(linked_list_t));
        list_init(player_list);
        list_init(observer_list);
        int game_server_socket = prepare_server_UDP(port_game, AF_INET6);
        int chat_server_socket = prepare_server_TCP(port_chat, AF_INET6);
        int map_server_socket  = prepare_server_TCP(port_map , AF_INET6);

        current_map = current_map->next;
        if(current_map == mapcycle_list->tail){
            current_map = mapcycle_list->head->next;
        }
        game_server_init(current_map->data);

        fd_set descriptors_set;
        FD_ZERO(&descriptors_set);
        FD_SET(map_server_socket,  &descriptors_set);
        FD_SET(chat_server_socket, &descriptors_set);
        FD_SET(game_server_socket, &descriptors_set);


        int max_fd = map_server_socket > chat_server_socket ? map_server_socket : chat_server_socket;
        max_fd = max_fd > game_server_socket ? max_fd : game_server_socket;
        struct timeval timeout;
        memset(&timeout, 0, sizeof(struct timeval));
        timeout.tv_sec = 3;
        change_map = 0;
        while(!change_map){
            if(select(max_fd  + 1, &descriptors_set, NULL, NULL, &timeout) < 0) {
                continue;
            }

            timeout.tv_sec = 3;

            if (FD_ISSET(map_server_socket , &descriptors_set)){
                map_server(map_server_socket, current_map_id);
            }

            if (FD_ISSET(chat_server_socket , &descriptors_set)){
                chat_server(chat_server_socket);
            }

            if (FD_ISSET(game_server_socket , &descriptors_set)){
                game_server(game_server_socket);
            }

            for (node_t *i = player_list->head->next; i != player_list->tail; i = i->next){
                player_info_t *player_info = (player_info_t*)i->data;
                if (FD_ISSET(player_info->chat_descriptor , &descriptors_set)){
                    char buffer[129];
                    memset(buffer, 0, 129);
                    int full_recv = 0;
                    int bytes_recv = chat_recv(player_info->chat_descriptor, buffer, &full_recv);
                    if(bytes_recv == 0){
                        //HANDLE DISCONNECT
                        int player_id = player_info->playerID;

                        close(player_info->chat_descriptor);
                        node_t *previous = i->previous;
                        list_remove_node(i, player_list);
                        i = previous;

                        if (player_id == 255){
                            continue;
                        }

                        char buffer[129];
                        sprintf(buffer, "Player %"SCNu8" disconnected", player_id);
                        printf("[CHAT SERVER] %s\n", buffer);
                        broadcast_disconnection_ack(game_server_socket, player_id, player_list);
                        chat_forward_msg(0, buffer, player_list);
                    }else if (bytes_recv < 0){
                        printf("[CHAT SERVER] Error receiving from %"SCNu8"%s\n", player_info->playerID, strerror(errno));
                    }else if (full_recv){
                        if (buffer[2] == '*'){
                            change_map = 1;
                        }
                        if (player_info->playerID == 255){
                            continue;
                        }
                        chat_forward_msg(player_info->playerID, &buffer[2], player_list);
                        gettimeofday(&player_info->last_action, NULL);
                    }
                }
            }

            remove_idle_players(game_server_socket);
            respawn_death_players(game_server_socket);

            FD_ZERO(&descriptors_set);
            FD_SET(map_server_socket,  &descriptors_set);
            FD_SET(chat_server_socket, &descriptors_set);
            FD_SET(game_server_socket, &descriptors_set);
            max_fd = map_server_socket > chat_server_socket ? map_server_socket : chat_server_socket;
            max_fd = max_fd > game_server_socket ? max_fd : game_server_socket;
            for (node_t *i = player_list->head->next; i != player_list->tail; i = i->next){
                player_info_t *player_info = (player_info_t*)i->data;
                FD_SET(player_info->chat_descriptor, &descriptors_set);
                if (player_info->chat_descriptor > max_fd){
                    max_fd = player_info->chat_descriptor;
                }
            }
            if (change_map){
                sleep(5);
                broadcast_map_change(game_server_socket, player_list);
            }
        }
        change_map = 0;
        for(node_t *i = player_list->head->next; i != player_list->tail; i = i->next){
            player_info_t *player_info = (player_info_t*)i->data;
            close(player_info->chat_descriptor);
        }

        list_delete(player_list);
        free(player_list);
        list_delete(observer_list);
        game_server_shutdown();
        free(observer_list);
        close(map_server_socket);
        close(chat_server_socket);
        close(game_server_socket);
    }
    delete_mapcycle_list(&mapcycle_list);
}