fix for server on local host (for server list)
This commit is contained in:
parent
22591a4aae
commit
3a1c4510fa
1 changed files with 271 additions and 258 deletions
|
@ -1,258 +1,271 @@
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
* Copyright (c) 2004-2011
|
* Copyright (c) 2004-2011
|
||||||
*
|
*
|
||||||
* Author(s):
|
* Author(s):
|
||||||
* Volker Fischer
|
* Volker Fischer
|
||||||
*
|
*
|
||||||
******************************************************************************
|
******************************************************************************
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it under
|
* This program is free software; you can redistribute it and/or modify it under
|
||||||
* the terms of the GNU General Public License as published by the Free Software
|
* the terms of the GNU General Public License as published by the Free Software
|
||||||
* Foundation; either version 2 of the License, or (at your option) any later
|
* Foundation; either version 2 of the License, or (at your option) any later
|
||||||
* version.
|
* version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
* details.
|
* details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License along with
|
* You should have received a copy of the GNU General Public License along with
|
||||||
* this program; if not, write to the Free Software Foundation, Inc.,
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
*
|
||||||
\******************************************************************************/
|
\******************************************************************************/
|
||||||
|
|
||||||
#include "serverlist.h"
|
#include "serverlist.h"
|
||||||
|
|
||||||
|
|
||||||
/* Implementation *************************************************************/
|
/* Implementation *************************************************************/
|
||||||
CServerListManager::CServerListManager ( const QString& sNCentServAddr,
|
CServerListManager::CServerListManager ( const QString& sNCentServAddr,
|
||||||
CProtocol* pNConLProt )
|
CProtocol* pNConLProt )
|
||||||
: strCentralServerAddress ( sNCentServAddr ),
|
: strCentralServerAddress ( sNCentServAddr ),
|
||||||
pConnLessProtocol ( pNConLProt )
|
pConnLessProtocol ( pNConLProt )
|
||||||
{
|
{
|
||||||
// per definition: If the central server address is empty, the server list
|
// per definition: If the central server address is empty, the server list
|
||||||
// is disabled.
|
// is disabled.
|
||||||
// per definition: If we are in server mode and the central server address
|
// per definition: If we are in server mode and the central server address
|
||||||
// is the localhost address, we are in central server mode. For the central
|
// is the localhost address, we are in central server mode. For the central
|
||||||
// server, the server list is always enabled.
|
// server, the server list is always enabled.
|
||||||
if ( !strCentralServerAddress.isEmpty() )
|
if ( !strCentralServerAddress.isEmpty() )
|
||||||
{
|
{
|
||||||
bIsCentralServer =
|
bIsCentralServer =
|
||||||
( !strCentralServerAddress.toLower().compare ( "localhost" ) ||
|
( !strCentralServerAddress.toLower().compare ( "localhost" ) ||
|
||||||
!strCentralServerAddress.compare ( "127.0.0.1" ) );
|
!strCentralServerAddress.compare ( "127.0.0.1" ) );
|
||||||
|
|
||||||
bEnabled = true;
|
bEnabled = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bIsCentralServer = false;
|
bIsCentralServer = false;
|
||||||
bEnabled = true;
|
bEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// per definition, the very first entry is this server and this entry will
|
// per definition, the very first entry is this server and this entry will
|
||||||
// never be deleted
|
// never be deleted
|
||||||
ServerList.clear();
|
ServerList.clear();
|
||||||
|
|
||||||
// per definition the client substitudes the IP address of the central server
|
// per definition the client substitudes the IP address of the central server
|
||||||
// itself for his server list
|
// itself for his server list
|
||||||
ServerList.append ( CServerListEntry (
|
ServerList.append ( CServerListEntry (
|
||||||
CHostAddress(),
|
CHostAddress(),
|
||||||
"Master Server", // TEST
|
"Master Server", // TEST
|
||||||
"",
|
"",
|
||||||
QLocale::Germany, // TEST
|
QLocale::Germany, // TEST
|
||||||
"Munich", // TEST
|
"Munich", // TEST
|
||||||
0, // will be updated later
|
0, // will be updated later
|
||||||
USED_NUM_CHANNELS,
|
USED_NUM_CHANNELS,
|
||||||
true ) ); // TEST
|
true ) ); // TEST
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Connections -------------------------------------------------------------
|
// Connections -------------------------------------------------------------
|
||||||
QObject::connect ( &TimerPollList, SIGNAL ( timeout() ),
|
QObject::connect ( &TimerPollList, SIGNAL ( timeout() ),
|
||||||
this, SLOT ( OnTimerPollList() ) );
|
this, SLOT ( OnTimerPollList() ) );
|
||||||
|
|
||||||
QObject::connect ( &TimerRegistering, SIGNAL ( timeout() ),
|
QObject::connect ( &TimerRegistering, SIGNAL ( timeout() ),
|
||||||
this, SLOT ( OnTimerRegistering() ) );
|
this, SLOT ( OnTimerRegistering() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServerListManager::SetEnabled ( const bool bState )
|
void CServerListManager::SetEnabled ( const bool bState )
|
||||||
{
|
{
|
||||||
QMutexLocker locker ( &Mutex );
|
QMutexLocker locker ( &Mutex );
|
||||||
|
|
||||||
bEnabled = bState;
|
bEnabled = bState;
|
||||||
|
|
||||||
if ( bEnabled )
|
if ( bEnabled )
|
||||||
{
|
{
|
||||||
if ( bIsCentralServer )
|
if ( bIsCentralServer )
|
||||||
{
|
{
|
||||||
// start timer for polling the server list if enabled
|
// start timer for polling the server list if enabled
|
||||||
// 1 minute = 60 * 1000 ms
|
// 1 minute = 60 * 1000 ms
|
||||||
TimerPollList.start ( SERVLIST_POLL_TIME_MINUTES * 60000 );
|
TimerPollList.start ( SERVLIST_POLL_TIME_MINUTES * 60000 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// initiate registration right away so that we do not have to wait
|
// initiate registration right away so that we do not have to wait
|
||||||
// for the first time out of the timer until the slave server gets
|
// for the first time out of the timer until the slave server gets
|
||||||
// registered at the central server, note that we have to unlock
|
// registered at the central server, note that we have to unlock
|
||||||
// the mutex before calling the function since inside this function
|
// the mutex before calling the function since inside this function
|
||||||
// the mutex is locked, too
|
// the mutex is locked, too
|
||||||
locker.unlock();
|
locker.unlock();
|
||||||
{
|
{
|
||||||
OnTimerRegistering();
|
OnTimerRegistering();
|
||||||
}
|
}
|
||||||
locker.relock();
|
locker.relock();
|
||||||
|
|
||||||
// start timer for registering this server at the central server
|
// start timer for registering this server at the central server
|
||||||
// 1 minute = 60 * 1000 ms
|
// 1 minute = 60 * 1000 ms
|
||||||
TimerRegistering.start ( SERVLIST_REGIST_INTERV_MINUTES * 60000 );
|
TimerRegistering.start ( SERVLIST_REGIST_INTERV_MINUTES * 60000 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// disable service -> stop timer
|
// disable service -> stop timer
|
||||||
if ( bIsCentralServer )
|
if ( bIsCentralServer )
|
||||||
{
|
{
|
||||||
TimerPollList.stop();
|
TimerPollList.stop();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TimerRegistering.stop();
|
TimerRegistering.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Central server functionality ***********************************************/
|
/* Central server functionality ***********************************************/
|
||||||
void CServerListManager::OnTimerPollList()
|
void CServerListManager::OnTimerPollList()
|
||||||
{
|
{
|
||||||
QMutexLocker locker ( &Mutex );
|
QMutexLocker locker ( &Mutex );
|
||||||
|
|
||||||
// check all list entries except of the very first one (which is the central
|
// check all list entries except of the very first one (which is the central
|
||||||
// server entry) if they are still valid
|
// server entry) if they are still valid
|
||||||
for ( int iIdx = 1; iIdx < ServerList.size(); iIdx++ )
|
for ( int iIdx = 1; iIdx < ServerList.size(); iIdx++ )
|
||||||
{
|
{
|
||||||
// 1 minute = 60 * 1000 ms
|
// 1 minute = 60 * 1000 ms
|
||||||
if ( ServerList[iIdx].RegisterTime.elapsed() >
|
if ( ServerList[iIdx].RegisterTime.elapsed() >
|
||||||
( SERVLIST_TIME_OUT_MINUTES * 60000 ) )
|
( SERVLIST_TIME_OUT_MINUTES * 60000 ) )
|
||||||
{
|
{
|
||||||
// remove this list entry
|
// remove this list entry
|
||||||
ServerList.removeAt ( iIdx );
|
ServerList.removeAt ( iIdx );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServerListManager::RegisterServer ( const CHostAddress& InetAddr,
|
void CServerListManager::RegisterServer ( const CHostAddress& InetAddr,
|
||||||
const CServerCoreInfo& ServerInfo )
|
const CServerCoreInfo& ServerInfo )
|
||||||
{
|
{
|
||||||
QMutexLocker locker ( &Mutex );
|
QMutexLocker locker ( &Mutex );
|
||||||
|
|
||||||
if ( bIsCentralServer && bEnabled )
|
if ( bIsCentralServer && bEnabled )
|
||||||
{
|
{
|
||||||
const int iCurServerListSize = ServerList.size();
|
const int iCurServerListSize = ServerList.size();
|
||||||
|
|
||||||
// check for maximum allowed number of servers in the server list
|
// check for maximum allowed number of servers in the server list
|
||||||
if ( iCurServerListSize < MAX_NUM_SERVERS_IN_SERVER_LIST )
|
if ( iCurServerListSize < MAX_NUM_SERVERS_IN_SERVER_LIST )
|
||||||
{
|
{
|
||||||
// define invalid index used as a flag
|
// define invalid index used as a flag
|
||||||
const int ciInvalidIdx = -1;
|
const int ciInvalidIdx = -1;
|
||||||
|
|
||||||
// Check if server is already registered. Use IP number and port
|
// Check if server is already registered. Use IP number and port
|
||||||
// number to fully identify a server. The very first list entry must
|
// number to fully identify a server. The very first list entry must
|
||||||
// not be checked since this is per definition the central server
|
// not be checked since this is per definition the central server
|
||||||
// (i.e., this server)
|
// (i.e., this server)
|
||||||
int iSelIdx = ciInvalidIdx; // initialize with an illegal value
|
int iSelIdx = ciInvalidIdx; // initialize with an illegal value
|
||||||
for ( int iIdx = 1; iIdx < iCurServerListSize; iIdx++ )
|
for ( int iIdx = 1; iIdx < iCurServerListSize; iIdx++ )
|
||||||
{
|
{
|
||||||
if ( ServerList[iIdx].HostAddr == InetAddr )
|
if ( ServerList[iIdx].HostAddr == InetAddr )
|
||||||
{
|
{
|
||||||
// store entry index
|
// store entry index
|
||||||
iSelIdx = iIdx;
|
iSelIdx = iIdx;
|
||||||
|
|
||||||
// entry found, leave for-loop
|
// entry found, leave for-loop
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if server is not yet registered, we have to create a new entry
|
// if server is not yet registered, we have to create a new entry
|
||||||
if ( iSelIdx == ciInvalidIdx )
|
if ( iSelIdx == ciInvalidIdx )
|
||||||
{
|
{
|
||||||
// create a new server list entry and init with received data
|
// create a new server list entry and init with received data
|
||||||
ServerList.append ( CServerListEntry ( InetAddr, ServerInfo ) );
|
ServerList.append ( CServerListEntry ( InetAddr, ServerInfo ) );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// update all data and call update registration function
|
// update all data and call update registration function
|
||||||
ServerList[iSelIdx].strName = ServerInfo.strName;
|
ServerList[iSelIdx].strName = ServerInfo.strName;
|
||||||
ServerList[iSelIdx].strTopic = ServerInfo.strTopic;
|
ServerList[iSelIdx].strTopic = ServerInfo.strTopic;
|
||||||
ServerList[iSelIdx].eCountry = ServerInfo.eCountry;
|
ServerList[iSelIdx].eCountry = ServerInfo.eCountry;
|
||||||
ServerList[iSelIdx].strCity = ServerInfo.strCity;
|
ServerList[iSelIdx].strCity = ServerInfo.strCity;
|
||||||
ServerList[iSelIdx].iNumClients = ServerInfo.iNumClients;
|
ServerList[iSelIdx].iNumClients = ServerInfo.iNumClients;
|
||||||
ServerList[iSelIdx].iMaxNumClients = ServerInfo.iMaxNumClients;
|
ServerList[iSelIdx].iMaxNumClients = ServerInfo.iMaxNumClients;
|
||||||
ServerList[iSelIdx].bPermanentOnline = ServerInfo.bPermanentOnline;
|
ServerList[iSelIdx].bPermanentOnline = ServerInfo.bPermanentOnline;
|
||||||
ServerList[iSelIdx].UpdateRegistration();
|
ServerList[iSelIdx].UpdateRegistration();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CServerListManager::QueryServerList ( const CHostAddress& InetAddr )
|
void CServerListManager::QueryServerList ( const CHostAddress& InetAddr )
|
||||||
{
|
{
|
||||||
QMutexLocker locker ( &Mutex );
|
QMutexLocker locker ( &Mutex );
|
||||||
|
|
||||||
if ( bIsCentralServer && bEnabled )
|
if ( bIsCentralServer && bEnabled )
|
||||||
{
|
{
|
||||||
const int iCurServerListSize = ServerList.size();
|
const int iCurServerListSize = ServerList.size();
|
||||||
|
|
||||||
// allocate memory for the entire list
|
// allocate memory for the entire list
|
||||||
CVector<CServerInfo> vecServerInfo ( iCurServerListSize );
|
CVector<CServerInfo> vecServerInfo ( iCurServerListSize );
|
||||||
|
|
||||||
// copy the list (we have to copy it since the message requires
|
// copy the list (we have to copy it since the message requires
|
||||||
// a vector but the list is actually stored in a QList object and
|
// a vector but the list is actually stored in a QList object and
|
||||||
// not in a vector object
|
// not in a vector object
|
||||||
for ( int iIdx = 0; iIdx < iCurServerListSize; iIdx++ )
|
for ( int iIdx = 0; iIdx < iCurServerListSize; iIdx++ )
|
||||||
{
|
{
|
||||||
// copy list item
|
// copy list item
|
||||||
vecServerInfo[iIdx] = ServerList[iIdx];
|
vecServerInfo[iIdx] = ServerList[iIdx];
|
||||||
|
|
||||||
// create "send empty message" for all registered servers (except
|
// check if the address of the client which is requesting the list
|
||||||
// of the very first list entry since this is this server (central
|
// is the same address as one server in the list -> in this case
|
||||||
// server) per definition)
|
// he has to connect to the local host address, unfortunately, the
|
||||||
if ( iIdx > 0 )
|
// port number is not known (because of NAT port translating) so we
|
||||||
{
|
// assume that it is the default llcon port number
|
||||||
pConnLessProtocol->CreateCLSendEmptyMesMes (
|
if ( vecServerInfo[iIdx].HostAddr == InetAddr )
|
||||||
vecServerInfo[iIdx].HostAddr,
|
{
|
||||||
InetAddr );
|
vecServerInfo[iIdx].HostAddr.InetAddr.
|
||||||
}
|
setAddress ( QHostAddress::LocalHost );
|
||||||
}
|
|
||||||
|
vecServerInfo[iIdx].HostAddr.iPort = LLCON_DEFAULT_PORT_NUMBER;
|
||||||
// send the server list to the client
|
}
|
||||||
pConnLessProtocol->CreateCLServerListMes ( InetAddr, vecServerInfo );
|
|
||||||
}
|
// create "send empty message" for all registered servers (except
|
||||||
}
|
// of the very first list entry since this is this server (central
|
||||||
|
// server) per definition)
|
||||||
|
if ( iIdx > 0 )
|
||||||
/* Slave server functionality *************************************************/
|
{
|
||||||
void CServerListManager::OnTimerRegistering()
|
pConnLessProtocol->CreateCLSendEmptyMesMes (
|
||||||
{
|
vecServerInfo[iIdx].HostAddr,
|
||||||
// we need the lock since the user might change the server properties at
|
InetAddr );
|
||||||
// any time
|
}
|
||||||
QMutexLocker locker ( &Mutex );
|
}
|
||||||
|
|
||||||
if ( !bIsCentralServer && bEnabled )
|
// send the server list to the client
|
||||||
{
|
pConnLessProtocol->CreateCLServerListMes ( InetAddr, vecServerInfo );
|
||||||
// For the slave server, the slave server properties are store in the
|
}
|
||||||
// very first item in the server list (which is actually no server list
|
}
|
||||||
// but just one item long for the slave server).
|
|
||||||
// Note that we always have to parse the server address again since if
|
|
||||||
// it is an URL of a dynamic IP address, the IP address might have
|
/* Slave server functionality *************************************************/
|
||||||
// changed in the meanwhile.
|
void CServerListManager::OnTimerRegistering()
|
||||||
CHostAddress HostAddress;
|
{
|
||||||
if ( LlconNetwUtil().ParseNetworkAddress ( strCentralServerAddress,
|
// we need the lock since the user might change the server properties at
|
||||||
HostAddress ) )
|
// any time
|
||||||
{
|
QMutexLocker locker ( &Mutex );
|
||||||
pConnLessProtocol->CreateCLRegisterServerMes ( HostAddress,
|
|
||||||
ServerList[0] );
|
if ( !bIsCentralServer && bEnabled )
|
||||||
}
|
{
|
||||||
}
|
// For the slave server, the slave server properties are store in the
|
||||||
}
|
// very first item in the server list (which is actually no server list
|
||||||
|
// but just one item long for the slave server).
|
||||||
|
// Note that we always have to parse the server address again since if
|
||||||
|
// it is an URL of a dynamic IP address, the IP address might have
|
||||||
|
// changed in the meanwhile.
|
||||||
|
CHostAddress HostAddress;
|
||||||
|
if ( LlconNetwUtil().ParseNetworkAddress ( strCentralServerAddress,
|
||||||
|
HostAddress ) )
|
||||||
|
{
|
||||||
|
pConnLessProtocol->CreateCLRegisterServerMes ( HostAddress,
|
||||||
|
ServerList[0] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue