- fixed an evil socket bug! Sockets in Linux were NOT properly set as non blocking and vice versa as expected. PErhaps this helps with the menu bug

This commit is contained in:
Mark Vejvoda 2010-12-18 23:03:53 +00:00
parent eb17a1c052
commit a844b79d3e
5 changed files with 106 additions and 98 deletions

View File

@ -1075,10 +1075,9 @@ void MenuStateCustomGame::PlayNow() {
if(listBoxControls[i].getSelectedItemIndex() == ctNetwork) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
ConnectionSlot* connectionSlot= serverInterface->getSlot(i);
if( connectionSlot != NULL && connectionSlot->isConnected() &&
connectionSlot->getAllowGameDataSynchCheck() == true &&
connectionSlot->getNetworkGameDataSynchCheckOk() == false) {
if( serverInterface->getSlot(i) != NULL && serverInterface->getSlot(i)->isConnected() &&
serverInterface->getSlot(i)->getAllowGameDataSynchCheck() == true &&
serverInterface->getSlot(i)->getNetworkGameDataSynchCheckOk() == false) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
dataSynchCheckOk = false;
break;
@ -1515,68 +1514,53 @@ void MenuStateCustomGame::update() {
if(listBoxControls[i].getSelectedItemIndex() == ctNetwork) {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
ConnectionSlot* connectionSlot= serverInterface->getSlot(i);
//assert(connectionSlot!=NULL);
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line %d]\n",__FILE__,__FUNCTION__,__LINE__);
hasOneNetworkSlotOpen=true;
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] A - ctNetwork\n",__FILE__,__FUNCTION__);
if(connectionSlot != NULL && connectionSlot->isConnected()) {
connectionSlot->setName(labelPlayerNames[i].getText());
if(serverInterface->getSlot(i) != NULL &&
serverInterface->getSlot(i)->isConnected()) {
serverInterface->getSlot(i)->setName(labelPlayerNames[i].getText());
//printf("FYI we have at least 1 client connected, slot = %d'\n",i);
haveAtLeastOneNetworkClientConnected = true;
if(connectionSlot->getConnectHasHandshaked())
if(serverInterface->getSlot(i) != NULL &&
serverInterface->getSlot(i)->getConnectHasHandshaked()) {
currentConnectionCount++;
}
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] B - ctNetwork\n",__FILE__,__FUNCTION__);
string label = (serverInterface->getSlot(i) != NULL ? serverInterface->getSlot(i)->getVersionString() : "");
//string label = connectionSlot->getName() + ", " + connectionSlot->getVersionString();
string label = connectionSlot->getVersionString();
if(connectionSlot != NULL &&
connectionSlot->getAllowDownloadDataSynch() == true &&
connectionSlot->getAllowGameDataSynchCheck() == true)
{
if(connectionSlot->getNetworkGameDataSynchCheckOk() == false)
{
if(serverInterface->getSlot(i) != NULL &&
serverInterface->getSlot(i)->getAllowDownloadDataSynch() == true &&
serverInterface->getSlot(i)->getAllowGameDataSynchCheck() == true) {
if(serverInterface->getSlot(i)->getNetworkGameDataSynchCheckOk() == false) {
label += " -waiting to synch:";
if(connectionSlot->getNetworkGameDataSynchCheckOkMap() == false)
{
if(serverInterface->getSlot(i)->getNetworkGameDataSynchCheckOkMap() == false) {
label = label + " map";
}
if(connectionSlot->getNetworkGameDataSynchCheckOkTile() == false)
{
if(serverInterface->getSlot(i)->getNetworkGameDataSynchCheckOkTile() == false) {
label = label + " tile";
}
if(connectionSlot->getNetworkGameDataSynchCheckOkTech() == false)
{
if(serverInterface->getSlot(i)->getNetworkGameDataSynchCheckOkTech() == false) {
label = label + " techtree";
}
}
else
{
else {
label += " - data synch is ok";
}
}
else
{
//label = connectionSlot->getName();
connectionSlot= serverInterface->getSlot(i);
if(connectionSlot != NULL &&
connectionSlot->getAllowGameDataSynchCheck() == true &&
connectionSlot->getNetworkGameDataSynchCheckOk() == false)
{
else {
if(serverInterface->getSlot(i) != NULL &&
serverInterface->getSlot(i)->getAllowGameDataSynchCheck() == true &&
serverInterface->getSlot(i)->getNetworkGameDataSynchCheckOk() == false) {
label += " -synch mismatch:";
connectionSlot= serverInterface->getSlot(i);
if(connectionSlot != NULL && connectionSlot->getNetworkGameDataSynchCheckOkMap() == false) {
if(serverInterface->getSlot(i) != NULL && serverInterface->getSlot(i)->getNetworkGameDataSynchCheckOkMap() == false) {
label = label + " map";
if(connectionSlot->getReceivedDataSynchCheck() == true &&
if(serverInterface->getSlot(i)->getReceivedDataSynchCheck() == true &&
lastMapDataSynchError != "map CRC mismatch, " + listBoxMap.getSelectedItem()) {
lastMapDataSynchError = "map CRC mismatch, " + listBoxMap.getSelectedItem();
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
@ -1584,11 +1568,11 @@ void MenuStateCustomGame::update() {
}
}
connectionSlot= serverInterface->getSlot(i);
if(connectionSlot != NULL && connectionSlot->getNetworkGameDataSynchCheckOkTile() == false) {
if(serverInterface->getSlot(i) != NULL &&
serverInterface->getSlot(i)->getNetworkGameDataSynchCheckOkTile() == false) {
label = label + " tile";
if(connectionSlot->getReceivedDataSynchCheck() == true &&
if(serverInterface->getSlot(i)->getReceivedDataSynchCheck() == true &&
lastTileDataSynchError != "tile CRC mismatch, " + listBoxTileset.getSelectedItem()) {
lastTileDataSynchError = "tile CRC mismatch, " + listBoxTileset.getSelectedItem();
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
@ -1596,14 +1580,13 @@ void MenuStateCustomGame::update() {
}
}
connectionSlot= serverInterface->getSlot(i);
if(connectionSlot != NULL && connectionSlot->getNetworkGameDataSynchCheckOkTech() == false)
{
if(serverInterface->getSlot(i) != NULL &&
serverInterface->getSlot(i)->getNetworkGameDataSynchCheckOkTech() == false) {
label = label + " techtree";
if(connectionSlot->getReceivedDataSynchCheck() == true) {
if(serverInterface->getSlot(i)->getReceivedDataSynchCheck() == true) {
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
string report = connectionSlot->getNetworkGameDataSynchCheckTechMismatchReport();
string report = serverInterface->getSlot(i)->getNetworkGameDataSynchCheckTechMismatchReport();
if(lastTechtreeDataSynchError != "techtree CRC mismatch" + report) {
lastTechtreeDataSynchError = "techtree CRC mismatch" + report;
@ -1620,22 +1603,20 @@ void MenuStateCustomGame::update() {
}
}
connectionSlot= serverInterface->getSlot(i);
if(connectionSlot != NULL) {
connectionSlot->setReceivedDataSynchCheck(false);
if(serverInterface->getSlot(i) != NULL) {
serverInterface->getSlot(i)->setReceivedDataSynchCheck(false);
}
}
}
//float pingTime = connectionSlot->getThreadedPingMS(connectionSlot->getIpAddress().c_str());
//float pingTime = serverInterface->getSlot(i)->getThreadedPingMS(serverInterface->getSlot(i)->getIpAddress().c_str());
char szBuf[1024]="";
//sprintf(szBuf,"%s, ping = %.2fms",label.c_str(),pingTime);
sprintf(szBuf,"%s",label.c_str());
labelNetStatus[i].setText(szBuf);
}
else
{
else {
//SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] C - ctNetwork\n",__FILE__,__FUNCTION__);
string port = intToStr(config.getInt("ServerPort"));
if(port != intToStr(GameConstants::serverPort)){
@ -1821,14 +1802,12 @@ void MenuStateCustomGame::publishToMasterserver()
if(listBoxControls[i].getSelectedItemIndex() == ctNetwork)
{
slotCountHumans++;
ConnectionSlot* connectionSlot= serverInterface->getSlot(i);
if((connectionSlot!=NULL) && (connectionSlot->isConnected()))
{
if(serverInterface->getSlot(i) != NULL &&
serverInterface->getSlot(i)->isConnected()) {
slotCountConnectedPlayers++;
}
}
else if(listBoxControls[i].getSelectedItemIndex() == ctHuman)
{
else if(listBoxControls[i].getSelectedItemIndex() == ctHuman) {
slotCountHumans++;
slotCountConnectedPlayers++;
}
@ -2046,12 +2025,12 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings) {
if(listBoxControls[i].getSelectedItemIndex() == ctNetwork) {
ConnectionSlot* connectionSlot= serverInterface->getSlot(i);
if(connectionSlot != NULL && connectionSlot->isConnected()) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, connectionSlot->getName() [%s]\n",__FILE__,__FUNCTION__,__LINE__,i,connectionSlot->getName().c_str());
if(serverInterface->getSlot(i) != NULL &&
serverInterface->getSlot(i)->isConnected()) {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, connectionSlot->getName() [%s]\n",__FILE__,__FUNCTION__,__LINE__,i,serverInterface->getSlot(i)->getName().c_str());
gameSettings->setNetworkPlayerName(slotIndex, connectionSlot->getName());
labelPlayerNames[i].setText(connectionSlot->getName());
gameSettings->setNetworkPlayerName(slotIndex, serverInterface->getSlot(i)->getName());
labelPlayerNames[i].setText(serverInterface->getSlot(i)->getName());
}
else {
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, playername unconnected\n",__FILE__,__FUNCTION__,__LINE__,i);
@ -2511,8 +2490,9 @@ void MenuStateCustomGame::closeUnusedSlots(){
try {
ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface();
for(int i= 0; i<mapInfo.players; ++i){
if(listBoxControls[i].getSelectedItemIndex()==ctNetwork){
if(!serverInterface->getSlot(i)->isConnected()){
if(listBoxControls[i].getSelectedItemIndex() == ctNetwork){
if(serverInterface->getSlot(i) == NULL ||
serverInterface->getSlot(i)->isConnected() == false) {
listBoxControls[i].setSelectedItemIndex(ctClosed);
}
}

View File

@ -223,16 +223,13 @@ void MenuStateJoinGame::mouseClick(int x, int y, MouseButton mouseButton)
}
//return
if(buttonReturn.mouseClick(x, y))
{
if(buttonReturn.mouseClick(x, y)) {
soundRenderer.playFx(coreData.getClickSoundA());
clientInterface->stopServerDiscovery();
if(clientInterface->getSocket() != NULL)
{
if(clientInterface->isConnected() == true)
{
if(clientInterface->getSocket() != NULL) {
if(clientInterface->isConnected() == true) {
string sQuitText = Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str()) + " has chosen to leave the game!";
clientInterface->sendTextMessage(sQuitText,-1);
}

View File

@ -37,7 +37,6 @@ protected:
string uniqueID;
bool hasBeginExecution;
virtual void setRunningStatus(bool value);
virtual void setQuitStatus(bool value);
public:
@ -57,6 +56,33 @@ public:
void setUniqueID(string value) { uniqueID = value; }
string getUniqueID() { return uniqueID; }
virtual void setRunningStatus(bool value);
};
class RunningStatusSafeWrapper {
protected:
BaseThread *thread;
public:
RunningStatusSafeWrapper(BaseThread *thread) {
this->thread = thread;
Enable();
}
~RunningStatusSafeWrapper() {
Disable();
}
void Enable() {
if(this->thread != NULL) {
this->thread->setRunningStatus(true);
}
}
void Disable() {
if(this->thread != NULL) {
this->thread->setRunningStatus(false);
}
}
};
}}//end namespace

View File

@ -137,10 +137,10 @@ bool BaseThread::shutdownAndWait() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
pThread->signalQuit();
//sleep(0);
sleep(0);
ret = false;
int maxWaitSeconds = 7;
int maxWaitSeconds = 5;
if(pThread->canShutdown() == false) {
maxWaitSeconds = 2;
}
@ -156,6 +156,7 @@ bool BaseThread::shutdownAndWait() {
}
//sleep(0);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] uniqueID [%s]\n",__FILE__,__FUNCTION__,__LINE__,uniqueID.c_str());
sleep(0);
}
}
//sleep(0);

View File

@ -1170,10 +1170,10 @@ void Socket::setBlock(bool block, PLATFORM_SOCKET socket){
#ifndef WIN32
int currentFlags = fcntl(socket, F_GETFL);
if(block == true) {
currentFlags |= O_NONBLOCK;
currentFlags &= (~O_NONBLOCK);
}
else {
currentFlags &= (~O_NONBLOCK);
currentFlags |= O_NONBLOCK;
}
int err= fcntl(socket, F_SETFL, currentFlags);
#else
@ -1356,6 +1356,7 @@ void ClientSocket::stopBroadCastClientThread() {
if(broadCastClientThread != NULL) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
broadCastClientThread->shutdownAndWait();
delete broadCastClientThread;
broadCastClientThread = NULL;
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
@ -1392,13 +1393,11 @@ void ClientSocket::connect(const Ip &ip, int port)
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Connecting to host [%s] on port = %d\n", ip.getString().c_str(),port);
int err= ::connect(sock, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
if(err < 0)
{
if(err < 0) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s\n",__FILE__,__FUNCTION__,ip.getString().c_str(),port,err,getLastSocketErrorFormattedText().c_str());
if (getLastSocketError() == PLATFORM_SOCKET_INPROGRESS ||
getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN)
{
getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) {
fd_set myset;
struct timeval tv;
int valopt;
@ -1406,8 +1405,7 @@ void ClientSocket::connect(const Ip &ip, int port)
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] PLATFORM_SOCKET_INPROGRESS in connect() - selecting\n",__FILE__,__FUNCTION__);
do
{
do {
tv.tv_sec = 10;
tv.tv_usec = 0;
@ -1501,8 +1499,9 @@ BroadCastClientSocketThread::BroadCastClientSocketThread(DiscoveredServersInterf
//
void BroadCastClientSocketThread::execute() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//setRunningStatus(true);
RunningStatusSafeWrapper runningStatus(this);
setRunningStatus(true);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast Client thread is running\n");
std::vector<string> foundServers;
@ -1545,14 +1544,17 @@ void BroadCastClientSocketThread::execute() {
Socket::setBlock(false, bcfd);
try
{
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
try {
// Keep getting packets forever.
for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 5; )
{
for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 5; ) {
alen = sizeof(struct sockaddr);
if( (nb = recvfrom(bcfd, buff, 10024, 0, (struct sockaddr *) &bcSender, &alen)) <= 0 )
{
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
bool gotData = (nb = recvfrom(bcfd, buff, 10024, 0, (struct sockaddr *) &bcSender, &alen)) > 0;
//SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] gotData = %d\n",__FILE__,__FUNCTION__,__LINE__,gotData);
if(gotData == false) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"recvfrom failed: %s\n", getLastSocketErrorFormattedText().c_str());
//exit(-1);
}
@ -1578,6 +1580,10 @@ void BroadCastClientSocketThread::execute() {
break;
}
sleep( 100 ); // send out broadcast every 1 seconds
if(getQuitStatus() == true) {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
break;
}
}
}
catch(const exception &ex) {
@ -1605,14 +1611,12 @@ void BroadCastClientSocketThread::execute() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
// Here we callback into the implementer class
if(discoveredServersCB != NULL) {
if(getQuitStatus() == false && discoveredServersCB != NULL) {
discoveredServersCB->DiscoveredServers(foundServers);
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast Client thread is exiting\n");
setRunningStatus(false);
//setRunningStatus(false);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
}
@ -1811,10 +1815,10 @@ BroadCastSocketThread::BroadCastSocketThread() : BaseThread() {
// the current broadcast message is <myhostname:my.ip.address.dotted>
//
void BroadCastSocketThread::execute() {
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
//setRunningStatus(true);
RunningStatusSafeWrapper runningStatus(this);
setRunningStatus(true);
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is running\n");
const int MAX_NIC_COUNT = 10;
@ -1951,7 +1955,7 @@ void BroadCastSocketThread::execute() {
}
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Broadcast thread is exiting\n",__FILE__,__FUNCTION__,__LINE__);
setRunningStatus(false);
//setRunningStatus(false);
}
double Socket::getAveragePingMS(std::string host, int pingCount) {