From 0bcb7106066bc456dff3a7bb0969a414211b998c Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Thu, 1 Apr 2010 06:31:10 +0000 Subject: [PATCH] Added auto-discovery of LAN servers using UDP broadcast. (for now the client must press the A key from the join menu to trigger this) --- .../menu/menu_state_custom_game.cpp | 1 - .../glest_game/menu/menu_state_join_game.cpp | 21 +- .../glest_game/network/client_interface.cpp | 11 + source/glest_game/network/client_interface.h | 4 +- .../glest_game/network/server_interface.cpp | 2 + .../include/platform/posix/socket.h | 40 +- .../include/platform/sdl/platform_util.h | 1 + .../include/platform/win32/platform_util.h | 3 +- .../include/platform/win32/socket.h | 5 + .../sources/platform/posix/socket.cpp | 384 ++++++++++++++++++ .../sources/platform/sdl/platform_util.cpp | 17 + .../sources/platform/win32/platform_util.cpp | 19 +- source/shared_lib/sources/util/util.cpp | 20 +- 13 files changed, 515 insertions(+), 13 deletions(-) diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index e584adba5..8a60bdb4f 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -232,7 +232,6 @@ void MenuStateCustomGame::mouseClick(int x, int y, MouseButton mouseButton){ bool bOkToStart = serverInterface->launchGame(&gameSettings); if(bOkToStart == true) { - program->setState(new Game(program, &gameSettings)); } } diff --git a/source/glest_game/menu/menu_state_join_game.cpp b/source/glest_game/menu/menu_state_join_game.cpp index 33a516355..1dc310ad9 100644 --- a/source/glest_game/menu/menu_state_join_game.cpp +++ b/source/glest_game/menu/menu_state_join_game.cpp @@ -336,11 +336,15 @@ void MenuStateJoinGame::update() } void MenuStateJoinGame::keyDown(char key){ - ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface(); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] key = [%c][%d]\n",__FILE__,__FUNCTION__,__LINE__,key,key); + + ClientInterface* clientInterface= NetworkManager::getInstance().getClientInterface(); if(!clientInterface->isConnected()) { - if(key==vkBack){ + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + if(key==vkBack) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); string text= labelServerIp.getText(); if(text.size()>1){ @@ -349,9 +353,22 @@ void MenuStateJoinGame::keyDown(char key){ labelServerIp.setText(text); } + else if(key== 'A') { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + std::vector serverList = clientInterface->discoverServers(); + if(serverList.size() > 0) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] serverList[0] = [%s]\n",__FILE__,__FUNCTION__,__LINE__,serverList[0].c_str()); + + labelServerIp.setText(serverList[0]); + connectToServer(); + } + } } else { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //send key to the chat manager chatManager.keyDown(key); } diff --git a/source/glest_game/network/client_interface.cpp b/source/glest_game/network/client_interface.cpp index 863a4ba4e..06e6cb33b 100755 --- a/source/glest_game/network/client_interface.cpp +++ b/source/glest_game/network/client_interface.cpp @@ -559,6 +559,17 @@ void ClientInterface::close() delete clientSocket; clientSocket= NULL; } + +std::vector ClientInterface::discoverServers() { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + std::vector serverList = ClientSocket::discoverServers(); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + return serverList; +} + /* bool ClientInterface::getFogOfWar() { diff --git a/source/glest_game/network/client_interface.h b/source/glest_game/network/client_interface.h index f42abbf01..920a4ab01 100644 --- a/source/glest_game/network/client_interface.h +++ b/source/glest_game/network/client_interface.h @@ -1,7 +1,7 @@ // ============================================================== // This file is part of Glest (www.glest.org) // -// Copyright (C) 2001-2008 Martiņo Figueroa +// Copyright (C) 2001-2008 Martio Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published @@ -76,6 +76,8 @@ public: void connect(const Ip &ip, int port); void reset(); + std::vector discoverServers(); + private: void waitForMessage(); }; diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index fb39710d3..d760ebd47 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -412,6 +412,8 @@ bool ServerInterface::launchGame(const GameSettings* gameSettings){ if(bOkToStart == true) { + serverSocket.stopBroadCastThread(); + NetworkMessageLaunch networkMessageLaunch(gameSettings); broadcastMessage(&networkMessageLaunch); } diff --git a/source/shared_lib/include/platform/posix/socket.h b/source/shared_lib/include/platform/posix/socket.h index f3373488b..3fc478fc5 100644 --- a/source/shared_lib/include/platform/posix/socket.h +++ b/source/shared_lib/include/platform/posix/socket.h @@ -23,6 +23,8 @@ #include #include #include +#include +#include "thread.h" using std::string; @@ -53,11 +55,16 @@ class Socket { protected: int sock; long lastDebugEvent; + static int broadcast_portno; public: Socket(int sock); Socket(); - ~Socket(); + virtual ~Socket(); + + static int getBroadCastPort() { return broadcast_portno; } + static void setBroadCastPort(int value) { broadcast_portno = value; } + static std::vector getLocalIPAddressList(); // Int lookup is socket fd while bool result is whether or not that socket was signalled for reading static bool hasDataToRead(std::map &socketTriggeredList); @@ -91,6 +98,28 @@ protected: class ClientSocket: public Socket{ public: void connect(const Ip &ip, int port); + + static std::vector discoverServers(); +}; + +class BroadCastSocketThread : public Thread +{ +private: + Mutex mutexRunning; + Mutex mutexQuit; + + bool quit; + bool running; + + void setRunningStatus(bool value); + void setQuitStatus(bool value); + +public: + BroadCastSocketThread(); + virtual void execute(); + void signalQuit(); + bool getQuitStatus(); + bool getRunningStatus(); }; // ===================================================== @@ -99,9 +128,18 @@ public: class ServerSocket: public Socket{ public: + ServerSocket(); + virtual ~ServerSocket(); void bind(int port); void listen(int connectionQueueSize= SOMAXCONN); Socket *accept(); + void stopBroadCastThread(); + +protected: + + BroadCastSocketThread *broadCastThread; + void startBroadCastThread(); + }; }}//end namespace diff --git a/source/shared_lib/include/platform/sdl/platform_util.h b/source/shared_lib/include/platform/sdl/platform_util.h index b08f52528..2854df7c8 100644 --- a/source/shared_lib/include/platform/sdl/platform_util.h +++ b/source/shared_lib/include/platform/sdl/platform_util.h @@ -108,6 +108,7 @@ public: // Misc // ===================================================== int MessageBox(int handle, const char *msg, const char *title, int buttons); +void Tokenize(const string& str,vector& tokens,const string& delimiters = " "); bool isdir(const char *path); void findDirs(const vector &paths, vector &results, bool errorOnNotFound=false); void findAll(const vector &paths, const string &fileFilter, vector &results, bool cutExtension=false, bool errorOnNotFound=true); diff --git a/source/shared_lib/include/platform/win32/platform_util.h b/source/shared_lib/include/platform/win32/platform_util.h index 8c36255c7..fd7557256 100755 --- a/source/shared_lib/include/platform/win32/platform_util.h +++ b/source/shared_lib/include/platform/win32/platform_util.h @@ -1,7 +1,7 @@ // ============================================================== // This file is part of Glest Shared Library (www.glest.org) // -// Copyright (C) 2001-2008 Martiņo Figueroa +// Copyright (C) 2001-2008 Martio Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published @@ -101,6 +101,7 @@ public: // ===================================================== // Misc // ===================================================== +void Tokenize(const string& str,vector& tokens,const string& delimiters = " "); bool isdir(const char *path); void findDirs(const vector &paths, vector &results, bool errorOnNotFound=false); void findAll(const vector &paths, const string &fileFilter, vector &results, bool cutExtension=false, bool errorOnNotFound=true); diff --git a/source/shared_lib/include/platform/win32/socket.h b/source/shared_lib/include/platform/win32/socket.h index dfd885b05..5a8fb67bb 100644 --- a/source/shared_lib/include/platform/win32/socket.h +++ b/source/shared_lib/include/platform/win32/socket.h @@ -103,10 +103,15 @@ public: // ===================================================== class ServerSocket: public Socket{ + public: void bind(int port); void listen(int connectionQueueSize= SOMAXCONN); Socket *accept(); + +protected: + + void broadcast_thread(); }; }}//end namespace diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index 2d765c7d6..227f8a732 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -21,14 +21,19 @@ #include #endif +#include + #include "conversion.h" #include "util.h" +#include "platform_util.h" using namespace std; using namespace Shared::Util; namespace Shared{ namespace Platform{ +int Socket::broadcast_portno = 61357; + // ===================================================== // class Ip // ===================================================== @@ -68,6 +73,50 @@ string Ip::getString() const{ // class Socket // =============================================== +std::vector Socket::getLocalIPAddressList() { + std::vector ipList; + + /* get my host name */ + char myhostname[101]=""; + gethostname(myhostname,100); + + struct hostent* myhostent = gethostbyname(myhostname); + + // get all host IP addresses (Except for loopback) + char myhostaddr[101] = ""; + int ipIdx = 0; + while (myhostent->h_addr_list[ipIdx] != 0) { + sprintf(myhostaddr, "%s",inet_ntoa(*(struct in_addr *)myhostent->h_addr_list[ipIdx])); + printf("%s\n",myhostaddr); + + if(strlen(myhostaddr) > 0 && strncmp(myhostaddr,"127.",4) != 0) { + ipList.push_back(myhostaddr); + } + ipIdx++; + } + + // Now check all linux network devices + int fd = socket(AF_INET, SOCK_DGRAM, 0); + + /* I want to get an IPv4 IP address */ + struct ifreq ifr; + ifr.ifr_addr.sa_family = AF_INET; + + /* I want IP address attached to "eth0" */ + strncpy(ifr.ifr_name, "eth1", IFNAMSIZ-1); + ioctl(fd, SIOCGIFADDR, &ifr); + close(fd); + + sprintf(myhostaddr, "%s",inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr)); + printf("%s\n",myhostaddr); + + if(strlen(myhostaddr) > 0 && strncmp(myhostaddr,"127.",4) != 0) { + ipList.push_back(myhostaddr); + } + + return ipList; +} + Socket::Socket(int sock){ this->sock= sock; } @@ -644,10 +693,132 @@ void ClientSocket::connect(const Ip &ip, int port) } } +//======================================================================= +// Function : discovery_response_thread +// in : none +// return : none +// Description: To be forked in its own thread to listen and respond to broadcasts from +// other servers +// +std::vector ClientSocket::discoverServers() { + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + std::vector foundServers; + + short port; // The port for the broadcast. + struct sockaddr_in bcSender; // local socket address for the broadcast. + struct sockaddr_in bcaddr; // The broadcast address for the receiver. + int bcfd; // The file descriptor used for the broadcast. + bool one = true; // Parameter for "setscokopt". + char buff[10024]; // Buffers the data to be broadcasted. + socklen_t alen; + int nb; // The number of bytes read. + + port = htons( Socket::getBroadCastPort() ); + + // Prepare to receive the broadcast. + bcfd = socket(AF_INET, SOCK_DGRAM, 0); + if( bcfd <= 0 ) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"socket failed: %d\n", errno); + //exit(-1); + } + else { + // Create the address we are receiving on. + memset( (char*)&bcaddr, 0, sizeof(bcaddr)); + bcaddr.sin_family = AF_INET; + bcaddr.sin_addr.s_addr = htonl(INADDR_ANY); + bcaddr.sin_port = port; + + int val = 1; + setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + + if(bind( bcfd, (struct sockaddr *)&bcaddr, sizeof(bcaddr) ) < 0 ) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"bind failed: %d\n", errno); + } + else { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + // Keep getting packets forever. + for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 3; ) + { + alen = sizeof(struct sockaddr); + if( (nb = recvfrom(bcfd, buff, 10024, 0, (struct sockaddr *) &bcSender, &alen)) <= 0 ) + { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"recvfrom failed: %d\n", errno); + //exit(-1); + } + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"broadcast message received: [%s] from: [%s]\n", buff,inet_ntoa(bcSender.sin_addr) ); + + vector tokens; + Tokenize(buff,tokens,":"); + foundServers.push_back(tokens[1]); + break; + } + } + } + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + return foundServers; +} + // =============================================== // class ServerSocket // =============================================== +ServerSocket::ServerSocket() : Socket() { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + broadCastThread = NULL; + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +ServerSocket::~ServerSocket() { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + stopBroadCastThread(); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +void ServerSocket::stopBroadCastThread() { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(broadCastThread != NULL) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + broadCastThread->signalQuit(); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + for( time_t elapsed = time(NULL); difftime(time(NULL),elapsed) <= 5; ) { + if(broadCastThread->getRunningStatus() == false) { + break; + } + sleep(100); + 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__); + + delete broadCastThread; + broadCastThread = NULL; + } + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +void ServerSocket::startBroadCastThread() { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + stopBroadCastThread(); + + broadCastThread = new BroadCastSocketThread(); + broadCastThread->start(); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + void ServerSocket::bind(int port) { //sockaddr structure @@ -677,6 +848,10 @@ void ServerSocket::listen(int connectionQueueSize) sprintf(szBuf, "In [%s::%s] Error listening socket sock = %d, err = %d, errno = %d\n",__FILE__,__FUNCTION__,sock,err,errno); throwException(szBuf); } + + broadCastThread = new BroadCastSocketThread(); + broadCastThread->start(); + } Socket *ServerSocket::accept() @@ -698,5 +873,214 @@ Socket *ServerSocket::accept() } +BroadCastSocketThread::BroadCastSocketThread() { + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + setQuitStatus(false); + setRunningStatus(false); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +void BroadCastSocketThread::signalQuit() { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + setQuitStatus(true); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +void BroadCastSocketThread::setQuitStatus(bool value) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + mutexQuit.p(); + quit = value; + mutexQuit.v(); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + +bool BroadCastSocketThread::getQuitStatus() { + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + bool retval = false; + mutexQuit.p(); + retval = quit; + mutexQuit.v(); + + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + return retval; +} + +bool BroadCastSocketThread::getRunningStatus() { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + bool retval = false; + mutexRunning.p(); + retval = running; + mutexRunning.v(); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] running = %d\n",__FILE__,__FUNCTION__,__LINE__,retval); + + return retval; +} + +void BroadCastSocketThread::setRunningStatus(bool value) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] value = %d\n",__FILE__,__FUNCTION__,__LINE__,value); + + mutexRunning.p(); + running = value; + mutexRunning.v(); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] running = %d\n",__FILE__,__FUNCTION__,__LINE__,value); +} + +//======================================================================= +// Function : broadcast_thread +// in : none +// return : none +// Description: To be forked in its own thread to send out a broadcast to the local subnet +// the current broadcast message is +// +void BroadCastSocketThread::execute() { + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + unsigned int tbcaddr; // The broadcast address. + short port; // The port for the broadcast. + struct sockaddr_in bcLocal; // local socket address for the broadcast. + struct sockaddr_in bcaddr; // The broadcast address for the receiver. + int bcfd; // The socket used for the broadcast. + bool one = true; // Parameter for "setscokopt". + int pn; // The number of the packet broadcasted. + char buff[1024]; // Buffers the data to be broadcasted. + char myhostname[100]; // hostname of local machine + //char subnetmask[100]; // Subnet mask to broadcast to + struct in_addr myaddr; // My host address in net format + struct hostent* myhostent; + char * ptr; // some transient vars + int len,i; + + /* get my host name */ + gethostname(myhostname,100); + myhostent = gethostbyname(myhostname); + + // get only the first host IP address + std::vector ipList = Socket::getLocalIPAddressList(); + + /* + strcpy(subnetmask, ipList[0].c_str()); + ptr = &subnetmask[0]; + len = strlen(ptr); + + // substitute the address with class C subnet mask x.x.x.255 + for(i=len;i>0;i--) { + if(ptr[i] == '.') { + strcpy(&ptr[i+1],"255"); + break; + } + } + */ + + // Convert the broadcast address from dot notation to a broadcast address. + //if( (tbcaddr = inet_addr( subnetmask )) == INADDR_NONE ) + //{ + // SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Badly formatted BC address: %d\n", errno); + //exit(-1); + //} + //else + { + port = htons( Socket::getBroadCastPort() ); + + // Create the broadcast socket + memset( &bcLocal, 0, sizeof( struct sockaddr_in)); + bcLocal.sin_family = AF_INET; + bcLocal.sin_addr.s_addr = htonl( INADDR_BROADCAST ); + bcLocal.sin_port = port; // We are letting the OS fill in the port number for the local machine. + bcfd = socket( AF_INET, SOCK_DGRAM, 0 ); + + // If there is an error, report it and terminate. + if( bcfd <= 0 ) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Unable to allocate broadcast socket.: %d\n", errno); + //exit(-1); + } + // Mark the socket for broadcast. + else if( setsockopt( bcfd, SOL_SOCKET, SO_BROADCAST, (const char *) &one, sizeof( int ) ) < 0 ) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Could not set socket to broadcast.: %d\n", errno); + //exit(-1); + } + // Bind the address to the broadcast socket. + else { + + //int val = 1; + //setsockopt(bcfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); + + //if(::bind(bcfd, (struct sockaddr *) &bcLocal, sizeof(struct sockaddr_in)) < 0) { + // SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Could not bind address to BC socket.: %d\n", errno); + //exit(-1); + //} + //else + { + // Record the broadcast address of the receiver. + bcaddr.sin_family = AF_INET; + bcaddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);//tbcaddr; + bcaddr.sin_port = port; + + setRunningStatus(true); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is running\n"); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + try { + // Send this machine's host name and address in hostname:n.n.n.n format + sprintf(buff,"%s:%s",myhostname,ipList[0].c_str()); + + time_t elapsed = 0; + for( pn = 1; ; pn++ ) + { + if(difftime(time(NULL),elapsed) >= 1) { + time_t elapsed = time(NULL); + // Broadcast the packet to the subnet + if( sendto( bcfd, buff, sizeof(buff) + 1, 0 , (struct sockaddr *)&bcaddr, sizeof(struct sockaddr_in) ) != sizeof(buff) + 1 ) + { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Sendto error: %d\n", errno); + //exit(-1); + } + else { + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting to [%s] the message: [%s]\n",subnetmask,buff); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcasting on port [%d] the message: [%s]\n",Socket::getBroadCastPort(),buff); + } + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + if(getQuitStatus() == true) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + break; + } + sleep( 100 ); // send out broadcast every 1 seconds + } + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + } + catch(const exception &ex) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] error [%s]\n",__FILE__,__FUNCTION__,__LINE__,ex.what()); + setRunningStatus(false); + } + catch(...) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unknown error\n",__FILE__,__FUNCTION__,__LINE__); + setRunningStatus(false); + } + + setRunningStatus(false); + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"Broadcast thread is exiting\n"); + } + } + } + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + + }}//end namespace diff --git a/source/shared_lib/sources/platform/sdl/platform_util.cpp b/source/shared_lib/sources/platform/sdl/platform_util.cpp index 510c526dd..372fa4fa5 100644 --- a/source/shared_lib/sources/platform/sdl/platform_util.cpp +++ b/source/shared_lib/sources/platform/sdl/platform_util.cpp @@ -126,6 +126,23 @@ int64 Chrono::getCurTicks() { // Misc // ===================================== +void Tokenize(const string& str,vector& tokens,const string& delimiters) { + // Skip delimiters at beginning. + string::size_type lastPos = str.find_first_not_of(delimiters, 0); + // Find first "non-delimiter". + string::size_type pos = str.find_first_of(delimiters, lastPos); + + while (string::npos != pos || string::npos != lastPos) { + // Found a token, add it to the vector. + tokens.push_back(str.substr(lastPos, pos - lastPos)); + // Skip delimiters. Note the "not_of" + lastPos = str.find_first_not_of(delimiters, pos); + // Find next "non-delimiter" + pos = str.find_first_of(delimiters, lastPos); + } +} + + // This was the simplest, most portable solution i could find in 5 mins for linux int MessageBox(int handle, const char *msg, const char *title, int buttons) { char cmd[1024]=""; diff --git a/source/shared_lib/sources/platform/win32/platform_util.cpp b/source/shared_lib/sources/platform/win32/platform_util.cpp index 4beebbb39..9ca49c6a9 100644 --- a/source/shared_lib/sources/platform/win32/platform_util.cpp +++ b/source/shared_lib/sources/platform/win32/platform_util.cpp @@ -1,7 +1,7 @@ // ============================================================== // This file is part of Glest Shared Library (www.glest.org) // -// Copyright (C) 2001-2008 Martiņo Figueroa +// Copyright (C) 2001-2008 Martio Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published @@ -186,6 +186,23 @@ void PlatformExceptionHandler::install(string dumpFileName){ // ===================================================== // class Misc // ===================================================== + +void Tokenize(const string& str,vector& tokens,const string& delimiters) { + // Skip delimiters at beginning. + string::size_type lastPos = str.find_first_not_of(delimiters, 0); + // Find first "non-delimiter". + string::size_type pos = str.find_first_of(delimiters, lastPos); + + while (string::npos != pos || string::npos != lastPos) { + // Found a token, add it to the vector. + tokens.push_back(str.substr(lastPos, pos - lastPos)); + // Skip delimiters. Note the "not_of" + lastPos = str.find_first_not_of(delimiters, pos); + // Find next "non-delimiter" + pos = str.find_first_of(delimiters, lastPos); + } +} + void findDirs(const vector &paths, vector &results, bool errorOnNotFound) { results.clear(); int pathCount = paths.size(); diff --git a/source/shared_lib/sources/util/util.cpp b/source/shared_lib/sources/util/util.cpp index bf44e24c1..44951a17b 100644 --- a/source/shared_lib/sources/util/util.cpp +++ b/source/shared_lib/sources/util/util.cpp @@ -1,7 +1,7 @@ // ============================================================== // This file is part of Glest Shared Library (www.glest.org) // -// Copyright (C) 2001-2008 Martiņo Figueroa +// Copyright (C) 2001-2008 Martio Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published @@ -17,6 +17,7 @@ #include #include #include +#include #include "leak_dumper.h" @@ -41,9 +42,19 @@ void SystemFlags::OutputDebug(DebugType type, const char *fmt, ...) { return; } + /* Get the current time. */ + time_t curtime = time (NULL); + /* Convert it to local time representation. */ + struct tm *loctime = localtime (&curtime); + char szBuf2[100]=""; + strftime(szBuf2,100,"%Y-%m-%d %H:%M:%S",loctime); + va_list argList; va_start(argList, fmt); + char szBuf[1024]=""; + vsprintf(szBuf,fmt, argList); + // Either output to a logfile or if(SystemFlags::debugLogFile != NULL && SystemFlags::debugLogFile[0] != 0) { if(fileStream.is_open() == false) { @@ -53,16 +64,13 @@ void SystemFlags::OutputDebug(DebugType type, const char *fmt, ...) { //printf("Logfile is open [%s]\n",SystemFlags::debugLogFile); - char szBuf[1024]=""; - vsprintf(szBuf,fmt, argList); - //printf("writing to logfile [%s]\n",szBuf); - fileStream << szBuf; + fileStream << "[" << szBuf2 << "] " << szBuf; fileStream.flush(); } // output to console else { - vprintf(fmt, argList); + printf("[%s] %s", szBuf2, szBuf); } va_end(argList);