Changeset 504 for AE/Installer/trunk/source
- Timestamp:
- Mar 27, 2010, 4:48:25 AM (15 years ago)
- Location:
- AE/Installer/trunk/source
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
AE/Installer/trunk/source/aeinstallerapp.cpp
r500 r504 139 139 if (updateNotification->ShowModal() == wxID_YES) 140 140 ProcessAEUpdate(¤tAE, &updateAE, &installerJustUpdated); 141 break; 142 case UPDATE_THIRD_PARTY: // there's an update with no globalization or Installer strings attached 143 updateMsg = (string)"One or more third party update(s) for Anniversary Edition package(s) are available.\n" + 144 (string)"Please note that the AE team assumes no responsibility for the content of third party mods" + 145 (string)"nor effects that a third party mod may have on your install.\n" + 146 (string)"Do you wish to install these update(s)?"; 147 updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition); 148 if (updateNotification->ShowModal() == wxID_YES) 149 ProcessThirdPartyUpdates(); 141 150 break; 142 151 case UPDATE_GLOB_AVAIL: // there's an update with globalization strings attached -
AE/Installer/trunk/source/globals.h
r503 r504 10 10 11 11 12 #pragma mark INCLUDES12 //#pragma mark INCLUDES 13 13 #include <fstream> 14 14 #include <string> … … 19 19 #include <errno.h> 20 20 #include <sstream> 21 #include "boost/thread.hpp"22 #include "boost/tokenizer.hpp"23 #include "boost/lexical_cast.hpp" // int -> string24 #include "boost/algorithm/string.hpp"25 #include "boost/filesystem.hpp" // includes all needed Boost.Filesystem declarations26 using namespace boost::filesystem;27 using namespace std;28 21 #ifdef WIN32 29 22 #include <windows.h> … … 39 32 #include "wx/wx.h" 40 33 #endif 34 #include "boost/thread.hpp" 35 #include "boost/tokenizer.hpp" 36 #include "boost/lexical_cast.hpp" // int -> string 37 #include "boost/algorithm/string.hpp" 38 #include "boost/filesystem.hpp" // includes all needed Boost.Filesystem declarations 39 using namespace boost::filesystem; 40 using namespace std; 41 41 42 #pragma mark DEFINES42 //#pragma mark DEFINES 43 43 #define INSTALLER_VERSION "1.2" // only place we need to change this 44 44 #define UPDATE_LOG_READ_ERR -1 … … 50 50 #define UPDATE_INST_AVAIL 3 51 51 #define UPDATE_CONT_UPD 4 52 53 #pragma mark STRUCTS52 #define UPDATE_THIRD_PARTY 5 53 //#pragma mark STRUCTS 54 54 struct ModPackage 55 55 { … … 58 58 string name; 59 59 string modStringName; 60 int modStringVersion;60 float modStringVersion; 61 61 string platform; 62 62 bool hasOnis; … … 92 92 93 93 94 #pragma mark PROTOTYPES94 //#pragma mark PROTOTYPES 95 95 void recompileAll(vector<string>); 96 96 int globalizeData(void); … … 99 99 bool ProcessInstallerUpdate(Install_info_cfg *, Install_info_cfg *); 100 100 bool ProcessAEUpdate(Install_info_cfg *, Install_info_cfg *, bool *); 101 bool ProcessThirdPartyUpdates(void); 101 102 void callRefreshMods(void); 102 103 string escapePath(string input); -
AE/Installer/trunk/source/installer.cpp
r502 r504 18 18 #include "boost/date_time/date_parsing.hpp" 19 19 #include "boost/date_time/posix_time/posix_time.hpp" 20 #include <boost/algorithm/string.hpp> 20 21 #include "installer.h" 21 22 #include "aeinstallerapp.h" … … 270 271 copy((path)"../GameDataFolder/level0_Characters", (path)("VanillaDats/level0_Final")); 271 272 GDFPaths.push_back( Characters ); 273 //concactates level0.... 272 274 for(int i = 0; i < GDFPaths.size(); i++) 273 275 { … … 284 286 } 285 287 } 288 //?: syntax is fun. 289 //condition ? value_if_true : value_if_false 290 (is_empty(Characters) ? remove( Characters ) : 1); 291 (is_empty(Particles) ? remove( Particles ) : 1); 292 (is_empty(Textures) ? remove( Textures ) : 1); 293 (is_empty(Sounds) ? remove( Sounds ) : 1); 294 (is_empty(TRAC) ? remove( TRAC ) : 1); 295 (is_empty(TRAM) ? remove( TRAM ) : 1); 296 (is_empty(Animations) ? remove( Animations ) : 1); 286 297 287 298 create_directory((path)"../GameDataFolder/IGMD"); 288 299 copy((path)"packages/VanillaBSL/IGMD", (path)"../GameDataFolder"); 289 300 setProgressBar( 1000 ); 290 291 if(exists("../../persist.dat")) 292 if(!exists("../persist.dat")) 293 294 //TODO: Concatenate level0 Dirs. 295 296 copy("../../persist.dat",".."); 297 if(exists("../../key_config.txt")) 298 if(!exists("../key_config.txt")) 299 copy("../../key_config.txt",".."); 300 301 302 if(exists("../../persist.dat") && !exists("../persist.dat")) copy("../../persist.dat",".."); 303 if(exists("../../key_config.txt")&& !exists("../key_config.txt")) copy("../../key_config.txt",".."); 304 301 305 #ifndef WIN32 302 306 /* On Mac only, set the current GDF to the AE GDF by writing to Oni's global preferences file (thankfully a standard OS X ".plist" XML file). … … 304 308 run Oni before :-p */ 305 309 string fullAEpath = escapePath(system_complete(".").parent_path().parent_path().string()); // get full path for Edition/ (Oni wants the folder that *contains* the GDF) 306 char prefsCommand[300] = "[ -f ~/Library/Preferences/com.godgames.oni.plist ] && defaults write com.godgames.oni RetailInstallationPath -string '"; 310 //bad Iritscen, bad! fixed buffers can cause crashes. 311 /*char prefsCommand[300] = "[ -f ~/Library/Preferences/com.godgames.oni.plist ] && defaults write com.godgames.oni RetailInstallationPath -string '"; 307 312 strcat(prefsCommand, fullAEpath.c_str()); 308 313 strcat(prefsCommand, "'"); // path string is enclosed in single quotes to avoid the need to escape UNIX-unfriendly characters 309 system(prefsCommand); 314 */ 315 string prefsCommand = "[ -f ~/Library/Preferences/com.godgames.oni.plist ] && defaults write com.godgames.oni RetailInstallationPath -string '" 316 + fullAEpath + "'"; 317 system(prefsCommand.c_str()); 318 310 319 #endif 311 320 … … 419 428 package.modStringName = *iter; 420 429 iter++; 421 package.modStringVersion = ato i((*iter).c_str());430 package.modStringVersion = atof((*iter).c_str()); 422 431 } 423 432 else if (!Platform.compare(*iter)) … … 828 837 return UPDATE_LOG_READ_ERR; 829 838 } 830 839 831 840 // Is there an update folder, and is it a monthly release or a patch? 832 if (!exists("../updates/Edition")) 833 { 841 bool firstParty = 0; 842 if (exists("../updates/Edition")) 843 { 844 firstParty = 1; 845 } 846 else { 834 847 strEUFN = "Edition-patch"; 835 if (!exists("../updates/Edition-patch")) 836 return UPDATE_NO_UPD_AVAIL; 837 } 838 839 // Unlike the current AE's version info, we *need* to find the update's version info or we won't continue 840 string updateCfgPath = ("../updates/" + strEUFN + "/install/packages/Globalize/Install_Info.cfg"); 841 updateAECfg.open(updateCfgPath.c_str()); 842 if (!updateAECfg.fail()) 843 { 844 if (!ReadInstallInfoCfg(&updateAECfg, updateAE)) 845 return UPDATE_LOG_READ_ERR; 846 847 updateAECfg.close(); 848 updateAECfg.clear(); 849 } 850 else 851 return UPDATE_LOG_READ_ERR; 852 853 // Now we check for an Installer update in progress 854 if (exists("Update.log")) 855 { 856 updateLog.open("Update.log"); 857 if (!updateLog.fail()) 858 { 859 vector<string> lines; 860 string line; 861 int num_lines = 0; 862 bool readingInstallerVersion = false, doneReadingFile = false; 863 864 while (!updateLog.eof() && !doneReadingFile) 865 { 866 getline(updateLog, line); 867 lines.push_back(line); 868 num_lines++; 869 vector<string> tokens; 870 vector<string>::iterator iter; 871 tokenize(line, tokens); 872 iter = tokens.begin(); 873 if (!readingInstallerVersion && tokens.capacity() >= 4) 874 { 875 if (!strInstaller.compare(*iter)) 876 { 877 if (!strBeing.compare(*++iter)) 878 readingInstallerVersion = true; 879 else if (!strWas.compare(*iter)) 880 *installerJustUpdated = true; // our third indirect return value after currentAE and updateAE 881 } 882 } 883 else if (readingInstallerVersion && tokens.capacity() >= 3) 884 { 885 readingInstallerVersion = false; 886 string installerVersion = INSTALLER_VERSION; 887 if (installerVersion.compare(*iter)) // then the shell script-powered replacement failed 888 return UPDATE_INST_REPL_ERR; 889 else 890 { 891 updateLog.close(); 892 updateLog.clear(); 893 Sleep(1000); 894 remove("Update.log"); 895 ofstream newUpdateLog("Update.log"); 896 if (!newUpdateLog.fail()) 897 { 898 // Write over old log with updated information 899 ptime startTime(second_clock::local_time()); 900 string strStartTime = to_simple_string(startTime); 901 string newUpdateLine = installerVersion + " on " + strStartTime; 902 for (int a = 0; a < lines.capacity() - 2; a++) // if there were even lines in the log before this at all 903 { 904 newUpdateLog << lines[a].c_str(); 905 newUpdateLog << "\n"; 906 } 907 newUpdateLog << "Installer was updated to:\n"; 908 newUpdateLog << newUpdateLine.c_str(); 909 *installerJustUpdated = true; // this value is indirectly returned to AEInstallerAp::OnInit() 910 doneReadingFile = true; 911 newUpdateLog.close(); 912 newUpdateLog.clear(); 913 //return UPDATE_CONT_UPD; // as noted above, we are not using this return value; in fact, we want... 914 // ...the code to continue running down through the Edition version check 915 } 916 else 917 return UPDATE_LOG_READ_ERR; 918 } 919 } 920 } 921 updateLog.close(); 922 updateLog.clear(); 848 if (exists("../updates/Edition-patch")) { 849 firstParty = 1; 850 } 851 852 } 853 854 if(firstParty) { 855 // Unlike the current AE's version info, we *need* to find the update's version info or we won't continue 856 string updateCfgPath = ("../updates/" + strEUFN + "/install/packages/Globalize/Install_Info.cfg"); 857 updateAECfg.open(updateCfgPath.c_str()); 858 if (!updateAECfg.fail()) 859 { 860 if (!ReadInstallInfoCfg(&updateAECfg, updateAE)) 861 return UPDATE_LOG_READ_ERR; 862 863 updateAECfg.close(); 864 updateAECfg.clear(); 923 865 } 924 866 else 925 867 return UPDATE_LOG_READ_ERR; 926 } 927 928 if (updateAE->AEVersion.compare(currentAE->AEVersion) >= 1) // is the release update newer than what's installed? 929 { 930 if (!strEUFN.compare("Edition-patch")) // if update is a patch... 931 { 932 if (currentAE->AEVersion.compare(updateAE->AEVersion.substr(0, updateAE->AEVersion.length() - 1))) // ...is it for a different month? 933 return UPDATE_MNTH_REQD_ERR; 934 } 935 string strNewInstallerPath = "../updates/" + strEUFN + "/install/" + strInstallerName; 936 string installerVersion = INSTALLER_VERSION; 937 if (updateAE->InstallerVersion.compare(installerVersion) >= 1) 938 { 939 if (exists(strNewInstallerPath)) 940 return UPDATE_INST_AVAIL; 941 } 942 else if (updateAE->globalizationRequired) 943 return UPDATE_GLOB_AVAIL; 944 else 945 return UPDATE_SIMP_AVAIL; 946 } 947 else 948 return UPDATE_NO_UPD_AVAIL; 949 868 869 // Now we check for an Installer update in progress 870 if (exists("Update.log")) 871 { 872 updateLog.open("Update.log"); 873 if (!updateLog.fail()) 874 { 875 vector<string> lines; 876 string line; 877 int num_lines = 0; 878 bool readingInstallerVersion = false, doneReadingFile = false; 879 880 while (!updateLog.eof() && !doneReadingFile) 881 { 882 getline(updateLog, line); 883 lines.push_back(line); 884 num_lines++; 885 vector<string> tokens; 886 vector<string>::iterator iter; 887 tokenize(line, tokens); 888 iter = tokens.begin(); 889 if (!readingInstallerVersion && tokens.capacity() >= 4) 890 { 891 if (!strInstaller.compare(*iter)) 892 { 893 if (!strBeing.compare(*++iter)) 894 readingInstallerVersion = true; 895 else if (!strWas.compare(*iter)) 896 *installerJustUpdated = true; // our third indirect return value after currentAE and updateAE 897 } 898 } 899 else if (readingInstallerVersion && tokens.capacity() >= 3) 900 { 901 readingInstallerVersion = false; 902 string installerVersion = INSTALLER_VERSION; 903 if (installerVersion.compare(*iter)) // then the shell script-powered replacement failed 904 return UPDATE_INST_REPL_ERR; 905 else 906 { 907 updateLog.close(); 908 updateLog.clear(); 909 Sleep(1000); 910 remove("Update.log"); 911 ofstream newUpdateLog("Update.log"); 912 if (!newUpdateLog.fail()) 913 { 914 // Write over old log with updated information 915 ptime startTime(second_clock::local_time()); 916 string strStartTime = to_simple_string(startTime); 917 string newUpdateLine = installerVersion + " on " + strStartTime; 918 for (int a = 0; a < lines.capacity() - 2; a++) // if there were even lines in the log before this at all 919 { 920 newUpdateLog << lines[a].c_str(); 921 newUpdateLog << "\n"; 922 } 923 newUpdateLog << "Installer was updated to:\n"; 924 newUpdateLog << newUpdateLine.c_str(); 925 *installerJustUpdated = true; // this value is indirectly returned to AEInstallerAp::OnInit() 926 doneReadingFile = true; 927 newUpdateLog.close(); 928 newUpdateLog.clear(); 929 //return UPDATE_CONT_UPD; // as noted above, we are not using this return value; in fact, we want... 930 // ...the code to continue running down through the Edition version check 931 } 932 else 933 return UPDATE_LOG_READ_ERR; 934 } 935 } 936 } 937 updateLog.close(); 938 updateLog.clear(); 939 } 940 else 941 return UPDATE_LOG_READ_ERR; 942 } 943 944 if (updateAE->AEVersion.compare(currentAE->AEVersion) >= 1) // is the release update newer than what's installed? 945 { 946 if (!strEUFN.compare("Edition-patch")) // if update is a patch... 947 { 948 if (currentAE->AEVersion.compare(updateAE->AEVersion.substr(0, updateAE->AEVersion.length() - 1))) // ...is it for a different month? 949 return UPDATE_MNTH_REQD_ERR; 950 } 951 string strNewInstallerPath = "../updates/" + strEUFN + "/install/" + strInstallerName; 952 string installerVersion = INSTALLER_VERSION; 953 if (updateAE->InstallerVersion.compare(installerVersion) >= 1) 954 { 955 if (exists(strNewInstallerPath)) 956 return UPDATE_INST_AVAIL; 957 } 958 else if (updateAE->globalizationRequired) 959 return UPDATE_GLOB_AVAIL; 960 else 961 return UPDATE_SIMP_AVAIL; 962 } 963 } 964 try { 965 directory_iterator end; 966 if(exists("../updates")){ 967 for ( directory_iterator install_iter( "../updates" ); 968 install_iter != end; 969 ++install_iter ) 970 { 971 972 ModPackage installedPackage, updatePackage; 973 if ( is_directory( install_iter->path() ) && exists( install_iter->path().string() + "/Mod_Info.cfg" ) ) { 974 fstream file; 975 file.open( (install_iter->path().string() + "/Mod_Info.cfg").c_str()); 976 if (!file.fail()) 977 { 978 ModPackage updatePackage = fileToModPackage(file); 979 } 980 else 981 { 982 file.close(); 983 continue; 984 } 985 if(!exists("packages" + install_iter->path().filename() + "/Mod_Info.cfg")); 986 file.close(); 987 file.open( ("packages" + install_iter->path().filename() + "/Mod_Info.cfg").c_str()); 988 if (!file.fail()) 989 { 990 ModPackage installedPackage = fileToModPackage(file); 991 } 992 else 993 { 994 file.close(); 995 return UPDATE_THIRD_PARTY; 996 } 997 file.close(); 998 if(updatePackage.modStringVersion > installedPackage.modStringVersion) { 999 return UPDATE_THIRD_PARTY; 1000 } 1001 1002 } 1003 } 1004 1005 } 1006 } 1007 catch (exception & ex) { 1008 // setStatusArea("Warning, handled exception: " + (string)ex.what()); 1009 } 1010 1011 950 1012 return UPDATE_NO_UPD_AVAIL; 951 1013 } … … 1203 1265 return true; // returning 'true' tells the Installer to quit itself ASAP so it can be replaced by the process that is now running 1204 1266 } 1267 //strPathToEUFNPackages 1268 1269 void CrawlPackages(string pathToUpdate, string strPathToPackages) { 1270 try{ 1271 directory_iterator end; 1272 for ( directory_iterator install_iter( pathToUpdate ); 1273 install_iter != end; 1274 ++install_iter ) 1275 { 1276 1277 ModPackage installedPackage, updatePackage; 1278 string updateStr = install_iter->path().string() + "/Mod_Info.cfg"; 1279 if ( !boost::iequals(install_iter->path().filename(),"Edition") 1280 && !boost::iequals(install_iter->path().filename(),"Edition-patch") 1281 && is_directory( install_iter->path() ) 1282 && exists( install_iter->path().string() + "/Mod_Info.cfg" ) ) 1283 { 1284 bool update = 0; 1285 fstream file; 1286 file.open( (install_iter->path().string() + "/Mod_Info.cfg").c_str()); 1287 if (!file.fail()) 1288 { 1289 updatePackage = fileToModPackage(file); 1290 } 1291 else 1292 { 1293 file.close(); 1294 continue; 1295 } 1296 if(!exists(strPathToPackages + "/" + install_iter->path().filename() + "/Mod_Info.cfg")); 1297 file.close(); 1298 file.clear(); 1299 file.open((strPathToPackages + "/" + install_iter->path().filename() + "/Mod_Info.cfg").c_str()); 1300 if (!file.fail()) 1301 { 1302 installedPackage = fileToModPackage(file); 1303 file.close(); 1304 if(updatePackage.modStringVersion > installedPackage.modStringVersion) { 1305 remove_all((path)(strPathToPackages + "/" + installedPackage.modStringName)); 1306 update = 1; 1307 } 1308 } 1309 else 1310 { 1311 file.close(); 1312 update = 1; 1313 } 1314 file.close(); 1315 1316 if(update) { 1317 rename((path)(pathToUpdate + "/" + updatePackage.modStringName), (path)(strPathToPackages + "/" + updatePackage.modStringName)); 1318 1319 } 1320 } 1321 } 1322 } 1323 catch (exception & ex) { 1324 // ex.what(); 1325 setStatusArea("Warning, handled exception: " + (string)ex.what()); 1326 } 1327 } 1328 1329 1330 bool ProcessThirdPartyUpdates() { 1331 CrawlPackages( "../updates", "./packages"); 1332 return true; 1333 // globalPackages = getPackages(); 1334 // refreshMods(globalInstalledMods); 1335 } 1336 1205 1337 1206 1338 bool ProcessAEUpdate(Install_info_cfg *currentAE, Install_info_cfg *updateAE, bool *installerJustUpdated) … … 1368 1500 } 1369 1501 1370 // Now we crawl the update's package folders for newer versions and move them over, trashing ones that are already present 1371 vector<ModPackage> updatePackages, currentPackages; 1372 bool matchFound; 1373 updatePackages.reserve(256); 1374 currentPackages.reserve(256); 1375 1376 currentPackages = getPackages(); 1377 updatePackages = getPackages(strPathToEUFNPackages); 1378 1379 for (vector<ModPackage>::iterator iter1 = updatePackages.begin(); iter1 != updatePackages.end(); iter1++) 1380 { 1381 matchFound = false; 1382 for (vector<ModPackage>::iterator iter2 = currentPackages.begin(); iter2 != currentPackages.end(); iter2++) 1383 { 1384 if (!iter1->modStringName.compare(iter2->modStringName)) 1385 { 1386 matchFound = true; 1387 if (iter1->modStringVersion > iter2->modStringVersion) 1388 { 1389 #ifndef WIN32 1390 rename((path)(strPathToPackages + iter2->modStringName), (path)(strTrashDir + iter2->modStringName)); 1391 #else 1392 remove((path)(strPathToPackages + iter2->modStringName)); 1393 #endif 1394 rename((path)(strPathToEUFNPackages + iter1->modStringName), (path)(strPathToPackages + iter1->modStringName)); 1395 } 1396 } 1397 } 1398 if (!matchFound) // then there's no old package in the way, so just move in the one from the update 1399 rename((path)(strPathToEUFNPackages + iter1->modStringName), (path)(strPathToPackages + iter1->modStringName)); 1400 } 1502 CrawlPackages( strPathToEUFNPackages, strPathToPackages); 1401 1503 1402 1504 // Next, we get a list of which files and folders in the update's Globalize folder to move over; all files not starting with '.' will be moved... … … 1455 1557 1456 1558 globalPackages = getPackages(); // refresh the list in memory 1457 1458 1559 // TODO: Refresh the packages list in the window 1459 1560 -
AE/Installer/trunk/source/replace_installer.bat
r503 r504 6 6 ) 7 7 8 COPYAEInstaller.exe .\..\..\..\install\8 MOVE AEInstaller.exe .\..\..\..\install\ 9 9 cd ..\..\..\install\ 10 10 START AEInstaller.exe
Note:
See TracChangeset
for help on using the changeset viewer.