Exemplo n.º 1
0
// Create new player instance, save it
// to logging in players list.
bool CLounge::addPlayer(SOCKET sd, struct in_addr* inaddr)
{   
    if (FindIPAddress(inaddr->s_addr))
    {
        CpduNotify pdu;
        char s[300];
        const char* saddr = inet_ntoa(*inaddr);
        if (saddr != NULL)
            sprintf(s, "Error: ip address %s is already logged in.", saddr);
        else
            sprintf(s, "Error: ip address %ld is already logged in.", inaddr->s_addr);
        pdu.sendNotifyMessage(sd, s);
        Sys_LogError(s);

        CPoller::Inst()->removePlayerSocket(sd);
        Sys_CloseSocket(sd);

        return false;
    }

    RegisterIPAddress(inaddr->s_addr);

    CLoginPlayer lp(sd, inaddr->s_addr);
    loggingIn_.push_back(lp);
    return true;
}
Exemplo n.º 2
0
void CLounge::processLogins(long now)
{
    // Check if somebody's been logging in too long
    // - if so, log out the player
    list<CLoginPlayer>::iterator i = loggingIn_.begin();

    while (i != loggingIn_.end())
    {
        CLoginPlayer& p = (*i);
    
        if (now - p.loginTime_ > LOGIN_TIMEOUT)
        {   
            // Login not completed withing timeout - player will
            // be forcibly logged out

            UnregisterIPAddress(p.player_.getIpAddress());

            CpduNotify pdu;
            pdu.sendNotifyMessage(p.player_.getSocket(), "Login timed out.");
            printf("Login time for socket %d exceeded - terminating connection.\n",
                   p.player_.getSocket());
            CPoller::Inst()->removePlayerSocket(p.player_.getSocket());
            Sys_CloseSocket(p.player_.getSocket());

            // XXX the client does not react very well
            // to the socket being closed like this

            i = loggingIn_.erase(i);
        }
        else
        {
            ++i;
        }
    }
}
Exemplo n.º 3
0
/*
====================
Sys_CloseAllSockets

Close all network sockets
====================
*/
static void Sys_CloseAllSockets (void)
{
	size_t sock_ind;
	for (sock_ind = 0; sock_ind < nb_sockets; sock_ind++)
	{
		listen_socket_t* sock = &listen_sockets[sock_ind];

		if (sock->socket != -1)
			Sys_CloseSocket (sock->socket);
	}
	nb_sockets = 0;
}
Exemplo n.º 4
0
bool CLounge::login(SOCKET sd,
                    const char* username,
                    const char* password,
                    u_int16_t platform,
                    u_byte_t* checksum)
{
  if (shutdown_)
  {
    CpduNotify pdu;
    pdu.sendNotifyMessage(sd, "The server is shutting down - please try again later.");
    return false;
  }   
  
  // Find the player from the logging in list
  list<CLoginPlayer>::iterator pos = find_if(loggingIn_.begin(),
                                             loggingIn_.end(),
                                             same_socket(sd));
  
  // Testing: Allow 'bot_X' players to log in without login entries
  string test_string(username);
  
  if (pos == loggingIn_.end() && test_string.find("bot_") != 0)
  {
    // Player was not found from logging in list.
    // Internal logic error - should never happen
    char s[128];
    sprintf(s, "Internal error: player (%d %s, %s) not in logging in list\n",
            sd, username, password);
    Sys_LogError(s);
    CPoller::Inst()->removePlayerSocket(sd);
    Sys_CloseSocket(sd);
    return false;
  }
  
  bool rc = validate(sd, username, password, pos);
  
  if (rc)
  {      
    // login accepted - add to loginComplete_ list
    // so it'll be removed from logginIn_ list
    // and added to main player container.
    // (it's done it two steps because while we're
    // here we're iterating over the logginIn_ list)
    (*pos).username_ = username;
    (*pos).password_ = password;
    
    loginComplete_.push_back(*pos);
  }
  
  return rc;
}
Exemplo n.º 5
0
bool CLounge::removeTable(CTable* table)
{
  // Remove table from poller
  SOCKET sd = table->getSocket();
  CPoller::Inst()->removeTableSocket(sd);
  Sys_CloseSocket(sd);
  
  // Remove table from main list
  Tables::iterator pos = find_if(tables_.begin(),
                                 tables_.end(),
                                 same_socket(sd));
  if (pos != tables_.end())
    tables_.erase(pos);
  
  return true;
}
Exemplo n.º 6
0
bool CLounge::validate(SOCKET sd,
                       const char* username,
                       const char* password,
                       LoginIT& pos)
{
    bool rc = dbase_->authenticate(username, password);

    if (!rc)
    {
        if ((*pos).retryCount_++ < MAX_LOGIN_RETRIES)
        {
            // Invalid username/password -
            // reject login, allow retry
            CpduLoginReject pdu;
            pdu.sendReject(sd, RF_Allow_Retry);
        }
        else
        {   // Too many login failures

            UnregisterIPAddress((*pos).player_.getIpAddress());

            // Remove the player from logging list
            loginComplete_.push_back(*pos);    
            //This code not for production:
            //loggingIn_.erase(pos);

            // Reject login, terminate connection
            CpduLoginReject pdu;
            pdu.sendReject(sd, RF_No_Retry);
            CPoller::Inst()->removePlayerSocket(sd);
            Sys_CloseSocket(sd);
        }
    }

    return rc;
}
Exemplo n.º 7
0
void CLounge::postProcessLogins()
{
    // Removing elements from a list while iterating
    // over it is tricky. 
    //
    // Those CLoginPlayers who have completed their
    // logins are processed here by removing the
    // CLoginPlayer entries
    //
    list<CLoginPlayer>::iterator i = loginComplete_.begin(),
                                 e = loginComplete_.end();

    while (i != e)
    {
        CLoginPlayer& p = (*i);

        // Remove from logging in list
        LoginPlayers::iterator pos =
            find_if(loggingIn_.begin(),
                    loggingIn_.end(),
                    same_socket(p.player_.getSocket()));
        if (pos != loggingIn_.end())
        {
            loggingIn_.erase(pos);
        }

        // Add to main list
        // We also check that THE SAME NAME is not there already.
        // The check is case insensitive.
        u_long ipaddr = p.player_.getIpAddress();
        SOCKET sd = p.player_.getSocket();
        string checkName = p.username_;

        // Failed logins will have empty name
        if (checkName.size() > 0)
        {
            tolower(checkName);

            CPlayer player(p.username_, sd, ipaddr);
            if (players_.insert(Players::value_type(checkName.c_str(), player)).second == false)
            {   // Player with same name is logged in already!
                CpduNotify pdu;
                char s[128];
                sprintf(s, "Error: user %s is already logged in.", p.username_.c_str());
                pdu.sendNotifyMessage(sd, s);

                UnregisterIPAddress(ipaddr);
                CPoller::Inst()->removePlayerSocket(sd);
                Sys_CloseSocket(sd);
            }
            else
            {   // 
                // login completed successfully
                //
                string motd;
                dbase_->getMotdMsg(motd);
                if (motd.size() == 0)
                  motd = "Welcome to PokerSpot online cardroom!";

                // Send accept to player
                CpduLoginAccept pduAccept(p.username_.c_str(),
                                          p.password_.c_str(),
                                          motd.c_str());
                pduAccept.sendTo(sd);

                // Notify Load Balancer and/or other lounges
                notifyOthers(AddPlayer, p.username_.c_str());
            }
        }
        ++i;
    }

    loginComplete_.clear();
}
Exemplo n.º 8
0
void CLounge::processLogouts(long /*now*/)
{
    bool sendUpdate = false;

    //
    // Process logging out players
    //
    list<PlayerPtr>::iterator i = loggingOut_.begin();

    while (i != loggingOut_.end())
    {
        sendUpdate = true;

        string username = (*i).player_->name();
        SOCKET sd = (*i).player_->getSocket();

        printf("Logging out player %s socket %d.\n",
               username.c_str(), sd);

        // Forget ip address
        UnregisterIPAddress((*i).player_->getIpAddress());

        // Erase the player from the main list.
        tolower(username);

        if (players_.erase(username) == 0)
        {   // player was not in main list - erase from
            // logging in list
            LoginPlayers::iterator it = find_if(loggingIn_.begin(),
                                                loggingIn_.end(),
                                                same_socket(sd));
            if (it != loggingIn_.end())
                loggingIn_.erase(it);
        }

        // Terminate the connection
        CPoller::Inst()->removePlayerSocket(sd);
        Sys_CloseSocket(sd);

        // Notify Load Balancer and/or lounges
        notifyOthers(RemovePlayer, username.c_str());


        // Remove it from logging out list
        i = loggingOut_.erase(i);
    }

    //
    // Process logging out tables
    //
    list<TablePtr>::iterator ti = loggingOutTables_.begin();

    while (ti != loggingOutTables_.end())
    {
        sendUpdate = true;

        CTable* table = (*ti).table_;
        printf("*** Removing table %d socket %d.\n",
               table->getNumber(), table->getSocket());

        removeTable(table);

        // NOTE: after removeTable 'table' points to destroyed data

        // Remove it from logging out list
        ti = loggingOutTables_.erase(ti);
    }

    if (sendUpdate)
    {
        // Send login stats update if something was removed
        CpduLoungeStats pduStats;
        pduStats.sendStats(players_.size(), tables_.size());
    }
}