ModDirs.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 <engine/ModDirs.h>
00022 #include <common/Defines.h>
00023 #include <common/Logger.h>
00024 #include <common/FileList.h>
00025 #include <stdio.h>
00026 
00027 ModDirs::ModDirs()
00028 {
00029 }
00030 
00031 ModDirs::~ModDirs()
00032 {
00033 }
00034 
00035 bool ModDirs::loadModDirs()
00036 {
00037         loadModFile("none", true);
00038 
00039         std::string modFile = S3D::getModFile("");
00040         std::string globalModFile = S3D::getGlobalModFile("");
00041         if (!loadModDir(modFile, false)) return false;
00042         if (!loadModDir(globalModFile, true)) return false;
00043         return true;
00044 }
00045         
00046 bool ModDirs::loadModDir(const std::string &dirName, bool global)
00047 {
00048         FileList dir(dirName.c_str(), "*", false);
00049         if (dir.getStatus())
00050         {
00051                 FileList::ListType &dirs = dir.getFiles();
00052                 FileList::ListType::iterator itor;
00053                 for (itor = dirs.begin();
00054                         itor != dirs.end();
00055                         itor++)
00056                 {
00057                         std::string filename = (*itor);
00058                         if (!loadModFile(filename, global)) return false;
00059                 }
00060         }
00061         return true;
00062 }
00063 
00064 bool ModDirs::loadModFile(const std::string &inputFileName, bool global)
00065 {
00066         if (strstr(inputFileName.c_str(), "CVS")) return true;
00067 
00068         std::string oldFileName(inputFileName);
00069         std::string newFileName(inputFileName);
00070         _strlwr((char *) newFileName.c_str());
00071 
00072         if (oldFileName != newFileName)
00073         {
00074                 S3D::dialogMessage("ModDirs", S3D::formatStringBuffer(
00075                         "ERROR: All mod directories must have lower case filenames.\n"
00076                         "Directory \"%s\" has upper case charaters in it",
00077                         newFileName.c_str()));
00078                 return false;
00079         }
00080         
00081         // Check if this mod has already been loaded
00082         std::list<ModInfo>::iterator itor;
00083         for (itor = dirs_.begin();
00084                 itor != dirs_.end();
00085                 itor++)
00086         {
00087                 ModInfo &info = (*itor);
00088                 if (0 == strcmp(info.getName(), newFileName.c_str())) return true;
00089         }
00090 
00091         // Check if there is a modinfo file for this mod
00092         std::string noneGamesFile = S3D::getDataFile("data/modinfo.xml");
00093         S3D::setDataFileMod(newFileName);
00094         std::string modGamesFile = S3D::getDataFile("data/modinfo.xml");
00095         S3D::setDataFileMod("none");
00096 
00097         bool defaultInfoFile = (noneGamesFile == modGamesFile);
00098         if (newFileName != "none" && defaultInfoFile)
00099         {
00100                 // This mod does not have a mod info, no one can play it
00101                 // or even see it
00102                 return true;
00103         }
00104 
00105         ModInfo newInfo(newFileName.c_str());
00106 
00107         S3D::setDataFileMod(newFileName);
00108         bool parseResult = newInfo.parse(modGamesFile.c_str());
00109         S3D::setDataFileMod("none");
00110 
00111         if (!parseResult)
00112         {
00113                 // Just log and return as this may be the result of
00114                 // only downloading 1/2 the mod and not having the icons required
00115                 // for the modinfo
00116                 Logger::log(S3D::formatStringBuffer(
00117                         "Failed to parse mod info file \"%s\"",
00118                         modGamesFile.c_str()));
00119                 return true;
00120         }
00121         
00122 
00123         if (0 != strcmp(newInfo.getProtocolVersion(), S3D::ScorchedProtocolVersion.c_str()))
00124         {
00125                 // Check if this is a global mod (one bundled with s3d)
00126                 // If its not we can't play it as it is out of date
00127                 // If it is we remove the custom version in the home dir
00128                 if (!global)
00129                 {
00130                         return true;
00131                 }
00132 
00133                 // The version has changed move the current mod directories
00134                 if (!S3D::dirExists(S3D::getSettingsFile("/oldmods")))
00135                 {
00136                         S3D::dirMake(S3D::getSettingsFile("/oldmods"));
00137                 }
00138 
00139                 // The gloabl mod is out of date, move it out the way
00140                 // This is done because this mod is included with S3D (i.e. a global mod)
00141                 // but also exists in the users custom mod directory.
00142                 // The one in the user's directory may be out of date, so it needs to be 
00143                 // removed incase it masks the newer one that comes with the game.
00144                 std::string src = S3D::getModFile(newFileName);
00145                 std::string dest = S3D::getSettingsFile(
00146                         S3D::formatStringBuffer("/oldmods/%s-%u", newFileName.c_str(), time(0)));
00147                 if (S3D::dirExists(src.c_str()))
00148                 {
00149                         if (0 == rename(src.c_str(), dest.c_str()))
00150                         {
00151                                 S3D::dialogMessage("Scorched3D", S3D::formatStringBuffer(
00152                                         "Mod directory\n"
00153                                         "\"%s\"\n"
00154                                         "was moved to\n"
00155                                         "\"%s\"\n"
00156                                         "as it may be incompatable with this version of Scorched3D",
00157                                         src.c_str(), dest.c_str()));
00158 
00159                                 return loadModFile(oldFileName.c_str(), global);
00160                         }
00161                 }
00162                 else
00163                 {
00164                         S3D::dialogExit("Scorched3D", S3D::formatStringBuffer(
00165                                 "Bundled mod \"%s\" has an out of date modinfo file.\n"
00166                                 "Mod version = %s, scorched version = %s",
00167                                 oldFileName.c_str(),
00168                                 newInfo.getProtocolVersion(), 
00169                                 S3D::ScorchedProtocolVersion.c_str()));
00170                 }
00171         }
00172 
00173         dirs_.push_back(newInfo);
00174         return true;
00175 }

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