UniqueIdStore.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 #include <client/UniqueIdStore.h>
00022 #include <common/Defines.h>
00023 #include <common/Logger.h>
00024 #include <graph/OptionsDisplay.h>
00025 #include <net/NetInterface.h>
00026 #include <XML/XMLFile.h>
00027 #include <stdlib.h>
00028 
00029 UniqueIdStore::UniqueIdStore()
00030 {
00031         if(SDLNet_Init()==-1) false;
00032 }
00033 
00034 UniqueIdStore::~UniqueIdStore()
00035 {
00036 }
00037 
00038 bool UniqueIdStore::loadStore()
00039 {
00040         ids_.clear();
00041 
00042         // Parse the XML file
00043         std::string idsPath = S3D::getSettingsFile("ids.xml");
00044         XMLFile file;
00045         if (!file.readFile(idsPath))
00046         {
00047                 S3D::dialogMessage("Scorched3D Ids", 
00048                         S3D::formatStringBuffer("ERROR: Failed to parse file \"%s\"\n"
00049                         "%s",
00050                         idsPath.c_str(),
00051                         file.getParserError()));                
00052                 return false;
00053         }
00054 
00055         // return true for an empty file
00056         if (!file.getRootNode()) return true;
00057 
00058         XMLNode *node;
00059         while (file.getRootNode()->getNamedChild("id", node, false))
00060         {
00061                 Entry entry;
00062                 if (!node->getNamedChild("id", entry.id)) return false;
00063                 if (!node->getNamedChild("published", entry.published)) return false;
00064 
00065                 IPaddress ipAddress;
00066                 if (SDLNet_ResolveHost(&ipAddress, (char *) entry.published.c_str(), 0) == 0)
00067                 {
00068                         entry.ip = SDLNet_Read32(&ipAddress.host);
00069                 }
00070                 else entry.ip = 0;
00071                 ids_.push_back(entry);
00072         }
00073         return file.getRootNode()->failChildren();
00074 }
00075 
00076 bool UniqueIdStore::saveStore()
00077 {
00078         XMLNode idsNode("ids");
00079         std::list<Entry>::iterator itor;
00080         for (itor = ids_.begin();
00081                 itor != ids_.end();
00082                 itor++)
00083         {
00084                 Entry *entry = &(*itor);
00085                 XMLNode *idNode = new XMLNode("id");
00086                 idsNode.addChild(idNode);
00087                 idNode->addChild(
00088                         new XMLNode("id", entry->id.c_str()));
00089                 idNode->addChild(
00090                         new XMLNode("published", entry->published.c_str()));
00091         }
00092 
00093         std::string idsPath = S3D::getSettingsFile("ids.xml");
00094         if (!idsNode.writeToFile(idsPath)) return false;
00095         return true;
00096 }
00097 
00098 const char *UniqueIdStore::getUniqueId(unsigned int ip)
00099 {
00100         std::list<Entry>::iterator itor;
00101         for (itor = ids_.begin();
00102                 itor != ids_.end();
00103                 itor++)
00104         {
00105                 Entry &entry = *itor;
00106                 if (entry.ip == ip)
00107                 {
00108                         return entry.id.c_str();
00109                 }
00110         }
00111 
00112         static char buffer[128];
00113         buffer[0] = '\0';
00114         return buffer;
00115 }
00116 
00117 bool UniqueIdStore::saveUniqueId(unsigned int ip, const char *id,
00118         const char *published)
00119 {
00120         // No unique id
00121         if (0 == id[0]) return true;
00122 
00123         // AutoDetect server no unique id saved
00124         if (0 == strcmp(published, "AutoDetect")) return true;
00125 
00126         // Check the published ip matches the actual server ip
00127         IPaddress address;
00128         if (SDLNet_ResolveHost(&address, (char *) published, 0) != 0)
00129         {
00130                 Logger::log(S3D::formatStringBuffer("Failed to resolve published server host \"%s\"", published));
00131                 return false;
00132         }
00133 
00134         unsigned int ipAddress = SDLNet_Read32(&address.host);
00135         if (ipAddress != ip) 
00136         {
00137                 std::string actualIp = NetInterface::getIpName(ip);
00138                 std::string pubIp = NetInterface::getIpName(ipAddress);
00139                 Logger::log(S3D::formatStringBuffer("Server ip does not match published ip\n%s != %s (%s)",
00140                         actualIp.c_str(), published, pubIp.c_str()));
00141 
00142                 if (OptionsDisplay::instance()->getValidateServerIp())
00143                 {
00144                         return false;
00145                 }
00146         }
00147 
00148         // If it does, store this id against the published name
00149         bool found = false;
00150         std::list<Entry>::iterator itor;
00151         for (itor = ids_.begin();
00152                 itor != ids_.end();
00153                 itor++)
00154         {
00155                 Entry &entry = *itor;
00156                 if (0 == strcmp(entry.published.c_str(), published))
00157                 {
00158                         if (0 != strcmp(entry.id.c_str(), id))
00159                         {
00160                                 Logger::log( "Warning: Updating to new uniqueid.");
00161 
00162                                 // Update an old id
00163                                 found = true;
00164                                 entry.id = id;
00165                                 break;
00166                         }
00167                         else
00168                         {
00169                                 // Id already here and the same
00170                                 return true;
00171                         }
00172                 }
00173         }
00174 
00175         if (!found)
00176         {
00177                 // A new id
00178                 Entry entry;
00179                 entry.id = id;
00180                 entry.ip = ip;
00181                 entry.published = published;
00182                 ids_.push_back(entry);
00183         }
00184 
00185         // Save this id
00186         saveStore();
00187         return true;
00188 }

Generated on Mon Feb 16 15:14:37 2009 for Scorched3D by  doxygen 1.5.3