Uint16
BotManager::addBot()
{
    PlayerState *p = PlayerInterface::allocateNewPlayer();
    if ( p )
    {
        Bot * b = new BotPlayer(p->getID());
        bot_list.push_back(b);

        ResourceManagerSyncFlagMessage flagmsg;
        ResourceManager::getFlagData("bot.bmp",(Uint8*)&flagmsg.flagdata);
        flagmsg.setFlagID(ResourceManager::registerFlagFromData((Uint8*)&flagmsg.flagdata));

        p->setName("Bot");
        p->setFlag(flagmsg.getFlagID());
        p->setStatus(_player_state_active);

        NetworkServer::broadcastMessage(&flagmsg, sizeof(flagmsg));

        PlayerStateSync updatemsg(p->getNetworkPlayerState());
        NetworkServer::broadcastMessage( &updatemsg, sizeof(updatemsg));

        SystemConnectAlert connect_alert;
        connect_alert.set( p->getID(), _connect_alert_mesg_connect );
        NetworkServer::broadcastMessage( &connect_alert, sizeof(SystemConnectAlert));
        NetworkClient::sendMessage(&connect_alert, sizeof(SystemConnectAlert));
        
        return p->getID();
    }
    return 0xffff;
}
    virtual T message(const NetMessage* msg)
    {
        if ( msg->message_id == _net_message_id_connect_client_settings )
        {
            ConnectClientSettings *client_setting;

            client_setting = (ConnectClientSettings *) msg;

            player->setName( client_setting->player_name );

            ResourceManager::updateFlagData(player->getID(),
                                            client_setting->player_flag,
                                            sizeof(client_setting->player_flag) );

            player->setStateConnecting();

            // ** send server game setting map, units, player, etc.
            ConnectMesgServerGameSettings* server_game_setup
                = GameManager::getServerGameSetup();

            connect_client->sendMessage( server_game_setup,
                                         sizeof(ConnectMesgServerGameSettings));
            connect_client->sendRemaining();
            delete server_game_setup;

            return connect_state_wait_for_client_game_setup_ack;
        }
        return State<T>::state;
    }
    virtual T message(const NetMessage* msg)
    {
        T new_state = connect_state_drop_bad_connecting_client;
        if ( msg->message_id == _net_message_id_client_connect_request )
        {
            ClientConnectResult connect_result;

            if ((GameConfig::game_allowmultiip == false) && 
               (SERVER->isAlreadyConnected(connect_client) == true))
            {
                connect_result.result_code = _connect_result_server_already_connected;
                LOGGER.warning("Client already connected!!!!, die");
            }
            else
            {
                PlayerState * player = PlayerInterface::allocateNewPlayer();
                if ( player == 0 )
                {
                    connect_result.result_code = _connect_result_server_full;
                }
                else
                {
                    connect_result.result_code = _connect_result_success;
                    connect_client->player_id = player->getID();
                    new_state = connect_state_wait_for_client_settings;
                }
            }

            connect_client->sendMessage( &connect_result,
                                         sizeof(ClientConnectResult));
            connect_client->sendRemaining();
        }

        return new_state;
    }
    virtual T message(const NetMessage* msg)
    {
        if ( msg->message_id == _net_message_id_connect_client_game_setup_ack )
        {
            PlayerConnectID player_connect_mesg(player->getID());
            connect_client->sendMessage( &player_connect_mesg,
                                         sizeof(PlayerConnectID));

            return connect_state_unit_profile_sync;
        }
        else if ( msg->message_id == _net_message_id_connect_client_game_setup_ping )
        {
            time_out_timer.reset();
        }
        return State<T>::state;
    }
void GameManager::netMessagePingRequest(const NetMessage* message)
{
    const SystemPingRequest *ping_request
        = (const SystemPingRequest*) message;

    if(ping_request->getClientPlayerIndex() >= PlayerInterface::getMaxPlayers())
    {
        LOGGER.warning("Invalid pingRequest message");
        return;
    }

    PlayerState * player;
    player = PlayerInterface::getPlayer( ping_request->getClientPlayerIndex() );

    SystemPingAcknowledge ping_ack;

    if ( player->getStatus() == _player_state_active
         && ping_request->getClientPlayerIndex() != MIN_PLAYER_ID
       )
    {
        SERVER->sendMessage(player->getID(), &ping_ack, sizeof(SystemPingAcknowledge));
    }
}
//-----------------------------------------------------------------
void DedicatedGameManager::inputLoop()
{
    // handle server commands
    SDL_mutexP(commandqueue_mutex);
    while(!commandqueue.empty()) {
        const ServerCommand& command = commandqueue.front();

        switch(command.type) {
            case ServerCommand::QUIT:
            {
                ActionManager::runAction("quit");
                break;
            }
            case ServerCommand::CHAT:
            {
                ChatInterface::serversay(command.argument.c_str());
                break;
            }
            case ServerCommand::STATUS:
            {
                //*Console::server
                std::cout
                    << "Server " << *GameConfig::server_name
                    << " version " << PACKAGE_VERSION << " port "
                    << GameConfig::server_port << "\n"
                    << "Map: " << *GameConfig::game_map << "\n"
                    << std::setw(3) << "ID" << " "
                    << std::setw(30) << "Name" << " "
                    << std::setw(4) << "Kill" << " "
                    << std::setw(4) << "Lost" << " "
                    << std::setw(5) << "Score" << " "
                    << std::setw(21) << "IP\n";
                PlayerID i;
                for ( i = 0; i<PlayerInterface::getMaxPlayers(); ++i)
                {
                    PlayerState* playerstate = PlayerInterface::getPlayer(i);
                    if ( playerstate->isActive() )
                    {
                        //*Console::server
                        std::cout
                            << std::setw(3) << static_cast<int>(i) << " "
                            << std::setw(30) << playerstate->getName() << " "
                            << std::setw(4) << playerstate->getKills() << " "
                            << std::setw(4) << playerstate->getLosses() << " "
                            << std::setw(5) << playerstate->getTotal() << " "
                            << std::setw(21)
                            << SERVER->getIP(playerstate->getID())
                            << "\n";
                    }
                }
                //*Console::server << std::flush;
                std::cout << std::flush;
                break;
            }
            case ServerCommand::MAPCHANGE:
                if(!MapsManager::existsMap(command.argument)) {
                    std::cout << "map '" << command.argument
                        << "' doesn't exist." << std::endl;
                    break;
                }
            
                GameControlRulesDaemon::forceMapChange(command.argument);
                std::cout << "Preparing mapchange..." << std::endl;
                break;
            case ServerCommand::KICK:
                std::stringstream idstream(command.argument);
                PlayerID id = INVALID_PLAYER_ID;
                idstream >> (int&)id; // XXX KREMOVE
                if(id >= PlayerInterface::getMaxPlayers()) {
                    std::cout << "Unknown player." << std::endl;
                    break;
                }
                SERVER->kickClient(id);
                break;
        }
        commandqueue.pop();
    }
    SDL_mutexV(commandqueue_mutex);
    BaseGameManager::inputLoop();
}
void
NetworkServer::onClientDisconected(ClientSocket *s, const char * msg)
{
    LOGGER.debug("NetworkServer::onClientDisconected( %d, '%s')", s->getId(), msg ? msg : "nice");
    
    bool cleandisconnect = false;
    bool sendalert = true;
    
    if ( ServerConnectDaemon::inConnectQueue(s) )
    {
        // player was connecting and dropped.
        ServerConnectDaemon::removeClientFromQueue(s);
        sendalert = false;
        LOGGER.debug("NetworkServer::onClientDisconected player was connecting");
    }
    
    if ( NetworkInterface::receive_queue.isReady() )
    {
        unsigned long frontsave = NetworkInterface::receive_queue.front;
        while ( NetworkInterface::receive_queue.isReady() )
        {
            LOGGER.debug("NetworkServer::onClientDisconected there was a packet");
            NetPacket packet;

            NetworkInterface::receive_queue.dequeue(&packet);

            if ( packet.fromClient == s )
            {
                LOGGER.debug("NetworkServer::onClientDisconected the packet was from our friend");
                const NetMessage * netmessage = packet.getNetMessage();
                if (   netmessage->message_class == _net_message_class_connect 
                    && netmessage->message_id == _net_message_id_connect_netPanzer_client_disconnect )
                {
                    LOGGER.debug("NetworkServer::onClientDisconected so is a clean disconnect");
                    cleandisconnect = true;
                }
            }
        }
        NetworkInterface::receive_queue.front = frontsave;
    }
    
    PlayerID player_index = s->getPlayerIndex();
    
    if ( player_index != INVALID_PLAYER_ID )
    {
        PlayerState * player = PlayerInterface::getPlayer(player_index);
        bool kicked = player ? player->isKicked() : false;

        if ( player && sendalert && ! kicked)
        {
            if (GameConfig::game_teammode == true)
            ConsoleInterface::postMessage(Color::cyan, true, player->getFlag(),
                                      _("'%s' has left."),
                                      player->getName().c_str());
        }

        ObjectiveInterface::disownPlayerObjectives( player_index );
        UnitInterface::destroyPlayerUnits( player_index );
        PlayerInterface::disconnectPlayerCleanup( player_index );    

        if ( sendalert )
        {
            SystemConnectAlert scmsg;
            if ( cleandisconnect || ! msg )
            {
                scmsg.set( player_index, _connect_alert_mesg_disconnect);
            }
            else if ( kicked )
            {
                scmsg.set( player_index, _connect_alert_mesg_client_kicked);
            }
            else
            {
                scmsg.set( player_index, _connect_alert_mesg_client_drop );
            }
            SERVER->broadcastMessage(&scmsg, sizeof(scmsg));
        }
        if (GameConfig::game_teammode == true)
        {
            TeamManager::removePlayer(player->getID(), player->getTeamID());
            TeamManager::BalancedTeam();
        }
    }
}