mirror of
https://github.com/glest/glest-source.git
synced 2025-08-15 21:04:00 +02:00
- attempt to add a client LAG checker to notify and disconnect clients that fall too far behind.
This commit is contained in:
@@ -26,7 +26,7 @@ using namespace Shared::Platform;
|
|||||||
namespace Glest{ namespace Game{
|
namespace Glest{ namespace Game{
|
||||||
|
|
||||||
const string mailString= "contact_game@glest.org";
|
const string mailString= "contact_game@glest.org";
|
||||||
const string glestVersionString= "v3.3.5-beta5";
|
const string glestVersionString= "v3.3.5-beta7";
|
||||||
|
|
||||||
string getCrashDumpFileName(){
|
string getCrashDumpFileName(){
|
||||||
return "glest" + glestVersionString + ".dmp";
|
return "glest" + glestVersionString + ".dmp";
|
||||||
|
@@ -32,6 +32,9 @@ using namespace Shared::Platform;
|
|||||||
|
|
||||||
namespace Glest{ namespace Game{
|
namespace Glest{ namespace Game{
|
||||||
|
|
||||||
|
// if FPS is less than this we start to skip 3D renders
|
||||||
|
int MIN_RENDER_FPS_ALLOWED = 15;
|
||||||
|
|
||||||
Game *thisGamePtr = NULL;
|
Game *thisGamePtr = NULL;
|
||||||
|
|
||||||
// =====================================================
|
// =====================================================
|
||||||
@@ -51,7 +54,9 @@ Game::Game(Program *program, const GameSettings *gameSettings):
|
|||||||
this->gameSettings= *gameSettings;
|
this->gameSettings= *gameSettings;
|
||||||
scrollSpeed = Config::getInstance().getFloat("UiScrollSpeed","1.5");
|
scrollSpeed = Config::getInstance().getFloat("UiScrollSpeed","1.5");
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
MIN_RENDER_FPS_ALLOWED = Config::getInstance().getInt("MIN_RENDER_FPS_ALLOWED",intToStr(MIN_RENDER_FPS_ALLOWED).c_str());
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] MIN_RENDER_FPS_ALLOWED = %d\n",__FILE__,__FUNCTION__,__LINE__,MIN_RENDER_FPS_ALLOWED);
|
||||||
|
|
||||||
mouseX=0;
|
mouseX=0;
|
||||||
mouseY=0;
|
mouseY=0;
|
||||||
@@ -539,26 +544,28 @@ void Game::render() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Game::renderWorker() {
|
void Game::renderWorker() {
|
||||||
Chrono chrono;
|
//Chrono chrono;
|
||||||
chrono.start();
|
//chrono.start();
|
||||||
|
|
||||||
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
//program->getWindow()->makeCurrentGl();
|
//program->getWindow()->makeCurrentGl();
|
||||||
|
|
||||||
//renderFps++;
|
//renderFps++;
|
||||||
render3d();
|
if(renderFps >= MIN_RENDER_FPS_ALLOWED) {
|
||||||
|
render3d();
|
||||||
|
}
|
||||||
//if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d renderFps = %d took msecs: %d\n",__FILE__,__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
|
//if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d renderFps = %d took msecs: %d\n",__FILE__,__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
|
||||||
|
|
||||||
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
chrono.start();
|
//chrono.start();
|
||||||
render2d();
|
render2d();
|
||||||
//if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d renderFps = %d took msecs: %d\n",__FILE__,__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
|
//if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d renderFps = %d took msecs: %d\n",__FILE__,__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
|
||||||
|
|
||||||
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
chrono.start();
|
//chrono.start();
|
||||||
Renderer::getInstance().swapBuffers();
|
Renderer::getInstance().swapBuffers();
|
||||||
//if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d renderFps = %d took msecs: %d\n",__FILE__,__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
|
//if(chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d renderFps = %d took msecs: %d\n",__FILE__,__FUNCTION__,__LINE__,renderFps,chrono.getMillis());
|
||||||
|
|
||||||
@@ -824,7 +831,7 @@ void Game::keyDown(char key){
|
|||||||
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
|
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
|
||||||
|
|
||||||
if(key == configKeys.getCharKey("RenderNetworkStatus")) {
|
if(key == configKeys.getCharKey("RenderNetworkStatus")) {
|
||||||
renderNetworkStatus= true;
|
renderNetworkStatus= !renderNetworkStatus;
|
||||||
}
|
}
|
||||||
else if(key == configKeys.getCharKey("ShowFullConsole")) {
|
else if(key == configKeys.getCharKey("ShowFullConsole")) {
|
||||||
showFullConsole= true;
|
showFullConsole= true;
|
||||||
@@ -963,33 +970,30 @@ void Game::keyUp(char key){
|
|||||||
//send key to the chat manager
|
//send key to the chat manager
|
||||||
chatManager.keyUp(key);
|
chatManager.keyUp(key);
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
switch(key){
|
Config &configKeys = Config::getInstance(std::pair<ConfigType,ConfigType>(cfgMainKeys,cfgUserKeys));
|
||||||
case 'N':
|
|
||||||
renderNetworkStatus= false;
|
if(key == configKeys.getCharKey("RenderNetworkStatus")) {
|
||||||
break;
|
//renderNetworkStatus= false;
|
||||||
case 'M':
|
}
|
||||||
|
else if(key == configKeys.getCharKey("ShowFullConsole")) {
|
||||||
showFullConsole= false;
|
showFullConsole= false;
|
||||||
break;
|
}
|
||||||
case 'A':
|
else if(key == configKeys.getCharKey("CameraRotateLeft") ||
|
||||||
case 'D':
|
key == configKeys.getCharKey("CameraRotateRight")) {
|
||||||
gameCamera.setRotate(0);
|
gameCamera.setRotate(0);
|
||||||
break;
|
}
|
||||||
|
else if(key == configKeys.getCharKey("CameraRotateDown") ||
|
||||||
case 'W':
|
key == configKeys.getCharKey("CameraRotateUp")) {
|
||||||
case 'S':
|
|
||||||
gameCamera.setMoveY(0);
|
gameCamera.setMoveY(0);
|
||||||
break;
|
}
|
||||||
|
else if(key == configKeys.getCharKey("CameraModeUp") ||
|
||||||
case vkUp:
|
key == configKeys.getCharKey("CameraModeDown")) {
|
||||||
case vkDown:
|
|
||||||
gameCamera.setMoveZ(0);
|
gameCamera.setMoveZ(0);
|
||||||
break;
|
}
|
||||||
|
else if(key == configKeys.getCharKey("CameraModeLeft") ||
|
||||||
case vkLeft:
|
key == configKeys.getCharKey("CameraModeRight")) {
|
||||||
case vkRight:
|
|
||||||
gameCamera.setMoveX(0);
|
gameCamera.setMoveX(0);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1146,7 +1150,7 @@ void Game::render2d(){
|
|||||||
str+= "Update FPS: "+intToStr(lastUpdateFps)+"\n";
|
str+= "Update FPS: "+intToStr(lastUpdateFps)+"\n";
|
||||||
str+= "GameCamera pos: "+floatToStr(gameCamera.getPos().x)+","+floatToStr(gameCamera.getPos().y)+","+floatToStr(gameCamera.getPos().z)+"\n";
|
str+= "GameCamera pos: "+floatToStr(gameCamera.getPos().x)+","+floatToStr(gameCamera.getPos().y)+","+floatToStr(gameCamera.getPos().z)+"\n";
|
||||||
str+= "Time: "+floatToStr(world.getTimeFlow()->getTime(),8)+"\n";
|
str+= "Time: "+floatToStr(world.getTimeFlow()->getTime(),8)+"\n";
|
||||||
str+= "Time Increment: "+floatToStr(world.getTimeFlow()->getTimeInc(),8)+"\n";
|
//str+= "Time Increment: "+floatToStr(world.getTimeFlow()->getTimeInc(),8)+"\n";
|
||||||
str+= "Triangle count: "+intToStr(renderer.getTriangleCount())+"\n";
|
str+= "Triangle count: "+intToStr(renderer.getTriangleCount())+"\n";
|
||||||
str+= "Vertex count: "+intToStr(renderer.getPointCount())+"\n";
|
str+= "Vertex count: "+intToStr(renderer.getPointCount())+"\n";
|
||||||
str+= "Frame count:"+intToStr(world.getFrameCount())+"\n";
|
str+= "Frame count:"+intToStr(world.getFrameCount())+"\n";
|
||||||
|
@@ -1099,21 +1099,15 @@ void MenuStateCustomGame::simpleTask() {
|
|||||||
if(publishToMasterserverThread == NULL || publishToMasterserverThread->getQuitStatus() == true || publishToMasterserverThread->getRunningStatus() == false) {
|
if(publishToMasterserverThread == NULL || publishToMasterserverThread->getQuitStatus() == true || publishToMasterserverThread->getRunningStatus() == false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
needToRepublishToMasterserver = false;
|
||||||
|
string newPublishToServerInfo = publishToServerInfo;
|
||||||
|
publishToServerInfo = "";
|
||||||
safeMutex.ReleaseLock(true);
|
safeMutex.ReleaseLock(true);
|
||||||
|
|
||||||
if(republish == true) {
|
if(republish == true) {
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
safeMutex.Lock();
|
string request = Config::getInstance().getString("Masterserver") + "addServerInfo.php?" + newPublishToServerInfo;
|
||||||
needToRepublishToMasterserver = false;
|
|
||||||
safeMutex.ReleaseLock(true);
|
|
||||||
|
|
||||||
string request = Config::getInstance().getString("Masterserver") + "addServerInfo.php?" + publishToServerInfo;
|
|
||||||
|
|
||||||
safeMutex.Lock();
|
|
||||||
publishToServerInfo = "";
|
|
||||||
safeMutex.ReleaseLock(true);
|
|
||||||
|
|
||||||
//printf("the request is:\n%s\n",request.c_str());
|
//printf("the request is:\n%s\n",request.c_str());
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] the request is:\n%s\n",__FILE__,__FUNCTION__,__LINE__,request.c_str());
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] the request is:\n%s\n",__FILE__,__FUNCTION__,__LINE__,request.c_str());
|
||||||
@@ -1125,10 +1119,10 @@ void MenuStateCustomGame::simpleTask() {
|
|||||||
std::string serverInfo = SystemFlags::getHTTP(request);
|
std::string serverInfo = SystemFlags::getHTTP(request);
|
||||||
//printf("the result is:\n'%s'\n",serverInfo.c_str());
|
//printf("the result is:\n'%s'\n",serverInfo.c_str());
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] the result is:\n'%s'\n",__FILE__,__FUNCTION__,__LINE__,serverInfo.c_str());
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d] the result is:\n'%s'\n",__FILE__,__FUNCTION__,__LINE__,serverInfo.c_str());
|
||||||
|
|
||||||
// uncomment to enable router setup check of this server
|
// uncomment to enable router setup check of this server
|
||||||
//if(serverInfo!="OK")
|
//if(serverInfo!="OK")
|
||||||
if(EndsWith(serverInfo, "OK") == false)
|
if(EndsWith(serverInfo, "OK") == false) {
|
||||||
{
|
|
||||||
safeMutex.Lock();
|
safeMutex.Lock();
|
||||||
showMasterserverError=true;
|
showMasterserverError=true;
|
||||||
masterServererErrorToShow=serverInfo;
|
masterServererErrorToShow=serverInfo;
|
||||||
@@ -1140,24 +1134,21 @@ void MenuStateCustomGame::simpleTask() {
|
|||||||
|
|
||||||
safeMutex.Lock();
|
safeMutex.Lock();
|
||||||
bool broadCastSettings = needToBroadcastServerSettings;
|
bool broadCastSettings = needToBroadcastServerSettings;
|
||||||
|
|
||||||
if(publishToMasterserverThread == NULL || publishToMasterserverThread->getQuitStatus() == true || publishToMasterserverThread->getRunningStatus() == false) {
|
if(publishToMasterserverThread == NULL || publishToMasterserverThread->getQuitStatus() == true || publishToMasterserverThread->getRunningStatus() == false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
needToBroadcastServerSettings=false;
|
||||||
safeMutex.ReleaseLock(true);
|
safeMutex.ReleaseLock(true);
|
||||||
|
|
||||||
if(broadCastSettings)
|
if(broadCastSettings) {
|
||||||
{
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
safeMutex.Lock();
|
|
||||||
needToBroadcastServerSettings=false;
|
|
||||||
safeMutex.ReleaseLock(true);
|
|
||||||
|
|
||||||
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
|
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
if(serverInterface->hasClientConnection() == true) {
|
if(serverInterface->hasClientConnection() == true) {
|
||||||
//printf("Sending game settings broadcast since we have at least 1 client connected'\n");
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
if(publishToMasterserverThread == NULL || publishToMasterserverThread->getQuitStatus() == true || publishToMasterserverThread->getRunningStatus() == false) {
|
if(publishToMasterserverThread == NULL || publishToMasterserverThread->getQuitStatus() == true || publishToMasterserverThread->getRunningStatus() == false) {
|
||||||
return;
|
return;
|
||||||
@@ -1170,6 +1161,8 @@ void MenuStateCustomGame::simpleTask() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
serverInterface->setGameSettings(&gameSettings);
|
serverInterface->setGameSettings(&gameSettings);
|
||||||
serverInterface->broadcastGameSetup(&gameSettings);
|
serverInterface->broadcastGameSetup(&gameSettings);
|
||||||
}
|
}
|
||||||
|
@@ -37,6 +37,7 @@ namespace Glest{ namespace Game{
|
|||||||
|
|
||||||
const int ClientInterface::messageWaitTimeout= 10000; //10 seconds
|
const int ClientInterface::messageWaitTimeout= 10000; //10 seconds
|
||||||
const int ClientInterface::waitSleepTime= 10;
|
const int ClientInterface::waitSleepTime= 10;
|
||||||
|
const int ClientInterface::maxNetworkCommandListSendTimeWait = 5;
|
||||||
|
|
||||||
ClientInterface::ClientInterface(){
|
ClientInterface::ClientInterface(){
|
||||||
clientSocket= NULL;
|
clientSocket= NULL;
|
||||||
@@ -45,6 +46,8 @@ ClientInterface::ClientInterface(){
|
|||||||
playerIndex= -1;
|
playerIndex= -1;
|
||||||
gameSettingsReceived=false;
|
gameSettingsReceived=false;
|
||||||
gotIntro = false;
|
gotIntro = false;
|
||||||
|
lastNetworkCommandListSendTime = 0;
|
||||||
|
currentFrameCount = 0;
|
||||||
|
|
||||||
networkGameDataSynchCheckOkMap = false;
|
networkGameDataSynchCheckOkMap = false;
|
||||||
networkGameDataSynchCheckOkTile = false;
|
networkGameDataSynchCheckOkTile = false;
|
||||||
@@ -96,7 +99,7 @@ void ClientInterface::reset()
|
|||||||
|
|
||||||
void ClientInterface::update()
|
void ClientInterface::update()
|
||||||
{
|
{
|
||||||
NetworkMessageCommandList networkMessageCommandList;
|
NetworkMessageCommandList networkMessageCommandList(currentFrameCount);
|
||||||
|
|
||||||
//send as many commands as we can
|
//send as many commands as we can
|
||||||
while(!requestedCommands.empty()){
|
while(!requestedCommands.empty()){
|
||||||
@@ -107,15 +110,20 @@ void ClientInterface::update()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(networkMessageCommandList.getCommandCount()>0){
|
|
||||||
|
int lastSendElapsed = difftime(time(NULL),lastNetworkCommandListSendTime);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] lastSendElapsed = %d\n",__FILE__,__FUNCTION__,__LINE__,lastSendElapsed);
|
||||||
|
|
||||||
|
if(networkMessageCommandList.getCommandCount() > 0 || lastSendElapsed >= ClientInterface::maxNetworkCommandListSendTimeWait) {
|
||||||
sendMessage(&networkMessageCommandList);
|
sendMessage(&networkMessageCommandList);
|
||||||
|
lastNetworkCommandListSendTime = time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Possible cause of out of synch since we have more commands that need
|
// Possible cause of out of synch since we have more commands that need
|
||||||
// to be sent in this frame
|
// to be sent in this frame
|
||||||
if(!requestedCommands.empty()) {
|
if(!requestedCommands.empty()) {
|
||||||
char szBuf[1024]="";
|
char szBuf[1024]="";
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING / ERROR, requestedCommands.size() = %d\n",__FILE__,__FUNCTION__,requestedCommands.size());
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING / ERROR, requestedCommands.size() = %d\n",__FILE__,__FUNCTION__,__LINE__,requestedCommands.size());
|
||||||
|
|
||||||
string sMsg = Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str()) + " may go out of synch: client requestedCommands.size() = " + intToStr(requestedCommands.size());
|
string sMsg = Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str()) + " may go out of synch: client requestedCommands.size() = " + intToStr(requestedCommands.size());
|
||||||
sendTextMessage(sMsg,-1);
|
sendTextMessage(sMsg,-1);
|
||||||
@@ -440,6 +448,8 @@ void ClientInterface::updateLobby()
|
|||||||
|
|
||||||
void ClientInterface::updateKeyframe(int frameCount)
|
void ClientInterface::updateKeyframe(int frameCount)
|
||||||
{
|
{
|
||||||
|
currentFrameCount = frameCount;
|
||||||
|
|
||||||
bool done= false;
|
bool done= false;
|
||||||
|
|
||||||
while(done == false) {
|
while(done == false) {
|
||||||
|
@@ -33,6 +33,7 @@ class ClientInterface: public GameNetworkInterface{
|
|||||||
private:
|
private:
|
||||||
static const int messageWaitTimeout;
|
static const int messageWaitTimeout;
|
||||||
static const int waitSleepTime;
|
static const int waitSleepTime;
|
||||||
|
static const int maxNetworkCommandListSendTimeWait;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ClientSocket *clientSocket;
|
ClientSocket *clientSocket;
|
||||||
@@ -48,6 +49,9 @@ private:
|
|||||||
Ip ip;
|
Ip ip;
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
|
int currentFrameCount;
|
||||||
|
time_t lastNetworkCommandListSendTime;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ClientInterface();
|
ClientInterface();
|
||||||
virtual ~ClientInterface();
|
virtual ~ClientInterface();
|
||||||
@@ -88,6 +92,8 @@ public:
|
|||||||
virtual bool getConnectHasHandshaked() const { return gotIntro; }
|
virtual bool getConnectHasHandshaked() const { return gotIntro; }
|
||||||
std::string getServerIpAddress();
|
std::string getServerIpAddress();
|
||||||
|
|
||||||
|
int getCurrentFrameCount() const { return currentFrameCount; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
Mutex * getServerSynchAccessor() { return NULL; }
|
Mutex * getServerSynchAccessor() { return NULL; }
|
||||||
|
@@ -152,6 +152,9 @@ ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex
|
|||||||
|
|
||||||
this->serverInterface = serverInterface;
|
this->serverInterface = serverInterface;
|
||||||
this->playerIndex = playerIndex;
|
this->playerIndex = playerIndex;
|
||||||
|
this->currentFrameCount = 0;
|
||||||
|
this->currentLagCount = 0;
|
||||||
|
this->lastReceiveCommandListTime = 0;
|
||||||
this->socket = NULL;
|
this->socket = NULL;
|
||||||
this->slotThreadWorker = NULL;
|
this->slotThreadWorker = NULL;
|
||||||
this->slotThreadWorker = new ConnectionSlotThread(this->serverInterface);
|
this->slotThreadWorker = new ConnectionSlotThread(this->serverInterface);
|
||||||
@@ -274,6 +277,10 @@ void ConnectionSlot::update(bool checkForNewClients) {
|
|||||||
|
|
||||||
NetworkMessageCommandList networkMessageCommandList;
|
NetworkMessageCommandList networkMessageCommandList;
|
||||||
if(receiveMessage(&networkMessageCommandList)) {
|
if(receiveMessage(&networkMessageCommandList)) {
|
||||||
|
currentFrameCount = networkMessageCommandList.getFrameCount();
|
||||||
|
lastReceiveCommandListTime = time(NULL);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,currentFrameCount);
|
||||||
|
|
||||||
for(int i= 0; i<networkMessageCommandList.getCommandCount(); ++i) {
|
for(int i= 0; i<networkMessageCommandList.getCommandCount(); ++i) {
|
||||||
//serverInterface->requestCommand(networkMessageCommandList.getCommand(i));
|
//serverInterface->requestCommand(networkMessageCommandList.getCommand(i));
|
||||||
vctPendingNetworkCommandList.push_back(*networkMessageCommandList.getCommand(i));
|
vctPendingNetworkCommandList.push_back(*networkMessageCommandList.getCommand(i));
|
||||||
|
@@ -104,6 +104,9 @@ private:
|
|||||||
bool gotIntro;
|
bool gotIntro;
|
||||||
vector<NetworkCommand> vctPendingNetworkCommandList;
|
vector<NetworkCommand> vctPendingNetworkCommandList;
|
||||||
ConnectionSlotThread* slotThreadWorker;
|
ConnectionSlotThread* slotThreadWorker;
|
||||||
|
int currentFrameCount;
|
||||||
|
int currentLagCount;
|
||||||
|
time_t lastReceiveCommandListTime;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ConnectionSlot(ServerInterface* serverInterface, int playerIndex);
|
ConnectionSlot(ServerInterface* serverInterface, int playerIndex);
|
||||||
@@ -139,6 +142,12 @@ public:
|
|||||||
bool updateCompleted();
|
bool updateCompleted();
|
||||||
|
|
||||||
virtual void sendMessage(const NetworkMessage* networkMessage);
|
virtual void sendMessage(const NetworkMessage* networkMessage);
|
||||||
|
int getCurrentFrameCount() const { return currentFrameCount; }
|
||||||
|
|
||||||
|
int getCurrentLagCount() const { return currentLagCount; }
|
||||||
|
void setCurrentLagCount(int value) { currentLagCount = value; }
|
||||||
|
|
||||||
|
time_t getLastReceiveCommandListTime() const { return lastReceiveCommandListTime; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@@ -38,12 +38,17 @@ namespace Glest{ namespace Game{
|
|||||||
//bool enabledThreadedClientCommandBroadcast = true;
|
//bool enabledThreadedClientCommandBroadcast = true;
|
||||||
bool enabledThreadedClientCommandBroadcast = false;
|
bool enabledThreadedClientCommandBroadcast = false;
|
||||||
|
|
||||||
|
// The maximum amount of network update iterations a client is allowed to fall behind
|
||||||
|
int maxFrameCountLagAllowed = 10;
|
||||||
|
|
||||||
ServerInterface::ServerInterface(){
|
ServerInterface::ServerInterface(){
|
||||||
gameHasBeenInitiated = false;
|
gameHasBeenInitiated = false;
|
||||||
gameSettingsUpdateCount = 0;
|
gameSettingsUpdateCount = 0;
|
||||||
|
currentFrameCount = 0;
|
||||||
|
|
||||||
enabledThreadedClientCommandBroadcast = Config::getInstance().getBool("EnableThreadedClientCommandBroadcast","false");
|
enabledThreadedClientCommandBroadcast = Config::getInstance().getBool("EnableThreadedClientCommandBroadcast","false");
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] enabledThreadedClientCommandBroadcast = %d\n",__FILE__,__FUNCTION__,__LINE__,enabledThreadedClientCommandBroadcast);
|
maxFrameCountLagAllowed = Config::getInstance().getInt("MaxFrameCountLagAllowed",intToStr(maxFrameCountLagAllowed).c_str());
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] enabledThreadedClientCommandBroadcast = %d, maxFrameCountLagAllowed = %d\n",__FILE__,__FUNCTION__,__LINE__,enabledThreadedClientCommandBroadcast,maxFrameCountLagAllowed);
|
||||||
|
|
||||||
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
for(int i= 0; i<GameConstants::maxPlayers; ++i){
|
||||||
slots[i]= NULL;
|
slots[i]= NULL;
|
||||||
@@ -199,6 +204,35 @@ void ServerInterface::updateSlot(ConnectionSlotEvent *event) {
|
|||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only call when client has just sent us data
|
||||||
|
bool ServerInterface::clientLagCheck(ConnectionSlot* connectionSlot) {
|
||||||
|
bool clientLagExceeded = false;
|
||||||
|
if(connectionSlot != NULL && connectionSlot->isConnected() == true) {
|
||||||
|
int clientLag = this->getCurrentFrameCount() - connectionSlot->getCurrentFrameCount();
|
||||||
|
int clientLagCount = (gameSettings.getNetworkFramePeriod() > 0 ? (clientLag / gameSettings.getNetworkFramePeriod()) : 0);
|
||||||
|
connectionSlot->setCurrentLagCount(clientLagCount);
|
||||||
|
|
||||||
|
if(this->getCurrentFrameCount() > 0) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d, clientLag = %d, clientLagCount = %d, this->getCurrentFrameCount() = %d, connectionSlot->getCurrentFrameCount() = %d\n",__FILE__,__FUNCTION__,__LINE__,connectionSlot->getPlayerIndex(),clientLag,clientLagCount,this->getCurrentFrameCount(),connectionSlot->getCurrentFrameCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
// New lag check
|
||||||
|
if(maxFrameCountLagAllowed > 0 && clientLagCount > maxFrameCountLagAllowed) {
|
||||||
|
clientLagExceeded = true;
|
||||||
|
char szBuf[4096]="";
|
||||||
|
snprintf(szBuf,4095,"%s exceeded max allowed LAG count of %d, clientLag = %d, disconnecting client.",Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str()).c_str(),maxFrameCountLagAllowed,clientLagCount);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,szBuf);
|
||||||
|
|
||||||
|
string sMsg = szBuf;
|
||||||
|
sendTextMessage(sMsg,-1);
|
||||||
|
|
||||||
|
connectionSlot->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return clientLagExceeded;
|
||||||
|
}
|
||||||
|
|
||||||
void ServerInterface::update() {
|
void ServerInterface::update() {
|
||||||
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
@@ -328,15 +362,23 @@ void ServerInterface::update() {
|
|||||||
// Step #3 dispatch network commands to the pending list so that they are done in proper order
|
// Step #3 dispatch network commands to the pending list so that they are done in proper order
|
||||||
for(int i= 0; i< GameConstants::maxPlayers; ++i) {
|
for(int i= 0; i< GameConstants::maxPlayers; ++i) {
|
||||||
ConnectionSlot* connectionSlot= slots[i];
|
ConnectionSlot* connectionSlot= slots[i];
|
||||||
if(connectionSlot != NULL && connectionSlot->isConnected() == true &&
|
if(connectionSlot != NULL && connectionSlot->isConnected() == true) {
|
||||||
connectionSlot->getPendingNetworkCommandList().size() > 0) {
|
if(connectionSlot->getPendingNetworkCommandList().size() > 0) {
|
||||||
vector<NetworkCommand> vctPendingNetworkCommandList = connectionSlot->getPendingNetworkCommandList();
|
// New lag check
|
||||||
|
bool clientLagExceeded = clientLagCheck(connectionSlot);
|
||||||
|
if(clientLagExceeded) {
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] slotIndex = %d, clientLagExceeded = %d\n",__FILE__,__FUNCTION__,__LINE__,i,clientLagExceeded);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vector<NetworkCommand> vctPendingNetworkCommandList = connectionSlot->getPendingNetworkCommandList();
|
||||||
|
|
||||||
for(int idx = 0; idx < vctPendingNetworkCommandList.size(); ++idx) {
|
for(int idx = 0; idx < vctPendingNetworkCommandList.size(); ++idx) {
|
||||||
NetworkCommand &cmd = vctPendingNetworkCommandList[idx];
|
NetworkCommand &cmd = vctPendingNetworkCommandList[idx];
|
||||||
this->requestCommand(&cmd);
|
this->requestCommand(&cmd);
|
||||||
|
}
|
||||||
|
connectionSlot->clearPendingNetworkCommandList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
connectionSlot->clearPendingNetworkCommandList();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,6 +456,9 @@ void ServerInterface::updateKeyframe(int frameCount){
|
|||||||
Chrono chrono;
|
Chrono chrono;
|
||||||
chrono.start();
|
chrono.start();
|
||||||
|
|
||||||
|
currentFrameCount = frameCount;
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] currentFrameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,currentFrameCount);
|
||||||
|
|
||||||
NetworkMessageCommandList networkMessageCommandList(frameCount);
|
NetworkMessageCommandList networkMessageCommandList(frameCount);
|
||||||
|
|
||||||
//build command list, remove commands from requested and add to pending
|
//build command list, remove commands from requested and add to pending
|
||||||
@@ -649,10 +694,11 @@ string ServerInterface::getNetworkStatus() {
|
|||||||
|
|
||||||
if(connectionSlot!= NULL){
|
if(connectionSlot!= NULL){
|
||||||
if(connectionSlot->isConnected()){
|
if(connectionSlot->isConnected()){
|
||||||
|
int clientLagCount = connectionSlot->getCurrentLagCount();
|
||||||
|
int lastClientCommandListTimeLag = difftime(time(NULL),connectionSlot->getLastReceiveCommandListTime());
|
||||||
float pingTime = connectionSlot->getThreadedPingMS(connectionSlot->getIpAddress().c_str());
|
float pingTime = connectionSlot->getThreadedPingMS(connectionSlot->getIpAddress().c_str());
|
||||||
char szBuf[100]="";
|
char szBuf[100]="";
|
||||||
sprintf(szBuf,", ping = %.2fms",pingTime);
|
sprintf(szBuf,", lag = %d [%d], ping = %.2fms",clientLagCount,lastClientCommandListTimeLag,pingTime);
|
||||||
|
|
||||||
str+= connectionSlot->getName() + string(szBuf);
|
str+= connectionSlot->getName() + string(szBuf);
|
||||||
}
|
}
|
||||||
|
@@ -37,6 +37,7 @@ private:
|
|||||||
int gameSettingsUpdateCount;
|
int gameSettingsUpdateCount;
|
||||||
SwitchSetupRequest* switchSetupRequests[GameConstants::maxPlayers];
|
SwitchSetupRequest* switchSetupRequests[GameConstants::maxPlayers];
|
||||||
Mutex serverSynchAccessor;
|
Mutex serverSynchAccessor;
|
||||||
|
int currentFrameCount;
|
||||||
|
|
||||||
//ConnectionSlotThread* slotThreads[GameConstants::maxPlayers];
|
//ConnectionSlotThread* slotThreads[GameConstants::maxPlayers];
|
||||||
|
|
||||||
@@ -78,6 +79,8 @@ public:
|
|||||||
|
|
||||||
virtual void slotUpdateTask(ConnectionSlotEvent *event);
|
virtual void slotUpdateTask(ConnectionSlotEvent *event);
|
||||||
bool hasClientConnection();
|
bool hasClientConnection();
|
||||||
|
int getCurrentFrameCount() const { return currentFrameCount; }
|
||||||
|
bool clientLagCheck(ConnectionSlot* connectionSlot);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@@ -1356,6 +1356,9 @@ BroadCastClientSocketThread::BroadCastClientSocketThread(DiscoveredServersInterf
|
|||||||
void BroadCastClientSocketThread::execute() {
|
void BroadCastClientSocketThread::execute() {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
setRunningStatus(true);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast Client thread is running\n");
|
||||||
|
|
||||||
std::vector<string> foundServers;
|
std::vector<string> foundServers;
|
||||||
|
|
||||||
short port; // The port for the broadcast.
|
short port; // The port for the broadcast.
|
||||||
@@ -1396,9 +1399,6 @@ void BroadCastClientSocketThread::execute() {
|
|||||||
|
|
||||||
Socket::setBlock(false, bcfd);
|
Socket::setBlock(false, bcfd);
|
||||||
|
|
||||||
setRunningStatus(true);
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast Client thread is running\n");
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Keep getting packets forever.
|
// Keep getting packets forever.
|
||||||
@@ -1436,15 +1436,12 @@ void BroadCastClientSocketThread::execute() {
|
|||||||
}
|
}
|
||||||
catch(const exception &ex) {
|
catch(const exception &ex) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
||||||
setRunningStatus(false);
|
//setRunningStatus(false);
|
||||||
}
|
}
|
||||||
catch(...) {
|
catch(...) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
setRunningStatus(false);
|
//setRunningStatus(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
setRunningStatus(false);
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast Client thread is exiting\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
@@ -1459,10 +1456,14 @@ void BroadCastClientSocketThread::execute() {
|
|||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
setRunningStatus(false);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast Client thread is exiting\n");
|
||||||
|
|
||||||
// Here we callback into the implementer class
|
// Here we callback into the implementer class
|
||||||
if(discoveredServersCB != NULL) {
|
if(discoveredServersCB != NULL) {
|
||||||
discoveredServersCB->DiscoveredServers(foundServers);
|
discoveredServersCB->DiscoveredServers(foundServers);
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1642,6 +1643,9 @@ void BroadCastSocketThread::execute() {
|
|||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
|
setRunningStatus(true);
|
||||||
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is running\n");
|
||||||
|
|
||||||
const int MAX_NIC_COUNT = 10;
|
const int MAX_NIC_COUNT = 10;
|
||||||
short port; // The port for the broadcast.
|
short port; // The port for the broadcast.
|
||||||
struct sockaddr_in bcLocal[MAX_NIC_COUNT]; // local socket address for the broadcast.
|
struct sockaddr_in bcLocal[MAX_NIC_COUNT]; // local socket address for the broadcast.
|
||||||
@@ -1652,8 +1656,6 @@ void BroadCastSocketThread::execute() {
|
|||||||
char myhostname[100]; // hostname of local machine
|
char myhostname[100]; // hostname of local machine
|
||||||
char subnetmask[MAX_NIC_COUNT][100]; // Subnet mask to broadcast to
|
char subnetmask[MAX_NIC_COUNT][100]; // Subnet mask to broadcast to
|
||||||
struct hostent* myhostent;
|
struct hostent* myhostent;
|
||||||
//char * ptr; // some transient vars
|
|
||||||
//int len,i;
|
|
||||||
|
|
||||||
/* get my host name */
|
/* get my host name */
|
||||||
gethostname(myhostname,100);
|
gethostname(myhostname,100);
|
||||||
@@ -1696,9 +1698,6 @@ void BroadCastSocketThread::execute() {
|
|||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] setting up broadcast on address [%s]\n",__FILE__,__FUNCTION__,__LINE__,subnetmask[idx]);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] setting up broadcast on address [%s]\n",__FILE__,__FUNCTION__,__LINE__,subnetmask[idx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
setRunningStatus(true);
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is running\n");
|
|
||||||
|
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
|
|
||||||
time_t elapsed = 0;
|
time_t elapsed = 0;
|
||||||
@@ -1740,11 +1739,11 @@ void BroadCastSocketThread::execute() {
|
|||||||
}
|
}
|
||||||
catch(const exception &ex) {
|
catch(const exception &ex) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what());
|
||||||
setRunningStatus(false);
|
//setRunningStatus(false);
|
||||||
}
|
}
|
||||||
catch(...) {
|
catch(...) {
|
||||||
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__);
|
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__);
|
||||||
setRunningStatus(false);
|
//setRunningStatus(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user