Changeset 504 for AE/Installer/trunk


Ignore:
Timestamp:
Mar 27, 2010, 4:48:25 AM (15 years ago)
Author:
gumby
Message:

Allowed single packages to be updated
Changed the modversion to be a float
Fixed a possible crash on Macs
Fixed batch file to move instead of copy

Location:
AE/Installer/trunk/source
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • AE/Installer/trunk/source/aeinstallerapp.cpp

    r500 r504  
    139139                                if (updateNotification->ShowModal() == wxID_YES)
    140140                                        ProcessAEUpdate(&currentAE, &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();     
    141150                                break;
    142151                        case UPDATE_GLOB_AVAIL: // there's an update with globalization strings attached
  • AE/Installer/trunk/source/globals.h

    r503 r504  
    1010
    1111
    12 #pragma mark INCLUDES
     12//#pragma mark INCLUDES
    1313#include <fstream>
    1414#include <string>
     
    1919#include <errno.h>
    2020#include <sstream>
    21 #include "boost/thread.hpp"
    22 #include "boost/tokenizer.hpp"
    23 #include "boost/lexical_cast.hpp" // int -> string
    24 #include "boost/algorithm/string.hpp"
    25 #include "boost/filesystem.hpp" // includes all needed Boost.Filesystem declarations
    26 using namespace boost::filesystem;
    27 using namespace std;
    2821#ifdef WIN32
    2922#include <windows.h>
     
    3932#include "wx/wx.h"
    4033#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
     39using namespace boost::filesystem;
     40using namespace std;
    4141
    42 #pragma mark DEFINES
     42//#pragma mark DEFINES
    4343#define INSTALLER_VERSION                "1.2" // only place we need to change this
    4444#define UPDATE_LOG_READ_ERR             -1
     
    5050#define UPDATE_INST_AVAIL                3
    5151#define UPDATE_CONT_UPD                  4
    52 
    53 #pragma mark STRUCTS
     52#define UPDATE_THIRD_PARTY               5
     53//#pragma mark STRUCTS
    5454struct ModPackage
    5555{
     
    5858        string  name;
    5959        string  modStringName;
    60         int     modStringVersion;
     60        float   modStringVersion;
    6161        string  platform;
    6262        bool    hasOnis;
     
    9292
    9393
    94 #pragma mark PROTOTYPES
     94//#pragma mark PROTOTYPES
    9595void recompileAll(vector<string>);
    9696int globalizeData(void);
     
    9999bool ProcessInstallerUpdate(Install_info_cfg *, Install_info_cfg *);
    100100bool ProcessAEUpdate(Install_info_cfg *, Install_info_cfg *, bool *);
     101bool ProcessThirdPartyUpdates(void);
    101102void callRefreshMods(void);
    102103string escapePath(string input);
  • AE/Installer/trunk/source/installer.cpp

    r502 r504  
    1818#include "boost/date_time/date_parsing.hpp"
    1919#include "boost/date_time/posix_time/posix_time.hpp"
     20#include <boost/algorithm/string.hpp>
    2021#include "installer.h"
    2122#include "aeinstallerapp.h"
     
    270271                copy((path)"../GameDataFolder/level0_Characters", (path)("VanillaDats/level0_Final"));
    271272                GDFPaths.push_back( Characters );
     273                //concactates level0....
    272274                for(int i = 0; i < GDFPaths.size(); i++)
    273275                {
     
    284286                        }
    285287                }
     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);
    286297
    287298                create_directory((path)"../GameDataFolder/IGMD");
    288299                copy((path)"packages/VanillaBSL/IGMD", (path)"../GameDataFolder");
    289300                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
    301305#ifndef WIN32
    302306                /* 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).
     
    304308                 run Oni before :-p */
    305309                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 '";
    307312                strcat(prefsCommand, fullAEpath.c_str());
    308313                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
    310319#endif
    311320               
     
    419428                                package.modStringName = *iter;
    420429                                iter++;
    421                                 package.modStringVersion = atoi((*iter).c_str());
     430                                package.modStringVersion = atof((*iter).c_str());
    422431                        }
    423432                        else if (!Platform.compare(*iter))
     
    828837                        return UPDATE_LOG_READ_ERR;
    829838        }
    830        
     839
    831840        // 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 {
    834847                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();
    923865                }
    924866                else
    925867                        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
    9501012        return UPDATE_NO_UPD_AVAIL;
    9511013}
     
    12031265        return true; // returning 'true' tells the Installer to quit itself ASAP so it can be replaced by the process that is now running
    12041266}
     1267//strPathToEUFNPackages
     1268
     1269void 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
     1330bool ProcessThirdPartyUpdates() {
     1331CrawlPackages( "../updates",  "./packages");
     1332return true;
     1333        //      globalPackages = getPackages();
     1334//      refreshMods(globalInstalledMods);
     1335}
     1336
    12051337
    12061338bool ProcessAEUpdate(Install_info_cfg *currentAE, Install_info_cfg *updateAE, bool *installerJustUpdated)
     
    13681500        }
    13691501       
    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);
    14011503       
    14021504        // 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...
     
    14551557       
    14561558        globalPackages = getPackages(); // refresh the list in memory
    1457        
    14581559        // TODO: Refresh the packages list in the window
    14591560
  • AE/Installer/trunk/source/replace_installer.bat

    r503 r504  
    66        )
    77
    8         COPY AEInstaller.exe  .\..\..\..\install\
     8        MOVE AEInstaller.exe  .\..\..\..\install\
    99        cd ..\..\..\install\
    1010        START AEInstaller.exe
Note: See TracChangeset for help on using the changeset viewer.