diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 617beba4..93a85542 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -2261,10 +2261,12 @@ void Game::update() { server->gameSettings.setFactionControl(i,ctNetwork); ConnectionSlot *slot = server->getSlot(faction->getStartLocationIndex()); server->gameSettings.setNetworkPlayerName(i,slot->getName()); + server->gameSettings.setNetworkPlayerUUID(i,slot->getUUID()); server->gameSettings.setNetworkPlayerStatuses(i,npst_None); this->gameSettings.setFactionControl(i,ctNetwork); this->gameSettings.setNetworkPlayerName(i,server->gameSettings.getNetworkPlayerName(i)); + this->gameSettings.setNetworkPlayerUUID(i,server->gameSettings.getNetworkPlayerUUID(i)); this->gameSettings.setNetworkPlayerStatuses(i,npst_None); } } @@ -2303,6 +2305,7 @@ void Game::update() { this->gameSettings.setFactionControl(i,ctNetwork); this->gameSettings.setNetworkPlayerName(i,server->gameSettings.getNetworkPlayerName(i)); + this->gameSettings.setNetworkPlayerUUID(i,server->gameSettings.getNetworkPlayerUUID(i)); if(this->gameSettings.getNetworkPlayerStatuses(i) == npst_Disconnected) { this->gameSettings.setNetworkPlayerStatuses(i,npst_None); @@ -2714,6 +2717,8 @@ bool Game::switchSetupForSlots(ServerInterface *& serverInterface, gameSettings.setNetworkPlayerName(oldFactionIndex, ""); serverInterface->gameSettings.setNetworkPlayerName(oldFactionIndex, ""); + gameSettings.setNetworkPlayerUUID(oldFactionIndex, ""); + serverInterface->gameSettings.setNetworkPlayerUUID(oldFactionIndex, ""); gameSettings.setFactionControl(newFactionIndex,ctNetwork); serverInterface->gameSettings.setFactionControl(newFactionIndex,ctNetwork); @@ -5118,6 +5123,7 @@ string Game::getDebugStats(std::map &factionDebugInfo) { // resources for(int i = 0; i < world.getFactionCount(); ++i) { string factionInfo = this->gameSettings.getNetworkPlayerName(i); + factionInfo += " [" + this->gameSettings.getNetworkPlayerUUID(i) + "]"; switch(this->gameSettings.getFactionControl(i)) { case ctCpuEasy: factionInfo += " CPU Easy"; diff --git a/source/glest_game/game/game_settings.h b/source/glest_game/game/game_settings.h index 92c138fe..bf657bc9 100644 --- a/source/glest_game/game/game_settings.h +++ b/source/glest_game/game/game_settings.h @@ -93,6 +93,7 @@ private: ControlType factionControls[GameConstants::maxPlayers]; int resourceMultiplierIndex[GameConstants::maxPlayers]; + string networkPlayerUUID[GameConstants::maxPlayers]; int thisFactionIndex; @@ -156,6 +157,8 @@ public: teams[i] = 0; startLocationIndex[i] = i; networkPlayerGameStatus[i] = 0; + + networkPlayerUUID[i] = ""; } flagTypes1 = ft1_none; @@ -273,6 +276,15 @@ public: return resourceMultiplierIndex[factionIndex]; } + const string &getNetworkPlayerUUID(int factionIndex) const { + if(factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"In [%s] Invalid factionIndex = %d\n",__FUNCTION__,factionIndex); + throw megaglest_runtime_error(szBuf); + } + return networkPlayerUUID[factionIndex]; + } + bool isNetworkGame() const { bool result = false; for(int idx = 0; idx < GameConstants::maxPlayers; ++idx) { @@ -414,6 +426,16 @@ public: this->resourceMultiplierIndex[factionIndex]= multiplierIndex; } + void setNetworkPlayerUUID(int factionIndex, const string& uuid) { + if(factionIndex < 0 || factionIndex >= GameConstants::maxPlayers) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"In [%s] Invalid factionIndex = %d\n",__FUNCTION__,factionIndex); + throw megaglest_runtime_error(szBuf); + } + + this->networkPlayerUUID[factionIndex]= uuid; + } + void setThisFactionIndex(int thisFactionIndex) { this->thisFactionIndex= thisFactionIndex; } @@ -491,6 +513,7 @@ public: result += "resourceMultiplierIndex = " + intToStr(resourceMultiplierIndex[idx]) + "\n"; result += "team = " + intToStr(teams[idx]) + "\n"; result += "startLocationIndex = " + intToStr(startLocationIndex[idx]) + "\n"; + result += "networkPlayerUUID = " + networkPlayerUUID[idx] + "\n"; } result += "thisFactionIndex = " + intToStr(thisFactionIndex) + "\n"; @@ -561,8 +584,6 @@ public: networkPlayerStatusesNode->addAttribute("game_status",intToStr(networkPlayerGameStatus[idx]), mapTagReplacements); } - - // string networkPlayerLanguages[GameConstants::maxPlayers]; for(int idx =0; idx < GameConstants::maxPlayers; idx++) { XmlNode *networkPlayerLanguagesNode = gameSettingsNode->addChild("networkPlayerLanguages"); @@ -597,6 +618,11 @@ public: startLocationIndexNode->addAttribute("location",intToStr(startLocationIndex[idx]), mapTagReplacements); } + for(int idx =0; idx < GameConstants::maxPlayers; idx++) { + XmlNode *networkPlayerUUIDNode = gameSettingsNode->addChild("networkPlayerUUID"); + networkPlayerUUIDNode->addAttribute("value",networkPlayerUUID[idx], mapTagReplacements); + } + // int mapFilterIndex; gameSettingsNode->addAttribute("mapFilterIndex",intToStr(mapFilterIndex), mapTagReplacements); // @@ -708,6 +734,11 @@ public: resourceMultiplierIndex[idx] = resourceMultiplierIndexNode->getAttribute("multiplier")->getIntValue(); } + for(int idx =0; idx < GameConstants::maxPlayers; idx++) { + const XmlNode *networkPlayerUUIDNode = gameSettingsNode->getChild("networkPlayerUUID",idx); + networkPlayerUUID[idx] = networkPlayerUUIDNode->getAttribute("value")->getValue(); + } + // int thisFactionIndex; thisFactionIndex = gameSettingsNode->getAttribute("thisFactionIndex")->getIntValue(); // int factionCount; diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index 56fe13fd..d50017c0 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -80,6 +80,7 @@ #include "network_message.h" #include "network_protocol.h" #include "conversion.h" +#include "gen_uuid.h" #include "leak_dumper.h" //#if defined(WIN32) && !defined(HAVE_GOOGLE_BREAKPAD) @@ -3529,6 +3530,16 @@ int glestMain(int argc, char** argv) { Config &config = Config::getInstance(); setupGameItemPaths(argc, argv, &config); + if(config.getString("PlayerId","") == "") { + Shared::Util::uuid_t u; + char uuid_str[38]; + get_uuid_string(uuid_str,sizeof(uuid_str)); + + config.setString("PlayerId",uuid_str); + config.save(); + } + //printf("Players UUID: [%s]\n",config.getString("PlayerId","").c_str()); + if(config.getBool("DisableLuaSandbox","false") == true) { LuaScript::setDisableSandbox(true); } diff --git a/source/glest_game/menu/menu_state_connected_game.cpp b/source/glest_game/menu/menu_state_connected_game.cpp index 059eb456..db4f13cd 100644 --- a/source/glest_game/menu/menu_state_connected_game.cpp +++ b/source/glest_game/menu/menu_state_connected_game.cpp @@ -998,12 +998,13 @@ void MenuStateConnectedGame::simpleTask(BaseThread *callingThread) { string baseURL = config.getString("Masterserver"); string phpVersionParam = config.getString("phpVersionParam","?version=0.1"); string gameVersion = "&glestVersion=" + SystemFlags::escapeURL(glestVersionString); + string playerUUID = "&uuid=" + SystemFlags::escapeURL(config.getString("PlayerId","")); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] About to call first http url, base [%s]..\n",__FILE__,__FUNCTION__,__LINE__,baseURL.c_str()); CURL *handle = SystemFlags::initHTTP(); CURLcode curlResult = CURLE_OK; - techsMetaData = SystemFlags::getHTTP(baseURL + "showTechsForGlest.php"+phpVersionParam+gameVersion,handle,-1,&curlResult); + techsMetaData = SystemFlags::getHTTP(baseURL + "showTechsForGlest.php"+phpVersionParam+gameVersion+playerUUID,handle,-1,&curlResult); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("techsMetaData [%s] curlResult = %d\n",techsMetaData.c_str(),curlResult); if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) { @@ -2156,6 +2157,7 @@ void MenuStateConnectedGame::loadGameSettings(GameSettings *gameSettings) { gameSettings->setThisFactionIndex(slotIndex); gameSettings->setNetworkPlayerName(slotIndex, getHumanPlayerName()); + gameSettings->setNetworkPlayerUUID(slotIndex,Config::getInstance().getString("PlayerId","")); gameSettings->setNetworkPlayerStatuses(slotIndex, getNetworkPlayerStatus()); Lang &lang= Lang::getInstance(); gameSettings->setNetworkPlayerLanguages(slotIndex, lang.getLanguage()); diff --git a/source/glest_game/menu/menu_state_custom_game.cpp b/source/glest_game/menu/menu_state_custom_game.cpp index 7369c53d..3d91ce3b 100644 --- a/source/glest_game/menu/menu_state_custom_game.cpp +++ b/source/glest_game/menu/menu_state_custom_game.cpp @@ -603,6 +603,9 @@ MenuStateCustomGame::MenuStateCustomGame(Program *program, MainMenu *mainMenu, //init controllers if(serverInitError == false) { ServerInterface* serverInterface= NetworkManager::getInstance().getServerInterface(); + if(serverInterface == NULL) { + throw megaglest_runtime_error("serverInterface == NULL"); + } if(this->headlessServerMode == true) { listBoxControls[0].setSelectedItemIndex(ctNetwork); updateResourceMultiplier(0); @@ -2879,6 +2882,8 @@ void MenuStateCustomGame::publishToMasterserver() { } } + publishToServerInfo["uuid"] = Config::getInstance().getString("PlayerId",""); + //?status=waiting&system=linux&info=titus publishToServerInfo["glestVersion"] = glestVersionString; publishToServerInfo["platform"] = getPlatformNameString() + "-" + getSVNRevisionString(); @@ -3254,6 +3259,7 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force gameSettings->setThisFactionIndex(slotIndex); gameSettings->setNetworkPlayerName(slotIndex, getHumanPlayerName(i)); + gameSettings->setNetworkPlayerUUID(slotIndex,Config::getInstance().getString("PlayerId","")); gameSettings->setNetworkPlayerStatuses(slotIndex, getNetworkPlayerStatus()); Lang &lang= Lang::getInstance(); gameSettings->setNetworkPlayerLanguages(slotIndex, lang.getLanguage()); @@ -3310,6 +3316,7 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] i = %d, connectionSlot->getName() [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,i,serverInterface->getSlot(i)->getName().c_str()); gameSettings->setNetworkPlayerName(slotIndex, serverInterface->getSlot(i)->getName()); + gameSettings->setNetworkPlayerUUID(i,serverInterface->getSlot(i)->getUUID()); labelPlayerNames[i].setText(serverInterface->getSlot(i)->getName()); } else { @@ -3328,6 +3335,10 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force labelPlayerNames[i].setText(""); } + if(serverInterface != NULL && serverInterface->getSlot(i) != NULL) { + gameSettings->setNetworkPlayerUUID(slotIndex,serverInterface->getSlot(i)->getUUID()); + } + factionCount++; } else { @@ -3353,6 +3364,7 @@ void MenuStateCustomGame::loadGameSettings(GameSettings *gameSettings,bool force gameSettings->setFactionTypeName(slotIndex, factionFiles[listBoxFactions[i].getSelectedItemIndex()]); gameSettings->setNetworkPlayerName(slotIndex, "Closed"); + gameSettings->setNetworkPlayerUUID(slotIndex,""); closedCount++; } diff --git a/source/glest_game/menu/menu_state_masterserver.cpp b/source/glest_game/menu/menu_state_masterserver.cpp index eeb57e04..230b4f0d 100644 --- a/source/glest_game/menu/menu_state_masterserver.cpp +++ b/source/glest_game/menu/menu_state_masterserver.cpp @@ -972,7 +972,10 @@ void MenuStateMasterserver::simpleTask(BaseThread *callingThread) { safeMutex.ReleaseLock(true); CURL *handle = SystemFlags::initHTTP(); - std::string localServerInfoString = SystemFlags::getHTTP(Config::getInstance().getString("Masterserver") + "showServersForGlest.php",handle); + + string playerUUID = "?uuid=" + SystemFlags::escapeURL(Config::getInstance().getString("PlayerId","")); + std::string localServerInfoString = SystemFlags::getHTTP( + Config::getInstance().getString("Masterserver") + "showServersForGlest.php" + playerUUID,handle); SystemFlags::cleanupHTTP(&handle); if(callingThread->getQuitStatus() == true) { return; diff --git a/source/glest_game/menu/menu_state_mods.cpp b/source/glest_game/menu/menu_state_mods.cpp index 2da7901b..8a7fab94 100644 --- a/source/glest_game/menu/menu_state_mods.cpp +++ b/source/glest_game/menu/menu_state_mods.cpp @@ -428,13 +428,14 @@ void MenuStateMods::simpleTask(BaseThread *callingThread) { if(config.getString("Masterserver","") != "") { string baseURL = config.getString("Masterserver"); string phpVersionParam = config.getString("phpVersionParam","?version=0.1"); + string playerUUID = "&uuid=" + SystemFlags::escapeURL(Config::getInstance().getString("PlayerId","")); string gameVersion = "&glestVersion=" + SystemFlags::escapeURL(glestVersionString); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line %d] About to call first http url, base [%s]..\n",__FILE__,__FUNCTION__,__LINE__,baseURL.c_str()); CURL *handle = SystemFlags::initHTTP(); CURLcode curlResult = CURLE_OK; - techsMetaData = SystemFlags::getHTTP(baseURL + "showTechsForGlest.php"+phpVersionParam+gameVersion,handle,-1,&curlResult); + techsMetaData = SystemFlags::getHTTP(baseURL + "showTechsForGlest.php"+phpVersionParam+gameVersion+playerUUID,handle,-1,&curlResult); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("techsMetaData [%s] curlResult = %d\n",techsMetaData.c_str(),curlResult); if(callingThread->getQuitStatus() == true || safeMutexThreadOwner.isValidMutex() == false) { diff --git a/source/glest_game/network/client_interface.cpp b/source/glest_game/network/client_interface.cpp index 9e2b87c8..7c3d7863 100644 --- a/source/glest_game/network/client_interface.cpp +++ b/source/glest_game/network/client_interface.cpp @@ -525,6 +525,7 @@ void ClientInterface::updateLobby() { versionString = networkMessageIntro.getVersionString(); playerIndex= networkMessageIntro.getPlayerIndex(); serverName= networkMessageIntro.getName(); + serverUUID = networkMessageIntro.getPlayerUUID(); serverFTPPort = networkMessageIntro.getFtpPort(); MutexSafeWrapper safeMutexFlags(flagAccessor,CODE_AT_LINE); @@ -595,7 +596,8 @@ void ClientInterface::updateLobby() { this->getSocket()->getConnectedIPAddress(), serverFTPPort, lang.getLanguage(), - networkMessageIntro.getGameInProgress()); + networkMessageIntro.getGameInProgress(), + Config::getInstance().getString("PlayerId","")); sendMessage(&sendNetworkMessageIntro); //printf("Got intro sending client details to server\n"); diff --git a/source/glest_game/network/client_interface.h b/source/glest_game/network/client_interface.h index b02d2369..74a3cf24 100644 --- a/source/glest_game/network/client_interface.h +++ b/source/glest_game/network/client_interface.h @@ -81,6 +81,8 @@ private: int sessionKey; int serverFTPPort; + string serverUUID; + ClientInterfaceThread *networkCommandListThread; Mutex *networkCommandListThreadAccessor; diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index 147bccbe..9f95484c 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -319,6 +319,7 @@ ConnectionSlot::ConnectionSlot(ServerInterface* serverInterface, int playerIndex this->playerIndex = playerIndex; this->playerStatus = npst_None; this->playerLanguage = ""; + this->playerUUID = ""; this->currentFrameCount = 0; this->currentLagCount = 0; this->gotLagCountWarning = false; @@ -463,8 +464,6 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { slotThreadWorker->purgeCompletedEvents(); } - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - pair socketInfo = this->getSocketInfo(); if(socketInfo.second == NULL) { if(networkGameDataSynchCheckOkMap) networkGameDataSynchCheckOkMap = false; @@ -472,35 +471,14 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { if(networkGameDataSynchCheckOkTech) networkGameDataSynchCheckOkTech = false; this->setReceivedDataSynchCheck(false); - //if(serverInterface->getGameHasBeenInitiated() == true && - // serverInterface->getAllowInGameConnections() == true) { - //printf("Checking for new client connection on slot, checkForNewClients: %d this->canAcceptConnections: %d\n",checkForNewClients,this->canAcceptConnections); - //} - // Is the listener socket ready to be read? if(checkForNewClients == true && this->canAcceptConnections == true) { - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] BEFORE accept new client connection, serverInterface->getOpenSlotCount() = %d\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getOpenSlotCount()); - //bool hasOpenSlots = (serverInterface->getOpenSlotCount() > 0); - //bool hasOpenSlots = true; - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); bool hasData = (serverInterface->getServerSocket() != NULL && serverInterface->getServerSocket()->hasDataToRead() == true); - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - - //if(serverInterface->getGameHasBeenInitiated() == true && - // serverInterface->getAllowInGameConnections() == true) { - //printf("Checking for new client connection on slot, hasData: %d\n",hasData); - //} - if(hasData == true) { - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to accept new client connection playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); Socket *newSocket = serverInterface->getServerSocket()->accept(false); @@ -510,108 +488,49 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { // Set Socket as non-blocking newSocket->setBlock(false); - //printf("Got new connection for slot = %d\n",playerIndex); - MutexSafeWrapper safeMutex(mutexCloseConnection,CODE_AT_LINE); this->setSocket(newSocket); safeMutex.ReleaseLock(); - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - this->connectedTime = time(NULL); this->clearChatInfo(); this->name = ""; this->playerStatus = npst_PickSettings; this->playerLanguage = ""; + this->playerUUID = ""; this->ready = false; this->vctFileList.clear(); this->receivedNetworkGameStatus = false; this->gotIntro = false; - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - MutexSafeWrapper safeMutexSlot1(mutexPendingNetworkCommandList,CODE_AT_LINE); this->vctPendingNetworkCommandList.clear(); safeMutexSlot1.ReleaseLock(); - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - this->currentFrameCount = 0; this->currentLagCount = 0; this->lastReceiveCommandListTime = 0; this->gotLagCountWarning = false; this->versionString = ""; - //if(this->slotThreadWorker == NULL) { - // this->slotThreadWorker = new ConnectionSlotThread(this->serverInterface,playerIndex); - // this->slotThreadWorker->setUniqueID(__FILE__); - // this->slotThreadWorker->start(); - //} - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); serverInterface->updateListen(); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - - - //if(serverInterface->getGameHasBeenInitiated() == true && - // serverInterface->getAllowInGameConnections() == true) { - //printf("Got Client connection on slot!\n"); - //} } else { - //printf("Did not get new socket!\n"); - close(); return; } - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - //} - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - - //send intro message when connected - //if(hasData == true && this->isConnected() == true) { + //send intro message when connected if(this->isConnected() == true) { - //RandomGen random; - //sessionKey = random.randRange(-100000, 100000); - Chrono seed(true); - srand((unsigned int)seed.getCurTicks() / (this->playerIndex + 1)); + Chrono seed(true); + srand((unsigned int)seed.getCurTicks() / (this->playerIndex + 1)); - sessionKey = rand() % 1000000; + sessionKey = rand() % 1000000; - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] accepted new client connection, serverInterface->getOpenSlotCount() = %d, sessionKey = %d\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getOpenSlotCount(),sessionKey); - -// if(hasOpenSlots == false) { -// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] !!!!!!!!WARNING - no open slots, disconnecting client\n",__FILE__,__FUNCTION__,__LINE__); -// -// //if(this->getSocket() != NULL) { -// NetworkMessageIntro networkMessageIntro( -// sessionKey, -// getNetworkVersionSVNString(), -// getHostName(), -// playerIndex, -// nmgstNoSlots, -// 0, -// ServerSocket::getFTPServerPort(), -// "", -// serverInterface->getGameHasBeenInitiated()); -// sendMessage(&networkMessageIntro); -// //} -// -// //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); -// -// //printf("No open slots available\n"); -// -// close(); -// } -// else { - { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] accepted new client connection, serverInterface->getOpenSlotCount() = %d, sessionKey = %d\n",__FILE__,__FUNCTION__,__LINE__,serverInterface->getOpenSlotCount(),sessionKey); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] client will be assigned to the next open slot\n",__FILE__,__FUNCTION__,__LINE__); - //if(this->getSocket() != NULL) { NetworkMessageIntro networkMessageIntro( sessionKey, getNetworkVersionSVNString(), @@ -621,26 +540,17 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { 0, ServerSocket::getFTPServerPort(), "", - serverInterface->getGameHasBeenInitiated()); + serverInterface->getGameHasBeenInitiated(), + Config::getInstance().getString("PlayerId","")); sendMessage(&networkMessageIntro); - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - //} - } } } } - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); } else { - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(socketInfo.first == true) { - - //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - this->clearChatInfo(); bool gotTextMsg = true; @@ -861,6 +771,9 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { this->versionString = networkMessageIntro.getVersionString(); this->connectedRemoteIPAddress = networkMessageIntro.getExternalIp(); this->playerLanguage = networkMessageIntro.getPlayerLanguage(); + this->playerUUID = networkMessageIntro.getPlayerUUID(); + + //printf("Got uuid from client [%s]\n",this->playerUUID.c_str()); //printf("\n\n\n ##### GOT this->playerLanguage [%s]\n\n\n",this->playerLanguage.c_str()); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] got name [%s] versionString [%s], msgSessionId = %d\n",__FILE__,__FUNCTION__,name.c_str(),versionString.c_str(),msgSessionId); @@ -874,6 +787,15 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { close(); return; } + else if(this->playerUUID == "") { + string playerNameStr = name; + string sErr = "Client gave an invalid UUID for player [" + playerNameStr + "]"; + printf("%s\n",sErr.c_str()); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,sErr.c_str()); + + close(); + return; + } else { //check consistency if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -922,11 +844,14 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); gotIntro = true; + int factionIndex = this->serverInterface->gameSettings.getFactionIndexForStartLocation(playerIndex); this->serverInterface->addClientToServerIPAddress(this->getSocket()->getConnectedIPAddress(this->getSocket()->getIpAddress()),this->connectedRemoteIPAddress); + this->serverInterface->gameSettings.setNetworkPlayerUUID(factionIndex,this->playerUUID); + if(serverInterface->getGameHasBeenInitiated() == true && serverInterface->getAllowInGameConnections() == true) { - int factionIndex = this->serverInterface->gameSettings.getFactionIndexForStartLocation(playerIndex); + //int factionIndex = this->serverInterface->gameSettings.getFactionIndexForStartLocation(playerIndex); this->serverInterface->gameSettings.setNetworkPlayerStatuses(factionIndex,npst_None); } @@ -939,14 +864,9 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { if(serverInterface->getGameHasBeenInitiated() == true && serverInterface->getAllowInGameConnections() == true) { - //printf("Sent intro to client connection on slot!\n"); - setJoinGameInProgressFlags(); this->setPauseForInGameConnection(true); - - //printf("Got intro from client sending game settings..\n"); } - } } else { @@ -1041,6 +961,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { int factionIndex = this->serverInterface->gameSettings.getFactionIndexForStartLocation(playerIndex); this->serverInterface->gameSettings.setFactionControl(factionIndex,ctNetwork); this->serverInterface->gameSettings.setNetworkPlayerName(factionIndex,this->name); + this->serverInterface->gameSettings.setNetworkPlayerUUID(factionIndex,this->playerUUID); if(this->serverInterface->gameSettings.getNetworkPlayerStatuses(factionIndex) == npst_Disconnected) { this->serverInterface->gameSettings.setNetworkPlayerStatuses(factionIndex,npst_None); diff --git a/source/glest_game/network/connection_slot.h b/source/glest_game/network/connection_slot.h index d5861d37..70d0e503 100644 --- a/source/glest_game/network/connection_slot.h +++ b/source/glest_game/network/connection_slot.h @@ -143,6 +143,7 @@ private: uint32 connectedRemoteIPAddress; int playerStatus; string playerLanguage; + string playerUUID; bool skipLagCheck; bool joinGameInProgress; @@ -181,6 +182,7 @@ public: void setReady(); const string &getName() const {return name;} + const string &getUUID() const {return playerUUID;} void setName(string value) {name = value;} bool isReady() const {return ready;} diff --git a/source/glest_game/network/network_message.cpp b/source/glest_game/network/network_message.cpp index dba9890c..4bc1de9f 100644 --- a/source/glest_game/network/network_message.cpp +++ b/source/glest_game/network/network_message.cpp @@ -120,7 +120,7 @@ NetworkMessageIntro::NetworkMessageIntro(int32 sessionId,const string &versionSt uint32 externalIp, uint32 ftpPort, const string &playerLanguage, - int gameInProgress) { + int gameInProgress, const string &playerUUID) { data.messageType = nmtIntro; data.sessionId = sessionId; data.versionString = versionString; @@ -131,10 +131,11 @@ NetworkMessageIntro::NetworkMessageIntro(int32 sessionId,const string &versionSt data.ftpPort = ftpPort; data.language = playerLanguage; data.gameInProgress = gameInProgress; + data.playerUUID = playerUUID; } const char * NetworkMessageIntro::getPackedMessageFormat() const { - return "cl128s32shcLL60sc"; + return "cl128s32shcLL60sc60s"; } unsigned int NetworkMessageIntro::getPackedSize() { @@ -152,7 +153,8 @@ unsigned int NetworkMessageIntro::getPackedSize() { packedData.externalIp, packedData.ftpPort, packedData.language.getBuffer(), - data.gameInProgress); + data.gameInProgress, + packedData.playerUUID.getBuffer()); delete [] buf; } return result; @@ -169,7 +171,8 @@ void NetworkMessageIntro::unpackMessage(unsigned char *buf) { &data.externalIp, &data.ftpPort, data.language.getBuffer(), - &data.gameInProgress); + &data.gameInProgress, + data.playerUUID.getBuffer()); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s] unpacked data:\n%s\n",__FUNCTION__,this->toString().c_str()); } @@ -187,7 +190,8 @@ unsigned char * NetworkMessageIntro::packMessage() { data.externalIp, data.ftpPort, data.language.getBuffer(), - data.gameInProgress); + data.gameInProgress, + data.playerUUID.getBuffer()); return buf; } @@ -202,6 +206,8 @@ string NetworkMessageIntro::toString() const { result += " ftpPort = " + uIntToStr(data.ftpPort); result += " language = " + data.language.getString(); result += " gameInProgress = " + uIntToStr(data.gameInProgress); + result += " playerUUID = " + data.playerUUID.getString(); + return result; } @@ -222,6 +228,7 @@ bool NetworkMessageIntro::receive(Socket* socket) { data.name.nullTerminate(); data.versionString.nullTerminate(); data.language.nullTerminate(); + data.playerUUID.nullTerminate(); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] get nmtIntro, data.playerIndex = %d, data.sessionId = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,data.playerIndex,data.sessionId); return result; @@ -530,17 +537,10 @@ NetworkMessageLaunch::NetworkMessageLaunch(const GameSettings *gameSettings,int8 data.resourceMultiplierIndex[i]= gameSettings->getResourceMultiplierIndex(i); data.teams[i]= gameSettings->getTeam(i); data.startLocationIndex[i]= gameSettings->getStartLocationIndex(i); + + data.networkPlayerUUID[i] = gameSettings->getNetworkPlayerUUID(i); + //printf("Build netmsg for index: %d [%s]\n",i,data.networkPlayerUUID[i].getString().c_str()); } -// for(int i= data.factionCount; i < GameConstants::maxPlayers; ++i) { -// data.factionTypeNames[i]= ""; -// data.networkPlayerNames[i]= ""; -// data.networkPlayerStatuses[i] = 0; -// data.networkPlayerLanguages[i] = ""; -// data.factionControls[i]= 0; -// data.resourceMultiplierIndex[i]= 0; -// data.teams[i]= -1; -// data.startLocationIndex[i]= 0; -// } data.cpuReplacementMultiplier = gameSettings->getFallbackCpuMultiplier(); data.aiAcceptSwitchTeamPercentChance = gameSettings->getAiAcceptSwitchTeamPercentChance(); data.masterserver_admin = gameSettings->getMasterserver_admin(); @@ -591,6 +591,9 @@ void NetworkMessageLaunch::buildGameSettings(GameSettings *gameSettings) const { gameSettings->setResourceMultiplierIndex(i,data.resourceMultiplierIndex[i]); gameSettings->setTeam(i, data.teams[i]); gameSettings->setStartLocationIndex(i, data.startLocationIndex[i]); + + gameSettings->setNetworkPlayerUUID(i,data.networkPlayerUUID[i].getString()); + //printf("Build game settings for index: %d [%s]\n",i,data.networkPlayerUUID[i].getString().c_str()); } gameSettings->setAiAcceptSwitchTeamPercentChance(data.aiAcceptSwitchTeamPercentChance); @@ -614,7 +617,7 @@ vector > NetworkMessageLaunch::getFactionCRCList() const { } const char * NetworkMessageLaunch::getPackedMessageFormat() const { - return "c256s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60sllllllll60s60s60s60s60s60s60s60sLLL60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60sLLLLLLLLLLLLLLLLLLLLcccccccccccccccccccccccccccccccccccccccccCccLccll256s"; + return "c256s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60sllllllll60s60s60s60s60s60s60s60sLLL60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60s60sLLLLLLLLLLLLLLLLLLLLcccccccccccccccccccccccccccccccccccccccccCccLccll256s60s60s60s60s60s60s60s60s"; } unsigned int NetworkMessageLaunch::getPackedSize() { @@ -752,7 +755,16 @@ unsigned int NetworkMessageLaunch::getPackedSize() { packedData.cpuReplacementMultiplier, packedData.masterserver_admin, packedData.masterserver_admin_factionIndex, - packedData.scenario.getBuffer()); + packedData.scenario.getBuffer(), + packedData.networkPlayerUUID[0].getBuffer(), + packedData.networkPlayerUUID[1].getBuffer(), + packedData.networkPlayerUUID[2].getBuffer(), + packedData.networkPlayerUUID[3].getBuffer(), + packedData.networkPlayerUUID[4].getBuffer(), + packedData.networkPlayerUUID[5].getBuffer(), + packedData.networkPlayerUUID[6].getBuffer(), + packedData.networkPlayerUUID[7].getBuffer() + ); delete [] buf; } return result; @@ -888,7 +900,16 @@ void NetworkMessageLaunch::unpackMessage(unsigned char *buf) { &data.cpuReplacementMultiplier, &data.masterserver_admin, &data.masterserver_admin_factionIndex, - data.scenario.getBuffer()); + data.scenario.getBuffer(), + data.networkPlayerUUID[0].getBuffer(), + data.networkPlayerUUID[1].getBuffer(), + data.networkPlayerUUID[2].getBuffer(), + data.networkPlayerUUID[3].getBuffer(), + data.networkPlayerUUID[4].getBuffer(), + data.networkPlayerUUID[5].getBuffer(), + data.networkPlayerUUID[6].getBuffer(), + data.networkPlayerUUID[7].getBuffer() + ); } unsigned char * NetworkMessageLaunch::packMessage() { @@ -1023,7 +1044,16 @@ unsigned char * NetworkMessageLaunch::packMessage() { data.cpuReplacementMultiplier, data.masterserver_admin, data.masterserver_admin_factionIndex, - data.scenario.getBuffer()); + data.scenario.getBuffer(), + data.networkPlayerUUID[0].getBuffer(), + data.networkPlayerUUID[1].getBuffer(), + data.networkPlayerUUID[2].getBuffer(), + data.networkPlayerUUID[3].getBuffer(), + data.networkPlayerUUID[4].getBuffer(), + data.networkPlayerUUID[5].getBuffer(), + data.networkPlayerUUID[6].getBuffer(), + data.networkPlayerUUID[7].getBuffer() + ); return buf; } @@ -1050,9 +1080,12 @@ bool NetworkMessageLaunch::receive(Socket* socket) { data.factionTypeNames[i].nullTerminate(); data.networkPlayerNames[i].nullTerminate(); data.networkPlayerLanguages[i].nullTerminate(); + + data.networkPlayerUUID[i].nullTerminate(); } for(unsigned int i = 0; i < maxFactionCRCCount; ++i) { data.factionNameList[i].nullTerminate(); + data.networkPlayerUUID[i].nullTerminate(); } data.scenario.nullTerminate(); diff --git a/source/glest_game/network/network_message.h b/source/glest_game/network/network_message.h index 88934873..59e64ca4 100644 --- a/source/glest_game/network/network_message.h +++ b/source/glest_game/network/network_message.h @@ -98,6 +98,7 @@ class NetworkMessageIntro: public NetworkMessage{ private: static const int maxVersionStringSize= 128; static const int maxNameSize= 32; + static const int maxSmallStringSize= 60; private: struct Data { @@ -111,6 +112,7 @@ private: uint32 ftpPort; NetworkString language; int8 gameInProgress; + NetworkString playerUUID; }; void toEndian(); void fromEndian(); @@ -125,7 +127,7 @@ public: NetworkMessageIntro(int32 sessionId, const string &versionString, const string &name, int playerIndex, NetworkGameStateType gameState, uint32 externalIp, uint32 ftpPort, const string &playerLanguage, - int gameInProgress); + int gameInProgress, const string &playerUUID); virtual const char * getPackedMessageFormat() const; @@ -146,6 +148,8 @@ public: string getPlayerLanguage() const { return data.language.getString(); } uint8 getGameInProgress() const { return data.gameInProgress; } + string getPlayerUUID() const { return data.playerUUID.getString();} + virtual bool receive(Socket* socket); virtual void send(Socket* socket); @@ -272,6 +276,7 @@ private: int8 factionCount; int8 teams[GameConstants::maxPlayers]; int8 startLocationIndex[GameConstants::maxPlayers]; + int8 defaultResources; int8 defaultUnits; int8 defaultVictoryConditions; @@ -290,6 +295,8 @@ private: int32 masterserver_admin_factionIndex; NetworkString scenario; + + NetworkString networkPlayerUUID[GameConstants::maxPlayers]; }; void toEndian(); void fromEndian(); diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index a959e3ce..aaffd8e5 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -2134,7 +2134,7 @@ string ServerInterface::getNetworkStatus() { //float pingTime = connectionSlot->getThreadedPingMS(connectionSlot->getIpAddress().c_str()); char szBuf[8096]=""; snprintf(szBuf,8096,", lag = %d [%.2f]",clientLagCount,lastClientCommandListTimeLag); - str+= connectionSlot->getName() + string(szBuf); + str += connectionSlot->getName() + " [" + connectionSlot->getUUID() + "] " + string(szBuf); } } else { @@ -2594,6 +2594,7 @@ void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool wai } gameSettings = *serverGameSettings; + if(getAllowGameDataSynchCheck() == true) { if(waitForClientAck == true && gameSettingsUpdateCount > 0) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Waiting for client acks #1\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__); @@ -2709,6 +2710,7 @@ std::map ServerInterface::publishToMasterserver() { } } } + publishToServerInfo["uuid"] = Config::getInstance().getString("PlayerId",""); publishToServerInfo["glestVersion"] = glestVersionString; publishToServerInfo["platform"] = getPlatformNameString() + "-" + getSVNRevisionString(); publishToServerInfo["binaryCompileDate"] = getCompileDateTime(); @@ -2854,6 +2856,7 @@ std::string ServerInterface::DumpStatsToLog(bool dumpToStringOnly) const { out << "Player Index: " << slot->getPlayerIndex() << std::endl; out << "IP Address: " << slot->getIpAddress() << std::endl; out << "Player name: " << slot->getName() << std::endl; + out << "Player uuid: " << slot->getUUID() << std::endl; out << "Language: " << slot->getNetworkPlayerLanguage() << std::endl; out << "Game Version: " << slot->getVersionString() << std::endl; out << "Session id: " << slot->getSessionKey() << std::endl; @@ -3008,6 +3011,7 @@ void ServerInterface::saveGame(XmlNode *rootNode) { slotNode->addAttribute("sessionkey",intToStr(slot->getSessionKey()), mapTagReplacements); slotNode->addAttribute("ipaddress",slot->getSocket(false)->getIpAddress(), mapTagReplacements); slotNode->addAttribute("name",slot->getName(), mapTagReplacements); + slotNode->addAttribute("uuid",slot->getUUID(), mapTagReplacements); } else { slotNode->addAttribute("isconnected",intToStr(false), mapTagReplacements); diff --git a/source/glest_game/world/scenario.cpp b/source/glest_game/world/scenario.cpp index 618bbbb8..cbbe9ca7 100644 --- a/source/glest_game/world/scenario.cpp +++ b/source/glest_game/world/scenario.cpp @@ -489,6 +489,7 @@ void Scenario::loadGameSettings(const vector &dirList, if(gameSettings->getNetworkPlayerName(i) == "") { gameSettings->setNetworkPlayerName(i,Config::getInstance().getString("NetPlayerName",Socket::getHostName().c_str())); } + gameSettings->setNetworkPlayerUUID(i,Config::getInstance().getString("PlayerId","")); } else { if(gameSettings->getNetworkPlayerName(i) == "") { diff --git a/source/shared_lib/include/util/gen_uuid.h b/source/shared_lib/include/util/gen_uuid.h new file mode 100644 index 00000000..c0ae40a8 --- /dev/null +++ b/source/shared_lib/include/util/gen_uuid.h @@ -0,0 +1,357 @@ +// ============================================================== +// This file is part of Glest Shared Library (www.glest.org) +// +// Copyright (C) 2005 Matthias Braun +// +// You can redistribute this code and/or modify it under +// 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 version +// ============================================================== +/* what follows is a somewhat stripped-down version of the sample + implementation of UUID generation from RFC 4122. */ + +/* +** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc. +** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. & +** Digital Equipment Corporation, Maynard, Mass. +** Copyright (c) 1998 Microsoft. +** To anyone who acknowledges that this file is provided "AS IS" +** without any express or implied warranty: permission to use, copy, +** modify, and distribute this file for any purpose is hereby +** granted without fee, provided that the above copyright notices and +** this notice appears in all source code copies, and that none of +** the names of Open Software Foundation, Inc., Hewlett-Packard +** Company, Microsoft, or Digital Equipment Corporation be used in +** advertising or publicity pertaining to distribution of the software +** without specific, written prior permission. Neither Open Software +** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital +** Equipment Corporation makes any representations about the +** suitability of this software for any purpose. +*/ + +#ifndef _SHARED_PLATFORM_UUID_H_ +#define _SHARED_PLATFORM_UUID_H_ + +//#ifdef HAVE_CONFIG_H +//#include "config.h" +//#endif + +#include +#include +#include + +namespace Shared { namespace Util { + +//#if defined(HAVE_INTTYPES_H) +//#include +//#endif + +/* set the following to the number of 100ns ticks of the actual + resolution of your system's clock */ +#define UUIDS_PER_TICK 1024 + +//#ifdef WIN32 +//#include +//#include "missing\stdint.h" +//#define snprintf _snprintf +//#else +// +//#if HAVE_SYS_TYPES_H +//#include +//#else +//# if HAVE_STDINT_H +//# include +//# endif +//#endif +// +//#if HAVE_SYS_TIME_H +//#include +//#endif +// +//#if HAVE_SYS_SYSINFO_H +//#include +//#endif +// +//#endif + +/* system dependent call to get the current system time. Returned as + 100ns ticks since UUID epoch, but resolution may be less than + 100ns. */ + +#ifdef WIN32 +#define I64(C) C +#else +#define I64(C) C##LL +#endif + +typedef uint64_t uuid_time_t; + +typedef struct { + char nodeID[6]; +} uuid_node_t; + +#undef uuid_t +typedef struct { + uint32_t time_low; + uint16_t time_mid; + uint16_t time_hi_and_version; + uint8_t clock_seq_hi_and_reserved; + uint8_t clock_seq_low; + uint8_t node[6]; +} uuid_t; + +/* some forward declarations. kind of wimpy to do that but heck, we + are all friends here right? raj 20081024 */ +static uint16_t true_random(void); + +#ifdef WIN32 + +static void get_system_time(uuid_time_t *uuid_time) { + ULARGE_INTEGER time; + + /* NT keeps time in FILETIME format which is 100ns ticks since + Jan 1, 1601. UUIDs use time in 100ns ticks since Oct 15, 1582. + The difference is 17 Days in Oct + 30 (Nov) + 31 (Dec) + + 18 years and 5 leap days. */ + GetSystemTimeAsFileTime((FILETIME *)&time); + time.QuadPart += + + (unsigned __int64) (1000*1000*10) // seconds + * (unsigned __int64) (60 * 60 * 24) // days + * (unsigned __int64) (17+30+31+365*18+5); // # of days + *uuid_time = time.QuadPart; +} + +/* Sample code, not for use in production; see RFC 1750 */ +static void get_random_info(char seed[16]) { + uint16_t myrand; + int i; + + i = 0; + do { + myrand = true_random(); + seed[i++] = myrand & 0xff; + seed[i++] = myrand >> 8; + } while (i < 14); +} + +#else + +static void get_system_time(uuid_time_t *uuid_time) { + struct timeval tp; + gettimeofday(&tp, (struct timezone *)0); + + /* Offset between UUID formatted times and Unix formatted times. + UUID UTC base time is October 15, 1582. + Unix base time is January 1, 1970.*/ + *uuid_time = ((uint64_t)tp.tv_sec * 10000000) + + ((uint64_t)tp.tv_usec * 10) + + I64(0x01B21DD213814000); +} + +/* Sample code, not for use in production; see RFC 1750 */ +static void get_random_info(char seed[16]) { + FILE *fp; + uint16_t myrand; + int i; + + /* we aren't all that picky, and we would rather not block so we + will use urandom */ + fp = fopen("/dev/urandom","rb"); + + if (NULL != fp) { + size_t bytes = fread(seed,sizeof(char),16,fp); + fclose(fp); + return; + } + + /* ok, now what? */ + + i = 0; + do { + myrand = true_random(); + seed[i++] = myrand & 0xff; + seed[i++] = myrand >> 8; + } while (i < 14); + + fclose(fp); +} + +#endif + +/* true_random -- generate a crypto-quality random number. +**This sample doesn't do that.** */ +static uint16_t true_random(void) { + static int inited = 0; + uuid_time_t time_now; + + if (!inited) { + get_system_time(&time_now); + time_now = time_now / UUIDS_PER_TICK; + srand((unsigned int) (((time_now >> 32) ^ time_now) & 0xffffffff)); + inited = 1; + } + + return (uint16_t)rand(); +} + +/* puid -- print a UUID */ +void puid(uuid_t u) { + int i; + + printf("%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", u.time_low, u.time_mid, + u.time_hi_and_version, u.clock_seq_hi_and_reserved, + u.clock_seq_low); + for (i = 0; i < 6; i++) + printf("%2.2x", u.node[i]); + printf("\n"); +} + +/* snpuid -- print a UUID in the supplied buffer */ +void snpuid(char *str, size_t size, uuid_t u) { + int i; + char *tmp = str; + + if (size < 38) { + snprintf(tmp,size,"%s","uuid string too small"); + return; + } + + /* perhaps this is a trifle optimistic but what the heck */ + sprintf(tmp, + "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-", + u.time_low, + u.time_mid, + u.time_hi_and_version, + u.clock_seq_hi_and_reserved, + u.clock_seq_low); + tmp += 24; + for (i = 0; i < 6; i++) { + sprintf(tmp,"%2.2x", u.node[i]); + tmp += 2; + } + *tmp = 0; +} + +/* get-current_time -- get time as 60-bit 100ns ticks since UUID epoch. + Compensate for the fact that real clock resolution is + less than 100ns. */ +static void get_current_time(uuid_time_t *timestamp) { + static int inited = 0; + static uuid_time_t time_last; + static uint16_t uuids_this_tick; + uuid_time_t time_now; + + if (!inited) { + get_system_time(&time_now); + uuids_this_tick = UUIDS_PER_TICK; + inited = 1; + } + + for ( ; ; ) { + get_system_time(&time_now); + + /* if clock reading changed since last UUID generated, */ + if (time_last != time_now) { + /* reset count of uuids gen'd with this clock reading */ + uuids_this_tick = 0; + time_last = time_now; + break; + } + if (uuids_this_tick < UUIDS_PER_TICK) { + uuids_this_tick++; + break; + } + /* going too fast for our clock; spin */ + } + /* add the count of uuids to low order bits of the clock reading */ + *timestamp = time_now + uuids_this_tick; +} + + +/* system dependent call to get IEEE node ID. + This sample implementation generates a random node ID. */ +/* netperf mod - don't bother trying to read or write the nodeid */ +static void get_ieee_node_identifier(uuid_node_t *node) { + static int inited = 0; + static uuid_node_t saved_node; + char seed[16]; + + if (!inited) { + get_random_info(seed); + seed[0] |= 0x01; + memcpy(&saved_node, seed, sizeof saved_node); + } + inited = 1; + + *node = saved_node; +} + +/* format_uuid_v1 -- make a UUID from the timestamp, clockseq, + and node ID */ +static void format_uuid_v1(uuid_t* uuid, uint16_t clock_seq, + uuid_time_t timestamp, uuid_node_t node) { + /* Construct a version 1 uuid with the information we've gathered + plus a few constants. */ + uuid->time_low = (unsigned long)(timestamp & 0xFFFFFFFF); + uuid->time_mid = (unsigned short)((timestamp >> 32) & 0xFFFF); + uuid->time_hi_and_version = + (unsigned short)((timestamp >> 48) & 0x0FFF); + uuid->time_hi_and_version |= (1 << 12); + uuid->clock_seq_low = clock_seq & 0xFF; + uuid->clock_seq_hi_and_reserved = (clock_seq & 0x3F00) >> 8; + uuid->clock_seq_hi_and_reserved |= 0x80; + memcpy(&uuid->node, &node, sizeof uuid->node); +} + +/* uuid_create -- generator a UUID */ +int uuid_create(uuid_t *uuid) { + uuid_time_t timestamp; + uint16_t clockseq; + uuid_node_t node; + + /* get time, node ID, saved state from non-volatile storage */ + get_current_time(×tamp); + get_ieee_node_identifier(&node); + + /* for us clockseq is always to be random as we have no state */ + clockseq = true_random(); + + /* stuff fields into the UUID */ + format_uuid_v1(uuid, clockseq, timestamp, node); + return 1; +} + +void get_uuid_string(char *uuid_str, size_t size) { + uuid_t u; + + uuid_create(&u); + snpuid(uuid_str,size,u); + + return; +} + +//#ifdef NETPERF_STANDALONE_DEBUG +// +//int +//main(int argc, char *argv[]) +//{ +// uuid_t u; +// char uuid_str[38]; +//#if 0 +// uuid_create(&u); +// printf("uuid_create(): "); puid(u); +// snpuid(uuid_str,sizeof(uuid_str),u); +// printf("\nas a string %s\n",uuid_str); +//#endif +// get_uuid_string(uuid_str,sizeof(uuid_str)); +// printf("uuid_str is %s\n",uuid_str); +// return 0; +//} +// +//#endif + +}}; + +#endif