Ignore:
Timestamp:
Dec 30, 2009, 2:51:38 AM (15 years ago)
Author:
iritscen
Message:

Adding update feature; moving/neatening some code; adding globals.h

Location:
AE/Installer/trunk/source
Files:
1 added
10 edited

Legend:

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

    r436 r487  
    1 /////////////////////////////////////////////////////////////////////////////
    2 // Name:        about_window.cpp
    3 // Purpose:     
    4 // Author:     
    5 // Modified by:
    6 // Created:     08/05/2009 11:10:32
    7 // RCS-ID:     
    8 // Copyright:   
    9 // Licence:     
    10 /////////////////////////////////////////////////////////////////////////////
    11 
    12 // For compilers that support precompilation, includes "wx/wx.h".
    13 #include "wx/wxprec.h"
    14 
    15 #ifdef __BORLANDC__
    16 #pragma hdrstop
    17 #endif
    18 
    19 #ifndef WX_PRECOMP
    20 #include "wx/wx.h"
    21 #endif
     1/***************************************************************************\
     2| Project: AE Installer                                                                                                         |
     3| By: Gumby & Iritscen                                                                                                          |
     4| File: About.cpp                                                                                                                       |
     5| Function: Handles the About window!                                                                           |
     6| Created: 08/05/2009 11:10:32                                                                                          |
     7\***************************************************************************/
    228
    239////@begin includes
    2410////@end includes
    25 
     11#include "globals.h"
    2612#include "about.h"
    2713
    2814////@begin XPM images
    2915////@end XPM images
    30 
    3116
    3217/*
     
    126111    itemPanel3->SetSizer(itemBoxSizer4);
    127112       
    128     wxStaticText* itemStaticText5 = new wxStaticText( itemPanel3, wxID_STATIC, _("Mod Installer v1.0.1\nby Gumby and Iritscen\n\nAE credited to:\nEdT: BGI troops, additional weapons\ngeyser: Original creator\nGumby: Installer and Framework\nIritscen: Installer (Mac)\nLoser: Improved animation and AI\nNeo: OniSplit, documenting Oni, tech support\nONIrules: Additional weapons\nParadox: Documenting of Oni\nRossyMiles: Daodan DLL port to C\nSFeLi: Original Daodan DLL\nssg: Documenting Oni"), wxDefaultPosition, wxDefaultSize, wxNO_BORDER );
     113        string aboutText = "AE/Mod Installer v";
     114        aboutText = aboutText + INSTALLER_VERSION;
     115        aboutText = aboutText + "\nby Gumby and Iritscen\n\n" +
     116                                                        "AE credited to:\n" +
     117                                                        "EdT: BGI troops, additional weapons\n" +
     118                                                        "geyser: Original AE framework\n" +
     119                                                        "Gumby: General AE framework, Windows Installer, add'l Daodan DLL coding\n" +
     120                                                        "Iritscen: Mac port of Installer & add'l Installer coding\n" +
     121                                                        "Loser: Improved combat animation and AI\n" +
     122                                                        "Neo: OniSplit, documenting Oni, tech support\n" +
     123                                                        "ONIrules: Additional weapons\n" +
     124                                                        "Paradox: Documenting of Oni\n" +
     125                                                        "RossyMiles: Daodan DLL port to C\n" +
     126                                                        "SFeLi: Original asm Daodan DLL\n" +
     127                                                        "ssg: Documenting Oni's game data";
     128    wxStaticText* itemStaticText5 = new wxStaticText( itemPanel3, wxID_STATIC, _(aboutText.c_str()), wxDefaultPosition, wxDefaultSize, wxNO_BORDER );
    129129    itemBoxSizer4->Add(itemStaticText5, 0, wxALIGN_LEFT|wxALL, 5);
    130130       
  • AE/Installer/trunk/source/about.h

    r411 r487  
    1 /////////////////////////////////////////////////////////////////////////////
    2 // Name:        about_window.h
    3 // Purpose:     
    4 // Author:     
    5 // Modified by:
    6 // Created:     08/05/2009 11:10:32
    7 // RCS-ID:     
    8 // Copyright:   
    9 // Licence:     
    10 /////////////////////////////////////////////////////////////////////////////
     1/***************************************************************************\
     2| Project: AE Installer                                                                                                         |
     3| By: Gumby & Iritscen                                                                                                          |
     4| File: About.h                                                                                                                         |
     5| Function: Handles the About window!                                                                           |
     6| Created: 08/05/2009 11:10:32                                                                                          |
     7\***************************************************************************/
    118
    129#ifndef _ABOUT_H_
    1310#define _ABOUT_H_
    14 
    1511
    1612/*!
  • AE/Installer/trunk/source/aeinstallerapp.cpp

    r423 r487  
    1 /////////////////////////////////////////////////////////////////////////////
    2 // Name:        aeinstallerapp.cpp
    3 // Purpose:     
    4 // Author:     
    5 // Modified by:
    6 // Created:     07/05/2009 17:23:39
    7 // RCS-ID:     
    8 // Copyright:   
    9 // Licence:     
    10 /////////////////////////////////////////////////////////////////////////////
     1/***************************************************************************\
     2| Project: AE Installer                                                                                                         |
     3| By: Gumby & Iritscen                                                                                                          |
     4| File: AEInstallerApp.cpp                                                                                                      |
     5| Function: Sets up the main application window.                                                        |
     6| Created: 07/05/2009 17:23:39                                                                                          |
     7\***************************************************************************/
     8
     9#include "boost/filesystem.hpp"
     10#include "boost/lexical_cast.hpp" // int -> string
    1111#include "boost/thread.hpp"
    12 #include <boost/thread/mutex.hpp>
     12#include "boost/thread/mutex.hpp"
    1313#include <fstream>
    14 #include "boost/filesystem.hpp" // includes all needed Boost.Filesystem declarations
    15 #include "boost/lexical_cast.hpp" //int -> string
    16 using namespace boost::filesystem;
    17 // For compilers that support precompilation, includes "wx/wx.h".
    18 #include "wx/wxprec.h"
    19 
    20 #ifdef __BORLANDC__
    21 #pragma hdrstop
    22 #endif
    23 
    24 #ifndef WX_PRECOMP
    25 #include "wx/wx.h"
    26 #endif
     14#include <string>
     15#include "installer.h"
     16#include "aeinstallerapp.h"
    2717
    2818////@begin includes
    2919////@end includes
    3020
    31 #include "aeinstallerapp.h"
    32 #include <string>
     21Install_info_cfg currentAE, updateAE;
     22MainWindow* TheWindow;
    3323
    3424////@begin XPM images
     
    8878 */
    8979
     80/* The OnInit() routine is used to check whether the Installer has the software *\
     81|  it needs to install mods, whether there is an available update, and whether   |
     82\* the user has globalized yet, to allow mods to be installed.                                  */
    9083bool AEInstallerApp::OnInit()
    9184{   
     
    9386        // Remove the comment markers above and below this block
    9487        // to make permanent changes to the code.
    95        
    9688#if wxUSE_XPM
    9789        wxImage::AddHandler(new wxXPMHandler);
     
    111103        TheWindow = mainWindow;
    112104       
     105        // Anything after this is done after the window appears...
     106       
     107        if (!CheckForRequiredSoftware())
     108        {
     109                TheWindow->Close(); // CheckForRequiredSoftware() will have notified the user of what they are missing, so we just quit now
     110                return true;
     111        }
     112       
     113        bool installerJustUpdated = false;
     114        int updateStatus = GetUpdateStatus(&currentAE, &updateAE, &installerJustUpdated);
     115        if (updateStatus) // otherwise there's no update
     116        {
     117                string updateMsg = "An update for the Anniversary Edition is available.\n"; // for some reason we can't set the initial value while using the '+' operator...
     118                updateMsg = updateMsg + "Do you wish to update to Edition version " + updateAE.AEVersion + "?\n" +
     119                                                        "(Current version is " + currentAE.AEVersion + ")\n"; // ...so tack the rest on in a second command
     120                wxMessageDialog* updateNotification;
     121               
     122                switch (updateStatus) // for the meanings of these return values, see the comments preceding installer.cpp's GetUpdateStatus()
     123                {
     124                        case UPDATE_LOG_READ_ERR:
     125                        {
     126                                if (exists("Update.log")) remove("Update.log");
     127                                ofstream logfile("Update.log");
     128                                logfile << "Error: A necessary .cfg file could not be read.";
     129                        } // brackets are needed due to the initialization of the ofstream; silly C!
     130                                break;
     131                        case UPDATE_MNTH_REQD_ERR:
     132                                updateMsg = "There is a patch in the updates/ folder, but it patches the\n";
     133                                updateMsg = updateMsg + updateAE.AEVersion.substr(0, updateAE.AEVersion.length() - 1) + " release; it cannot update this version of the Edition.";
     134                                updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxOK | wxICON_EXCLAMATION, wxDefaultPosition);
     135                                updateNotification->ShowModal();
     136                                break;
     137                        case UPDATE_SIMP_AVAIL: // there's an update with no globalization or Installer strings attached
     138                                updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition);
     139                                if (updateNotification->ShowModal() == wxID_YES)
     140                                        ProcessAEUpdate(&currentAE, &updateAE, &installerJustUpdated);
     141                                break;
     142                        case UPDATE_GLOB_AVAIL: // there's an update with globalization strings attached
     143                                updateMsg = updateMsg + "**Note that the update requires you to reglobalize, which will take 5-20 minutes.**\n" +
     144                                                                                "Before clicking Yes, MAKE SURE you have backed up any mods not installed through\n " +
     145                                                                                "the Installer, such as plug-ins or direct OniSplit imports.";
     146                                updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition);
     147                                if (updateNotification->ShowModal() == wxID_YES)
     148                                        ProcessAEUpdate(&currentAE, &updateAE, &installerJustUpdated);
     149                                break;
     150                        case UPDATE_INST_AVAIL: // there's an update with Installer strings attached (globalization is irrelevant while the Installer is not yet updated)
     151                                updateMsg = updateMsg + "**Note that the update requires the Installer to update itself.**\n" +
     152                                                                                "If you click Yes, the Installer will quit and re-launch itself, then\n" +
     153                                                                                "you will be prompted to begin the installation.";
     154                                updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition);
     155                                updateNotification->ShowModal();
     156                                if (updateNotification->ShowModal() == wxID_YES)
     157                                {
     158                                        if (ProcessInstallerUpdate(&currentAE, &updateAE)) // there's an intentional logic gap here: if the user clicks "Yes"...
     159                                        {                                                                                                  // ...and then ProcessInstallerUpdate has an error and returns false, the logic gap results...
     160                                                TheWindow->Close();                                                        // ...in the code continuing to execute down through case UPDATE_INST_REPL_ERR
     161                                                return true;
     162                                        }
     163                                }
     164                                else
     165                                        break;
     166                        case UPDATE_INST_REPL_ERR: // the Installer replacement failed, user has to do it :-(
     167                                updateMsg = "The Installer replacement process failed for some reason.\n";
     168                                updateMsg = updateMsg + "Please quit, go into the folder Edition/Updates/" + strEUFN + "/install/ and drag the Installer to Edition/install/, " +
     169                                                                                "replacing the current Installer application, then launch the new version.";
     170                                updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxOK | wxICON_EXCLAMATION, wxDefaultPosition);
     171                                updateNotification->ShowModal();
     172                                TheWindow->Close();
     173                                return true;
     174                }
     175        }
     176
     177        CheckForGlobalization(false); // function will prompt user and initiate globalization if not done already
     178       
     179        return true;
     180}
     181
     182bool CheckForRequiredSoftware(void)
     183{
    113184#ifdef WIN32
    114          HKEY hKey;
    115          if(!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\.NETFramework\\policy\\v2.0", 0L, KEY_READ , &hKey) == ERROR_SUCCESS) {
    116                  wxMessageDialog* MonoDialogOfDeath = new wxMessageDialog(TheWindow, "You don't have .NET 2.0 installed! .NET is a framework required by the Edition. You can download it from:\nhttp://gumby.oni2.net/dotnet\nPlease install .NET 2.0, then open this Installer again. \n\nWould you like to open the download webpage?",  "AE Installer Alert",  wxYES_NO | wxICON_EXCLAMATION        , wxDefaultPosition);
    117                  if(MonoDialogOfDeath->ShowModal() == wxID_YES) {
     185        // test for .NET 2.0 or higher
     186        HKEY hKey;
     187        if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\.NETFramework\\policy\\v2.0", 0L, KEY_READ , &hKey) == ERROR_SUCCESS)
     188        {
     189                string dotnetMsg = "You don't have .NET 2.0 installed! .NET is a framework required by the Edition.\n";
     190                dotnetMsg = dotnetMsg + "You can download it from:\n" +
     191                                                                "http://gumby.oni2.net/dotnet\n" +
     192                                                                "Please install .NET 2.0, then open this Installer again.\n\n" +
     193                                                                "Would you like to open the download webpage?";
     194                wxMessageDialog* DotNetDialogOfDeath = new wxMessageDialog(TheWindow, dotnetMsg.c_str(), "AE Installer Alert",
     195                                                                                                                                 wxYES_NO | wxICON_EXCLAMATION  , wxDefaultPosition);
     196                if (DotNetDialogOfDeath->ShowModal() == wxID_YES)
    118197                        system("start http://www.microsoft.com/downloads/details.aspx?familyid=0856eacb-4362-4b0d-8edd-aab15c5e04f5");
    119                  }
    120198                RegCloseKey(hKey);
    121                 TheWindow->Close();
    122          }
    123 #else
    124         // test for the third-party mono framework, because without it, on Mac, we are up a creek
    125         char monoCommand[300] = "which mono >> ";
    126         strcat(monoCommand, escapePath(system_complete("mono_check.log").string()).c_str());
    127         system(monoCommand);
    128         fstream file;
    129         file.open("mono_check.log");
    130         string line;
    131         int line_count = 0;
    132         while (!file.eof())
    133         {
    134                 line_count++;
    135                 getline(file, line);
    136         }
    137         file.close();
    138         remove("mono_check.log");
    139        
    140         if (line_count <= 1) // this means that "which mono" returned nothing -- abort! abort! abort!
    141         {
    142                 wxMessageDialog* MonoDialogOfDeath = new wxMessageDialog(TheWindow, "You don't have 'mono' installed! 'mono' is a command-line tool required by the Edition. You can download it from:\nhttp://www.go-mono.com/mono-downloads/download.html (OS X 10.4+) or\nhttp://edt.oni2.net/AE/MonoFramework10.3.dmg (OS X 10.3)\n\nPlease install 'mono', then open this Installer again.",  "AE Installer Alert",  wxOK | wxICON_EXCLAMATION     , wxDefaultPosition);
     199                return false;
     200        }
     201#else // on Mac...
     202        // test for the third-party "mono" framework, because without it, we are up a creek
     203        FILE *fWhichMono = NULL;
     204        char chrWhichMono[32];
     205        fWhichMono = popen("which mono", "r");
     206        fgets(chrWhichMono, sizeof(chrWhichMono), fWhichMono);
     207        pclose(fWhichMono);
     208        string strWhichMono = (string)chrWhichMono;
     209        string::size_type loc = strWhichMono.find("mono", 0);
     210       
     211        if (loc == string::npos) // this means that "which mono" did not return a path leading to the mono binary -- abort! abort! abort!
     212        {
     213                string monoMsg = "You don't have 'mono' installed! 'mono' is a command-line tool required by the Edition.\n";
     214                monoMsg = monoMsg + "You can download it from: http://www.go-mono.com/mono-downloads/download.html (OS X 10.4+)\n" +
     215                                                        "or http://edt.oni2.net/AE/MonoFramework10.3.dmg (OS X 10.3)\n\n" +
     216                                                        "Please install 'mono', then open this Installer again.";
     217                wxMessageDialog* MonoDialogOfDeath = new wxMessageDialog(TheWindow, monoMsg.c_str(), "AE Installer Alert", wxOK | wxICON_EXCLAMATION, wxDefaultPosition);
    143218                MonoDialogOfDeath->ShowModal();
    144                 TheWindow->Close();
    145                 return true; // it's quittin' time, Joe
    146         }
    147 #endif
    148 
    149         //anything after this is done after the window appears...
    150 
    151         if ( !exists("../GameDataFolder") )
    152         {
    153                 wxMessageDialog* YesNoDialog = new wxMessageDialog(TheWindow,           "You haven't globalized yet! \nYou must globalize to use the Anniversary Edition framework. \nWould you like to globalize now? (This could take a while...)\n(Selecting \"No\" will exit this program...)",  "AE Installer Alert",  wxYES_NO | wxICON_EXCLAMATION       , wxDefaultPosition);
    154 
     219                return false; // it's quittin' time, Joe
     220        }
     221#endif
     222        return true;
     223}
     224
     225bool CheckForGlobalization(bool justDoIt)
     226{
     227        if (!exists("../GameDataFolder"))
     228        {
     229                string globMsg = "You haven't globalized yet!\n";
     230                globMsg = globMsg + "You must globalize to use the Anniversary Edition framework.\n" +
     231                                                        "Would you like to globalize now? (This could take a while...)\n" +
     232                                                        "(Selecting \"No\" will exit this program...)";
     233                wxMessageDialog* YesNoDialog = new wxMessageDialog(TheWindow, globMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition);
     234               
    155235                if (YesNoDialog->ShowModal() == wxID_NO) // if the user said no...
     236                {
    156237                        TheWindow->Close();
    157                 else
    158                 {
    159 
    160 
     238                        return true;
     239                }
     240        }
     241        else if (!justDoIt)
     242                return false;
     243        // Code below this point runs if user clicks "Yes" or if they are never asked but justDoIt is true
    161244#ifdef WIN32
    162                         boost::thread thrd3(globalize2);
    163                 //globalizeData();
    164                 //boost::thread::create_thread(&globalizeData);
    165                 //       boost::thread_group Tg;
    166                 // Tg.create_thread( &globalizeData(), this );
    167 #else
    168                                                 TheWindow->InstallButton->Disable();
    169                         TheWindow->ReglobalizeButton->Disable();
    170                         globalizeData();
    171                                                 TheWindow->InstallButton->Enable();
    172                         TheWindow->ReglobalizeButton->Enable();
    173 #endif
    174                
    175 
    176                 }
    177         }
    178 
     245        boost::thread thrd3(globalize2);
     246#else // cannot use multi-threading in Mac build
     247        TheWindow->InstallButton->Disable();
     248        TheWindow->ReglobalizeButton->Disable();
     249        globalizeData();
     250        TheWindow->InstallButton->Enable();
     251        TheWindow->ReglobalizeButton->Enable();
     252#endif
     253       
    179254        return true;
    180255}
    181256
    182 
    183 void setStatusArea( string s ) {
     257void setStatusArea(string s)
     258{
    184259        wxString wxs(s.c_str(), wxConvUTF8);
    185260       
    186         TheWindow->StatusArea->SetStatusText(  wxs );
    187         //TheWindow->StatusArea->SetStatusText(s.c_str());
    188         //StatusArea->SetStatusText(_(s.c_str()));
    189         //(*TheStatusBar)->SetStatusText(_(s.c_str()));
    190         //AEInstallerApp::
    191         //      TheWindow->StatusArea->SetStatusText("hi");
    192         //mainWindow
    193         //itemFrame1->StatusArea->SetStatusText(_"lol");
    194         //MainWindow.StatusArea->SetStatusText("hi");
    195         // class AbstractStatusNotifier { public: virtual void NotifyStatus(const wxString &statusString) = 0; };
    196         //class StatusBarStatusNotifier : public AbstractStatusNotifier { wxStatusBar *statusbar; StatusBarStatusNotifier(wxStatusBar *bar) : statusbar(bar) { } ;
    197         //void NotifyStatus(const wxString &status) { statusbar->SetStatus(status); } }
    198        
    199        
    200         //MainWindow::StatusArea->
    201         //MainWindow::MainWindow().SetSize(MainWindow::MainWindow().GetRect().GetWidth(), MainWindow::MainWindow().GetRect().GetHeight()+1);
    202        
    203         //MainWindow::StatusBar->SetLabel("Importing Files...");
    204         //StatusBar->SetLabel(s);
    205         //->SetLabel(s);
    206        
     261        TheWindow->StatusArea->SetStatusText(wxs);
    207262}
    208263
     
    218273        ////@end AEInstallerApp cleanup
    219274}
    220 void doglobalizeData() {
    221         //TheWindow->Disable();
     275void doglobalizeData()
     276{
    222277        globalizeData();
    223278#ifdef WIN32
    224279        while(1) Sleep(-1);
    225280#endif
    226         //TheWindow->Enable();
    227         //setStatusArea((string)"Test1");
    228 }
     281}
  • AE/Installer/trunk/source/aeinstallerapp.h

    r423 r487  
    1 /////////////////////////////////////////////////////////////////////////////
    2 // Name:        main.h
    3 // Purpose:     
    4 // Author:     
    5 // Modified by:
    6 // Created:     07/05/2009 17:23:39
    7 // RCS-ID:     
    8 // Copyright:   
    9 // Licence:     
    10 /////////////////////////////////////////////////////////////////////////////
     1/***************************************************************************\
     2| Project: AE Installer                                                                                                         |
     3| By: Gumby & Iritscen                                                                                                          |
     4| File: AEInstallerApp.h                                                                                                        |
     5| Function: Sets up the main application window.                                                        |
     6| Created: 07/05/2009 17:23:39                                                                                          |
     7\***************************************************************************/
    118
    129#ifndef _AEINSTALLERAPP_H_
     
    1916
    2017////@begin includes
     18#include "wx/app.h"
    2119#include "wx/image.h"
    2220#include "main_window.h"
    2321////@end includes
    24 
    25 string escapePath(string input);
    2622
    2723/*!
     
    8278#endif
    8379    // _AEINSTALLERAPP_H_
    84 int globalizeData(void);
     80
    8581void globalize2(void);
    86 MainWindow* TheWindow;
     82bool CheckForRequiredSoftware(void);
     83void doglobalizeData(void);
  • AE/Installer/trunk/source/app_resources.cpp

    r324 r487  
    1 /////////////////////////////////////////////////////////////////////////////
    2 // Name:       
    3 // Purpose:     
    4 // Author:     
    5 // Modified by:
    6 // Created:     06/05/2009 08:47:16
    7 // RCS-ID:     
    8 // Copyright:   
    9 // Licence:     
    10 /////////////////////////////////////////////////////////////////////////////
     1/***************************************************************************\
     2| Project: AE Installer                                                                                                         |
     3| By: Gumby & Iritscen                                                                                                          |
     4| File: App_Resources.cpp                                                                                                       |
     5| Function: Creates the menubar and loads image resources into memory.          |
     6| Created: 06/05/2009 08:47:16                                                                                          |
     7\***************************************************************************/
    118
    12 // For compilers that support precompilation, includes "wx/wx.h".
    13 #include "wx/wxprec.h"
    14 
    15 #ifdef __BORLANDC__
    16 #pragma hdrstop
    17 #endif
    18 
    19 #ifndef WX_PRECOMP
    20 #include "wx/wx.h"
    21 #endif
    229
    2310////@begin includes
    2411////@end includes
    25 
     12#include "globals.h"
    2613#include "app_resources.h"
    2714
  • AE/Installer/trunk/source/app_resources.h

    r324 r487  
    1 /////////////////////////////////////////////////////////////////////////////
    2 // Name:       
    3 // Purpose:     
    4 // Author:     
    5 // Modified by:
    6 // Created:     06/05/2009 08:47:17
    7 // RCS-ID:     
    8 // Copyright:   
    9 // Licence:     
    10 /////////////////////////////////////////////////////////////////////////////
     1/***************************************************************************\
     2| Project: AE Installer                                                                                                         |
     3| By: Gumby & Iritscen                                                                                                          |
     4| File: App_Resources.h                                                                                                         |
     5| Function: Creates menubar and loads image resources into memory.                      |
     6| Created: 06/05/2009 08:47:17                                                                                          |
     7\***************************************************************************/
     8
    119
    1210#ifndef _APP_RESOURCES_H_
  • AE/Installer/trunk/source/installer.cpp

    r379 r487  
    1 /*
    2  AE/Mod Installer
    3  by Gumby and Iritscen
    4 */
     1/***************************************************************************\
     2| Project: AE Installer                                                                                                         |
     3| By: Gumby & Iritscen                                                                                                          |
     4| File: Installer.cpp                                                                                                           |
     5| Function: Contains the real meat of the installation process. Mm, beefy.      |
     6| Created: 24/05/2009 19:39:00                                                                                          |
     7\***************************************************************************/
     8
     9// TODO: Load credits from text resource file
     10// TODO: Clear mod info fields when mod is de-selected
    511
    612#define DEBUG
    7 #include <stdio.h>
    8 //#include <conio.h>
    9 //#include <process.h>
    10 #include <string>
    11 #include <iostream>
    12 #include <cctype>
    13 #include <vector>
    14 #include <fstream>
    15 #include <errno.h>
    16 #include <sstream>
    17 
    18 #include "boost/filesystem.hpp" // includes all needed Boost.Filesystem declarations
    19 
     13
     14#include "boost/date_time/gregorian/gregorian.hpp"
     15#include "boost/date_time/date_parsing.hpp"
     16#include "boost/date_time/posix_time/posix_time.hpp"
    2017#include "installer.h"
    21 
    22 #ifdef WIN32
    23 #include <windows.h>
    24 #else // assume we're on Mac
    25 #include <stdlib.h>
    26 #include <dirent.h>
    27 #endif
    28 
    29 //const string strInstallerVersion = "1.0";
    30 const bool SPLIT = 1;
    31 const bool NOT_SPLIT = 0;
    32 bool splitInstances = SPLIT;
    33 
    34 #ifdef WIN32
    35 const string strOniSplit = "Onisplit.exe";
    36 string strImportOption = "-import:nosep";
    37 const char* strClsCmd = "cls";
    38 const char* strPauseCmd = "PAUSE";
    39 #else // set up Mac equivalents since we're in Mac OS
    40 const string strOniSplit = "mono Onisplit.exe";
    41 string strImportOption = "-import:sep";
    42 const char* strClsCmd = "clear";
    43 const char* strPauseCmd = "read -n 1 -p \"Press any key to continue\"";
    44 #endif
    45 
    46 using namespace boost::filesystem;
    47 using namespace std;
    48 
    49 
    50 /*
    51  int main(void)
    52  {
    53  if ( exists( "../../GameDataFolder/level0_Final.sep" ) ) splitInstances = NOT_SPLIT;
    54  else splitInstances = NOT_SPLIT;
    55  //     SetConsoleTitle("AE Installer"); windows junk, convert to SDL
    56  #ifdef WIN32   
    57  system("color 0A");
    58  #endif
    59  cout << "\nWelcome to the AE installer!\n";
    60  cout << "\nWhat would you like to do?\n";
    61  
    62  return mainMenu();
    63  }
    64  */
    65 
    66 
    67 
    68 int mainMenu(void)
    69 {
    70         char choice = '0';
    71         bool exit = false;
     18#include "aeinstallerapp.h"
     19
     20using namespace boost::gregorian;
     21using namespace boost::posix_time;
     22
     23// externs declared in installer.h
     24string strInstallCfg = "../GameDataFolder/Add.cfg";
     25string strEUFN = "Edition"; // GetUpdateStatus() may set this to "Edition-patch" later, but this is the assumed name of the new Edition folder in Updates/
     26
     27int globalizeData(void)
     28{
     29        busy = 1;
     30        using boost::lexical_cast;
     31        using boost::bad_lexical_cast;
     32        using namespace boost::gregorian;
     33        using namespace boost::posix_time;
     34        ptime start_time(second_clock::local_time());
     35       
     36        setStatusArea("Globalizing!");
    7237        int err = 0;
    73         do
    74         {
    75                 if( exists( "../GameDataFolder" ) ) {
    76                         cout << "\n1. Add new packages\n";
    77                         cout << "2. Remove packages\n";
    78                         cout << "3. See what is installed\n";
    79                         cout << "4. Globalize data\n";
    80                         cout << "5. About AE\n";
    81                         cout << "6. Quit\n\n";
    82                        
    83                         choice = cin.get();
    84                         cin.ignore(128, '\n');
    85                         switch(choice)
    86                         {
    87                                 case '1':
    88                                         err = installPackages();
    89                                         break;
    90                                 case '2':
    91                                         err = uninstallPackages();
    92                                         break;
    93                                 case '3':
    94                                         err = listInstalledPackages();
    95                                         break;
    96                                 case '4':
    97                                         err = globalizeData();
    98                                         break;
    99                                 case '5':
    100                                         err = printInstallerInfo();
    101                                         break;
    102                                 case '6':
    103                                         exit = true;
    104                                         break;
    105                                 default:
    106                                         cout << "Please choose one of the above numbers, and press Enter.\n\n";
    107                         }
    108                         if (err) // if something fatal happened
    109                                 exit = true;
    110                 }
    111                 else {
    112                         cout << "\n1. Globalize data\n";
    113                         cout << "2. About AE\n";
    114                         cout << "3. Quit\n\n";
    115                        
    116                         choice = cin.get();
    117                         cin.ignore(128, '\n');
    118                         switch(choice)
    119                         {
    120                                 case '1':
    121                                         err = globalizeData();
    122                                         break;
    123                                 case '2':
    124                                         err = printInstallerInfo();
    125                                         break;
    126                                 case '3':
    127                                         exit = true;
    128                                         break;
    129                                 default:
    130                                         cout << "Please choose one of the above numbers, and press Enter.\n\n";
    131                         }
    132                         if (err) // if something fatal happened
    133                                 exit = true;
    134                 }
    135         } while(!exit);
    136        
    137         return err;
    138 }
    139 
    140 int globalizeData(void)
    141 {
    142         int err = 0;
    143        
    144         try {
    145                 int levels[15] = {0, 1, 2, 3, 4, 6, 8, 9, 10, 11, 12, 13, 14, 18, 19}; // the levels Oni has
    146                 char choice = 0;
    147                
    148                 //SetCurrentDirectory("C:/Program Files/Oni/edition/install");
    149                 char levelnum[3];
     38        int parts_done = 0;
     39        remove("Globalize.log");
     40        ofstream logfile("Globalize.log");
     41        logfile << "Globalization started " << to_simple_string(start_time) << endl;
     42       
     43        try {  // the levels Oni has...probably should have made a string array. Oops.
     44                char levels_cstr[15][3] = {"0", "1", "2", "3", "4", "6", "8", "9", "10", "11", "12", "13", "14", "18", "19"};
     45                vector<string> levels;
     46                for (int f = 0; f < 15; f++) {
     47                        levels.push_back(levels_cstr[f]);
     48                }
     49
    15050                path Characters = "../GameDataFolder/level0_Characters";
    15151                path Particles = "../GameDataFolder/level0_Particles";
     
    15656                path TRAC = Animations / "level0_TRAC";
    15757                path TRAM = Animations / "level0_TRAM";
    158                 /*
    159                  if (exists("../GameDataFolder/"))
    160                  {
    161                  //cout << "\nIt looks like you've already globalized Oni's data.\nDo you want to re-globalize?\n(This will erase existing mods installed to the AE's game data.)"
    162                  //      << "\n1. Re-globalize"
    163                  //      << "\n2. Return to main menu\n";
    164                  //choice = cin.get();
    165                  cin.ignore(128, '\n');
    166                  if (choice == '1')
    167                  remove_all("../GameDataFolder"); // remove AE GDF
    168                  if (choice == '2')
    169                  return 0;
    170                  }
    171                  */
     58               
     59                vector<path> GDFPaths;
     60                GDFPaths.push_back(Particles);
     61                GDFPaths.push_back(Textures);
     62                GDFPaths.push_back(Sounds);
     63                GDFPaths.push_back(TRAC);
     64                GDFPaths.push_back(TRAM);
     65               
     66                path VanillaCharacters = "VanillaDats/level0_Final/level0_Characters/level0_Characters.oni";
     67                path VanillaParticles = "VanillaDats/level0_Final/level0_Particles/level0_Particles.oni";
     68                path VanillaTextures  = "VanillaDats/level0_Final/level0_Textures/level0_Textures.oni";
     69                path VanillaSounds = "VanillaDats/level0_Final/level0_Sounds/level0_Sounds.oni";
     70                path VanillaAnimations = "VanillaDats/level0_Final/level0_Animations/level0_Animations.oni";
     71                path VanillaTRAC = "VanillaDats/level0_Final/level0_Animations/level0_TRAC.oni";
     72                path VanillaTRAM = "VanillaDats/level0_Final/level0_Animations/level0_TRAM.oni";
     73               
     74                vector<path> VanillaPaths;
     75               
     76                VanillaPaths.push_back(VanillaParticles);
     77                VanillaPaths.push_back(VanillaTextures);
     78                VanillaPaths.push_back(VanillaSounds);
     79                VanillaPaths.push_back(VanillaTRAC);
     80                VanillaPaths.push_back(VanillaTRAM);
     81               
     82                setStatusArea("Removing old GameDataFolder...\n");
     83                logfile <<  "Removing old GameDataFolder...\n";
     84                remove_all( "../GameDataFolder/" );
     85                setStatusArea("Creating needed directories...");
     86                logfile <<  "Creating needed directories...\n";
    17287                create_directory( "../GameDataFolder/" );
     88               
    17389                create_directory( "packages" );
    174                 if (exists("packages/VanillaDats")) remove_all("packages/VanillaDats");
    175                 create_directory( "packages/VanillaDats" );
    176                
    177                 create_directory( "packages/VanillaDats/level0_Final/" );
     90               
     91                if (exists("VanillaDats")) remove_all("VanillaDats");
     92                create_directory( "VanillaDats" );
     93                create_directory( "VanillaDats/level0_Final/" );
    17894                create_directory( Characters );
    17995                create_directory( Particles );
     
    184100                create_directory( TRAC );
    185101                create_directory( TRAM );
     102                int num_levels = 0;
     103                for(int i = 1; i < 15; i++)
     104                {
     105                        if (exists("../../GameDataFolder/level" + levels[i] + "_Final.dat")) {
     106                                num_levels++;
     107                               
     108                        }
     109                }
     110                logfile << "Exporting and moving...\n\n";
     111                int total_steps =  8 + 2 * num_levels;
    186112               
    187113                for(int i = 0; i < 15; i++)
    188                 {
    189                         sprintf(levelnum,"%d",levels[i]); // int to char array
    190                         exists("../../GameDataFolder/level" + (string)levelnum + "_Final");
    191                         system((strOniSplit + " -export ../GameDataFolder/level" + (string)levelnum + "_Final ../../GameDataFolder/level" + (string)levelnum + "_Final.dat").c_str());
    192                        
    193                         create_directory( "packages/VanillaDats/level" + (string)levelnum + "_Final" ); //remember to cast your arrays as strings :)
    194                         create_directory( "packages/VanillaDats/level" + (string)levelnum + "_Final/level" + (string)levelnum + "_Final" );
    195                        
    196                         directory_iterator end_iter;
    197                         for ( directory_iterator dir_itr( "../GameDataFolder/level" + (string)levelnum + "_Final" ); dir_itr != end_iter; ++dir_itr )
    198                         {
    199                                 //cout << dir_itr->path().filename();
    200                                 if ( is_regular_file( dir_itr->status() ) )
     114                {                       
     115                        if (exists("../../GameDataFolder/level" + levels[i] + "_Final.dat")) {
     116                                logfile << "level" << levels[i] << "_Final\n";
     117                                logfile << "\tExporting level" << levels[i] << "_Final.dat\n";
     118                                setStatusArea("Step " + lexical_cast<std::string>(parts_done + 1) + "/" + lexical_cast<std::string>(total_steps) + " exporting level" + levels[i]+"_Final.dat");
     119                                create_directory( "../GameDataFolder/level" + levels[i] + "_Final" );
     120                                system((strOniSplit + " -export ../GameDataFolder/level" + levels[i] + "_Final ../../GameDataFolder/level" + levels[i] + "_Final.dat").c_str());
     121                                create_directory( "VanillaDats/level" + levels[i] + "_Final" );
     122                                create_directory( "VanillaDats/level" + levels[i] + "_Final/level" + levels[i] + "_Final" );
     123                               
     124                                //Moves the AKEV and other files into a safe directory so that level specific textures are not globalized...
     125                                if ( strcmp(levels[i].c_str(), "0") ){
     126                                        create_directory( "../GameDataFolder/level" + levels[i] + "_Final/AKEV" );
     127                                        system((strOniSplit + " -move:overwrite ../GameDataFolder/level" + levels[i] + "_Final/AKEV ../GameDataFolder/level" + levels[i] + "_Final/AKEV*.oni").c_str());
     128                                       
     129                                }
     130                               
     131                                directory_iterator end_iter;
     132                                for ( directory_iterator dir_itr( "../GameDataFolder/level" + levels[i] + "_Final" ); dir_itr != end_iter; ++dir_itr )
    201133                                {
     134                                        if ( is_regular_file( dir_itr->status() ) )
     135                                        {
     136                                                if ( dir_itr->path().filename().substr(0,8) == "TXMPfail" ||
     137                                                        dir_itr->path().filename().substr(0,9) == "TXMPlevel" ||
     138                                                        ( dir_itr->path().filename().substr(0,4) == "TXMP" && dir_itr->path().filename().find("intro")!=string::npos) ||
     139                                                        dir_itr->path().filename().substr(0,4) == "TXMB" ||
     140                                                        dir_itr->path().filename() == "M3GMpowerup_lsi.oni" ||
     141                                                        dir_itr->path().filename() == "TXMPlsi_icon.oni" ||
     142                                                        ( dir_itr->path().filename().substr(0,4) == "TXMB" && dir_itr->path().filename().find("splash_screen.oni")!=string::npos)       )
     143                                                {
     144                                                        cout <<dir_itr->path().filename() << "\n";
     145                                                        create_directory( dir_itr->path().parent_path() / "NoGlobal"); 
     146                                                        if(!exists( dir_itr->path().parent_path() / "NoGlobal" / dir_itr->filename())) rename(dir_itr->path(), dir_itr->path().parent_path() / "NoGlobal" /
     147                                                                                                                                                                                                                                  dir_itr->filename());
     148                                                        else remove(dir_itr->path());
     149                                                }
     150                                                else if (dir_itr->path().filename().substr(0,4) == "TRAC"
     151                                                                 ) {
     152                                                        cout <<dir_itr->path().filename() << "\n";
     153                                                        if(!exists( TRAC / dir_itr->filename())) rename(dir_itr->path(), TRAC / dir_itr->filename());
     154                                                        else remove(dir_itr->path());
     155                                                }
     156                                                else if (dir_itr->path().filename().substr(0,4) == "TRAM") {
     157                                                        cout <<dir_itr->path().filename() << "\n";
     158                                                        if(!exists( TRAM / dir_itr->filename())) rename(dir_itr->path(), TRAM / dir_itr->filename());
     159                                                        else remove(dir_itr->path());
     160                                                }
     161                                                else if (dir_itr->path().filename().substr(0,4) == "ONSK" ||
     162                                                                 dir_itr->path().filename().substr(0,4) == "TXMP") {
     163                                                        cout <<dir_itr->path().filename() << "\n";\
     164                                                        create_directory( dir_itr->path().parent_path() / "TexFix");   
     165                                                        if(!exists( Textures / dir_itr->filename())) rename(dir_itr->path(), Textures / dir_itr->filename());
     166                                                }
     167                                                else if (dir_itr->path().filename().substr(0,4) == "ONCC"
     168                                                                 || dir_itr->path().filename().substr(0,4) == "TRBS"
     169                                                                 || dir_itr->path().filename().substr(0,4) == "ONCV"
     170                                                                 || dir_itr->path().filename().substr(0,4) == "ONVL"
     171                                                                 || dir_itr->path().filename().substr(0,4) == "TRMA"
     172                                                                 || dir_itr->path().filename().substr(0,4) == "TRSC"
     173                                                                 || dir_itr->path().filename().substr(0,4) == "TRAS") {
     174                                                        cout <<dir_itr->path().filename() << "\n";
     175                                                        if(!exists( Characters / dir_itr->filename())) rename(dir_itr->path(), Characters / dir_itr->filename());
     176                                                        else remove(dir_itr->path());
     177                                                }
     178                                                else if (dir_itr->path().filename().substr(0,4) == "OSBD"
     179                                                                 || dir_itr->path().filename().substr(0,4) == "SNDD") {
     180                                                        cout << dir_itr->path().filename() << "\n";
     181                                                        if(!exists( Sounds / dir_itr->filename())) rename(dir_itr->path(), Sounds / dir_itr->filename());
     182                                                        else remove(dir_itr->path());
     183                                                }
     184                                                else if (dir_itr->path().filename().substr(0,5) == "BINA3"
     185                                                                 || dir_itr->path().filename().substr(0,10) == "M3GMdebris"
     186                                                                 || dir_itr->path().filename() == "M3GMtoxic_bubble.oni"
     187                                                                 || dir_itr->path().filename().substr(0,8) == "M3GMelec"
     188                                                                 || dir_itr->path().filename().substr(0,7) == "M3GMrat"
     189                                                                 || dir_itr->path().filename().substr(0,7) == "M3GMjet"
     190                                                                 || dir_itr->path().filename().substr(0,9) == "M3GMbomb_"
     191                                                                 || dir_itr->path().filename() == "M3GMbarab_swave.oni"
     192                                                                 || dir_itr->path().filename() == "M3GMbloodyfoot.oni"
     193                                                                 ){
     194                                                        cout <<dir_itr->path().filename() << "\n";
     195                                                        if(!exists( Particles / dir_itr->filename())) rename(dir_itr->path(), Particles / dir_itr->filename());
     196                                                        else remove(dir_itr->path());
     197                                                }
     198                                                else if (dir_itr->path().filename().substr(0,4) == "AGDB"
     199                                                                 || dir_itr->path().filename().substr(0,4) == "TRCM") {
     200                                                        cout <<dir_itr->path().filename() << "\n";
     201                                                       
     202                                                        if(!exists( Archive / dir_itr->filename())) rename(dir_itr->path(), Archive / dir_itr->filename());
     203                                                        else remove(dir_itr->path());
     204                                                }
     205                                                else if (dir_itr->path().filename().substr(0,4) == "ONWC") { //fix for buggy ONWC overriding
     206                                                        cout <<dir_itr->path().filename() << "\n";
     207                                                       
     208                                                        if(!exists( "VanillaDats/level0_Final/level0_Final/" +  dir_itr->filename()))
     209                                                                rename(dir_itr->path(), "VanillaDats/level0_Final/level0_Final/" +  dir_itr->filename());
     210                                                        else remove(dir_itr->path());
     211                                                }
     212                                               
     213                                                if (exists(dir_itr->path())) {
     214                                                       
     215                                                }
     216                                                else {
     217                                                        //logfile << "\tMoved file: " << dir_itr->path().filename() << "\n";
     218                                                }
     219                                        }
    202220                                       
    203                                         if ( dir_itr->path().filename().substr(0,8) == "TXMPfail" ||
    204                                                 dir_itr->path().filename().substr(0,9) == "TXMPlevel" ||
    205                                                 ( dir_itr->path().filename().substr(0,4) == "TXMP" && dir_itr->path().filename().find("intro")!=string::npos) ||
    206                                                 dir_itr->path().filename().substr(0,4) == "TXMB" ||
    207                                                 dir_itr->path().filename() == "M3GMpowerup_lsi.oni" ||
    208                                                 dir_itr->path().filename() == "TXMPlsi_icon.oni" ||
    209                                                 ( dir_itr->path().filename().substr(0,4) == "TXMB" && dir_itr->path().filename().find("splash_screen.oni")!=string::npos)       )
    210                                         {
    211                                                 cout <<dir_itr->path().filename() << "\n";
    212                                                 create_directory( dir_itr->path().parent_path() / "NoGlobal"); 
    213                                                 if(!exists( dir_itr->path().parent_path() / "NoGlobal" / dir_itr->filename())) rename(dir_itr->path(), dir_itr->path().parent_path() / "NoGlobal" /
    214                                                                                                                                                                                                                           dir_itr->filename());
    215                                                 else remove(dir_itr->path());
    216                                         }
    217                                         else if (dir_itr->path().filename().substr(0,4) == "TRAC") {
    218                                                 cout <<dir_itr->path().filename() << "\n";
    219                                                 if(!exists( TRAC / dir_itr->filename())) rename(dir_itr->path(), TRAC / dir_itr->filename());
    220                                                 else remove(dir_itr->path());
    221                                         }
    222                                         else if (dir_itr->path().filename().substr(0,4) == "TRAM") {
    223                                                 cout <<dir_itr->path().filename() << "\n";
    224                                                 if(!exists( TRAM / dir_itr->filename())) rename(dir_itr->path(), TRAM / dir_itr->filename());
    225                                                 else remove(dir_itr->path());
    226                                         }
    227                                         else if (dir_itr->path().filename().substr(0,4) == "ONSK" ||
    228                                                          dir_itr->path().filename().substr(0,4) == "TXMP") {
    229                                                 cout <<dir_itr->path().filename() << "\n";\
    230                                                 create_directory( dir_itr->path().parent_path() / "TexFix");   
    231                                                 if(!exists( Textures / dir_itr->filename())) rename(dir_itr->path(), Textures / dir_itr->filename());
    232                                                 //rename(dir_itr->path(), dir_itr->path().parent_path() / "TexFix" / dir_itr->filename());
    233                                         }
    234                                         else if (dir_itr->path().filename().substr(0,4) == "ONCC"
    235                                                          || dir_itr->path().filename().substr(0,4) == "TRBS"
    236                                                          || dir_itr->path().filename().substr(0,4) == "TRMA"
    237                                                          || dir_itr->path().filename().substr(0,4) == "TRSC"
    238                                                          || dir_itr->path().filename().substr(0,4) == "TRAS") {
    239                                                 cout <<dir_itr->path().filename() << "\n";
    240                                                 if(!exists( Characters / dir_itr->filename())) rename(dir_itr->path(), Characters / dir_itr->filename());
    241                                                 else remove(dir_itr->path());
    242                                         }
    243                                         else if (dir_itr->path().filename().substr(0,4) == "OSBD"
    244                                                          || dir_itr->path().filename().substr(0,4) == "SNDD") {
    245                                                 cout << dir_itr->path().filename() << "\n";
    246                                                 if(!exists( Sounds / dir_itr->filename())) rename(dir_itr->path(), Sounds / dir_itr->filename());
    247                                                 else remove(dir_itr->path());
    248                                         }
    249                                         else if (dir_itr->path().filename().substr(0,5) == "BINA3"
    250                                                          || dir_itr->path().filename().substr(0,10) == "M3GMdebris"
    251                                                          || dir_itr->path().filename() == "M3GMtoxic_bubble.oni"
    252                                                          || dir_itr->path().filename().substr(0,8) == "M3GMelec"
    253                                                          || dir_itr->path().filename().substr(0,7) == "M3GMrat"
    254                                                          || dir_itr->path().filename().substr(0,7) == "M3GMjet"
    255                                                          || dir_itr->path().filename().substr(0,9) == "M3GMbomb_"
    256                                                          || dir_itr->path().filename() == "M3GMbarab_swave.oni"
    257                                                          || dir_itr->path().filename() == "M3GMbloodyfoot.oni"
    258                                                          ){
    259                                                 cout <<dir_itr->path().filename() << "\n";
    260                                                 if(!exists( Particles / dir_itr->filename())) rename(dir_itr->path(), Particles / dir_itr->filename());
    261                                                 else remove(dir_itr->path());
    262                                         }
    263                                         else if (dir_itr->path().filename().substr(0,4) == "AGDB"
    264                                                          || dir_itr->path().filename().substr(0,4) == "TRCM") {
    265                                                 cout <<dir_itr->path().filename() << "\n";
    266                                                
    267                                                 if(!exists( Archive / dir_itr->filename())) rename(dir_itr->path(), Archive / dir_itr->filename());
    268                                                 else remove(dir_itr->path());
    269                                         }
    270                                 }
     221                                       
     222                                       
     223                                }
     224                               
     225                                logfile << "\tCleaning up TXMPs...\n";
     226                                system( (strOniSplit + " -move:delete " + Textures.string() + " ../GameDataFolder/level" + levels[i] + "_Final/TXMP*.oni").c_str());
    271227                               
    272228                               
    273                         }
    274                         system( (strOniSplit + " -move:delete " + Textures.string() + " ../GameDataFolder/level" + (string)levelnum + "_Final/TXMP*.oni").c_str());
    275                        
    276                 }
    277                
     229                                if ( strcmp(levels[i].c_str(), "0") ){
     230                                        system((strOniSplit + " -move:overwrite ../GameDataFolder/level" + levels[i] + "_Final ../GameDataFolder/level" + levels[i] + "_Final/AKEV/AKEV*.oni").c_str());
     231                                        remove(  "../GameDataFolder/level" + levels[i] + "_Final/AKEV" );
     232                                }
     233                               
     234                                parts_done++;
     235                               
     236                                setProgressBar( (int)(1000 * (float)(parts_done) / (float)(total_steps) ));
     237                               
     238                        }
     239                }
     240                logfile << "Reimporting levels\n";
    278241                for (int i = 0; i < 15; i++)
    279242                {
    280                         sprintf(levelnum,"%d",levels[i]);
    281                         system( (strOniSplit + " " + strImportOption + " ../GameDataFolder/level" + levelnum + "_Final packages/VanillaDats/level" + levelnum + "_Final/level"
    282                                          + levelnum + "_Final/level" + levelnum + "_Final.oni").c_str());
    283                 }
    284                 path VanillaCharacters = "packages/VanillaDats/level0_Final/level0_Characters/level0_Characters.oni";
    285                 path VanillaParticles = "packages/VanillaDats/level0_Final/level0_Particles/level0_Particles.oni";
    286                 path VanillaTextures  = "packages/VanillaDats/level0_Final/level0_Textures/level0_Textures.oni";
    287                 path VanillaSounds = "packages/VanillaDats/level0_Final/level0_Sounds/level0_Sounds.oni";
    288                 path VanillaAnimations = "packages/VanillaDats/level0_Final/level0_Animations/level0_Animations.oni";
    289                 path VanillaTRAC = "packages/VanillaDats/level0_Final/level0_Animations/level0_TRAC.oni";
    290                 path VanillaTRAM = "packages/VanillaDats/level0_Final/level0_Animations/level0_TRAM.oni";
    291                 create_directory( VanillaCharacters.parent_path() );
     243                        logfile << "\tReimporting level" << levels[i] << "_Final.oni\n";
     244                        setStatusArea("Step " + lexical_cast<std::string>(parts_done + 1) + "/" + lexical_cast<std::string>(total_steps) + " reimporting level" + levels[i]+"_Final.oni");
     245                        logfile << (strOniSplit + " " + strImportOption + " ../GameDataFolder/level" + levels[i] + "_Final VanillaDats/level" + levels[i] + "_Final/level"
     246                                                + levels[i] + "_Final/level" + levels[i] + "_Final.oni >> Globalize.log").c_str() << '\n';
     247                        string sys_str = (strOniSplit + " " + strImportOption + " ../GameDataFolder/level" + levels[i] + "_Final VanillaDats/level" + levels[i] + "_Final/level"
     248                                                          + levels[i] + "_Final/level" + levels[i] + "_Final.oni");
     249                        system(sys_str.c_str() );
     250                        setProgressBar( (int)(1000 * (float)(parts_done) / (float)(total_steps) ));
     251                        parts_done++;
     252                }
    292253                create_directory( VanillaParticles.parent_path() );
    293254                create_directory( VanillaTextures.parent_path() );
    294255                create_directory( VanillaSounds.parent_path() );
    295256                create_directory( VanillaAnimations.remove_filename() );
    296                 system((strOniSplit + " " + strImportOption + " " + Characters.string() + " " + VanillaCharacters.string()).c_str());
    297                 system((strOniSplit + " " + strImportOption + " " + Particles.string() + " " + VanillaParticles.string()).c_str());
    298                 system((strOniSplit + " " + strImportOption + " " + Textures.string() + " " + VanillaTextures.string()).c_str());
    299                 //system((strOniSplit   + " " + strImportOption + (string)" " + Animations.string() + (string)" " + VanillaAnimations.string()).c_str());
    300                 system((strOniSplit + " " + strImportOption + " " + TRAC.string() + " " + VanillaTRAC.string()).c_str());
    301                 system((strOniSplit + " " + strImportOption + " " + Sounds.string() + " " + VanillaSounds.string()).c_str());
    302                 system((strOniSplit + " " + strImportOption + " " + TRAM.string() + " " + VanillaTRAM.string()).c_str());
    303                
    304                 create_directory("../GameDataFolder/IGMD");
     257               
     258                for(unsigned int j = 0; j < GDFPaths.size(); j++) {
     259                        logfile << "\tReimporting " << GDFPaths[j].filename() << ".oni\n";
     260                        setStatusArea("Step " + lexical_cast<std::string>(parts_done + 1) + "/" + lexical_cast<std::string>(total_steps) + ": reimporting " + GDFPaths[j].filename() );
     261                        system((strOniSplit + " " + strImportOption + " " + GDFPaths[j].string() + " " + VanillaPaths[j].string()).c_str());
     262                        parts_done++;
     263                        setProgressBar( (int)(1000 * (float)(parts_done) / (float)(total_steps) ));
     264                }
     265                logfile << "\nMoving level0_Characters\n";
     266                setStatusArea("Step " + lexical_cast<std::string>(parts_done + 1) + "/" + lexical_cast<std::string>(total_steps) + ": moving level0_Characters" );     
     267                copy((path)"../GameDataFolder/level0_Characters", (path)("VanillaDats/level0_Final"));
     268                GDFPaths.push_back( Characters );
     269                for(int i = 0; i < GDFPaths.size(); i++)
     270                {
     271                        directory_iterator end_iter;
     272                        for ( directory_iterator dir_itr( GDFPaths[i] ); dir_itr != end_iter; ++dir_itr )
     273                        {
     274                                try
     275                                {
     276                                        rename(dir_itr->path(), "../GameDataFolder/level0_Final/" + dir_itr->path().filename() );
     277                                }
     278                                catch(exception &ex) {
     279                                       
     280                                }
     281                        }
     282                }
     283
     284                create_directory((path)"../GameDataFolder/IGMD");
    305285                copy((path)"packages/VanillaBSL/IGMD", (path)"../GameDataFolder");
    306         }
    307         catch (exception ex) {
    308                 cout << ex.what();
    309         }
     286                setProgressBar( 1000 );
     287               
     288                if(exists("../../persist.dat"))
     289                        if(!exists("../persist.dat"))
     290                       
     291                        //TODO: Concatenate level0 Dirs.
     292                       
     293                                copy("../../persist.dat","..");
     294                if(exists("../../key_config.txt"))
     295                        if(!exists("../key_config.txt"))
     296                                copy("../../key_config.txt","..");
     297               
     298#ifndef WIN32
     299                /* 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).
     300                 Tests for presence of prefs with [ -f ] before doing anything so it doesn't create a partial prefs file -- just in case user has never
     301                 run Oni before :-p */
     302                string fullAEpath = escapePath(system_complete(".").parent_path().parent_path().string()); // get full path for edition/
     303                char prefsCommand[300] = "[ -f ~/Library/Preferences/com.godgames.oni.plist ] && defaults write com.godgames.oni RetailInstallationPath -string '";
     304                strcat(prefsCommand, fullAEpath.c_str()); // get path of Edition/ folder (Oni wants the folder that *contains* the GDF)
     305                strcat(prefsCommand, "'"); // path string is enclosed in single quotes to avoid the need to escape UNIX-unfriendly characters
     306                system(prefsCommand);
     307#endif
     308               
     309                setStatusArea((string)"Done! Now select your mod packages and click install.");
     310        }
     311        catch (exception & ex) {
     312                setStatusArea("Warning, handled exception: " + (string)ex.what());
     313        }
     314       
     315        ptime end_time(second_clock::local_time());
     316        time_period total_time (start_time, end_time);
     317        logfile << "\n\nGlobalization ended " << to_simple_string(end_time) << "\nThe process took " << total_time.length();
     318        logfile.close();
     319        busy = 0;
    310320        return err;
    311321}
    312322
    313 int installPackages(void)
    314 {
    315         bool installed_something = 0;
    316         int err = 0;
    317         ModPackage package;
    318         vector<string> installed_packages;
    319         vector<ModPackage> packages;
    320         vector<ModPackage>::iterator iter;
    321         vector<string> installString;
    322        
    323         iter = packages.begin();
    324         packages = getPackages();
    325         vector<string> installedMods = getInstallString();
    326        
    327         if (packages.empty())
    328         {
    329                 cout << "Error: You have no packages!\n";
    330                 return 0;
    331         }
    332        
    333         cout << "Detecting installed packages...\n";
    334        
    335         int index = 1;
    336         char choice = '0';
    337        
    338         for (vector<ModPackage>::iterator package_iter = packages.begin(); package_iter != packages.end(); ++package_iter)
    339         {
    340                 if (!binary_search(installedMods.begin(), installedMods.end(), package_iter->modStringName))
    341                 { //package_iter->isInstalled :< I forgot about this...
    342                         //cout << index << " ";
    343                         system(strClsCmd);
    344                         cout << (*package_iter).name << "\n";
    345                         for (int character = 1; character <= (*package_iter).name.length() - 1; character++) cout << '-';
    346                         cout << "\n"
    347                         << (*package_iter).readme << "\n\n"
    348                         << "Please enter a number choice\n"
    349                         << " 1. Add\n"
    350                         << " 2. Don't Add\n"
    351                         << "";
    352                         index++;
    353                         choice = 0;
    354                        
    355                         do
    356                         {
    357                                 choice = cin.get();
    358                                 cin.ignore(1280, '\n');
    359                         } while(choice == 0);
    360                        
    361                         if (choice == '1')
    362                         {
    363                                 cout << "\nInstalling...\n\n";
    364                                 if (package_iter->hasOnis || (package_iter->hasDeltas /*(*package_iter).isUnpacked */ ))
    365                                 {
    366                                         installed_something = 1;
    367                                         installedMods.push_back(package_iter->modStringName);
    368                                         system(strPauseCmd);
    369                                 }
    370                         }
    371                 }
    372         }
    373         if (index == 1)
    374         {
    375                 cout << "Warning: All packages are already installed\n";
    376                 //would you like to recombine your data?
    377                 return 0;
    378         }
    379         if (installed_something == 0)
    380         {
    381                 cout << "Warning: You didn't add anything!\n";
    382                 //would you like to recombine your data?
    383                 return 0;
    384         }
    385        
    386         sort(installedMods.begin(), installedMods.end());
    387         //system(Onisplit.c_str());
    388         recompileAll(installedMods);
    389         system(strPauseCmd);
    390        
    391         return err;
    392 }
    393 
    394 int uninstallPackages(void)
    395 {
    396         int err = 0;
    397         ModPackage package;
    398         vector<string> installed_packages;
    399         vector<ModPackage> packages;
    400         vector<ModPackage>::iterator iter;
    401         vector<string> installString;
    402        
    403         iter = packages.begin();
    404         packages = getPackages();
    405        
    406        
    407         cout << "Detecting installed packages...\n";
    408        
    409         vector<string> installedMods = getInstallString();
    410        
    411         if (packages.empty())
    412         {
    413                 cout << "Error: You have no packages!\n";
    414                 return 0;
    415         }
    416        
    417         int index = 0;
    418         int uninstalled_something = 0;
    419         char choice = '0';
    420        
    421         for (vector<ModPackage>::iterator package_iter = packages.begin(); package_iter != packages.end(); ++package_iter)
    422         {
    423                 if (binary_search(installedMods.begin(), installedMods.end(), package_iter->modStringName))
    424                 { //package_iter->isInstalled :< I forgot about this...
    425                         //cout << index << " ";
    426                         system(strClsCmd);
    427                         cout << (*package_iter).name << "\n";
    428                         for (int character = 1; character <= (*package_iter).name.length() - 1; character++) cout << '-';
    429                         cout << "\n"
    430                         << (*package_iter).readme << "\n\n"
    431                         << "Please enter a number choice\n"
    432                         << " 1. Remove\n"
    433                         << " 2. Don't Remove\n"
    434                         << "";
    435                        
    436                         choice = 0;
    437                        
    438                         do
    439                         {
    440                                 choice = cin.get();
    441                                 cin.ignore(1280, '\n');
    442                         } while(choice == 0);
    443                        
    444                         if (choice == '1')
    445                         {
    446                                 cout << "\nUninstalling...\n\n";
    447                                 installedMods.erase( installedMods.begin() + (index) );
    448                                 system(strPauseCmd);
    449                                 uninstalled_something = 1;
    450                                
    451                         }
    452                         else {
    453                                 index++;
    454                         }
    455                 }
    456         }
    457         if ( uninstalled_something == 0 )
    458         {
    459                 if (index == 0) //bad practice, I need to implement a second vector or something. Meh.
    460                 {
    461                         cout << "\nWarning: You have no installed packages!";
    462                 }
    463                 else
    464                 {
    465                         cout << "\nWarning: You didn't remove anything!";
    466                 }
    467                 //would you like to recombine your data?
    468                 return 0;
    469                
    470         }       
    471         sort(installedMods.begin(), installedMods.end());
    472         //system(Onisplit.c_str());
    473         recompileAll(installedMods);
    474         system(strPauseCmd);
    475        
    476         return err;
    477 }
    478 
    479 int listInstalledPackages(void)
    480 {
    481         cout << "\nThis feature not yet implemented.\n\n";
    482        
    483         return 0;
    484 }
    485 
    486 int printInstallerInfo(void)
    487 {
    488         cout << "\nAE/Mod Installer\n";
    489         cout << "version " << strInstallerVersion << "\n";
    490         cout << "by Gumby & Iritscen\n";
    491         cout << "see http://oni.bungie.org/community/forums for more info\n\n";
    492        
    493         return 0;
    494 }
    495 
    496 vector<ModPackage> getPackages(void)
     323vector<ModPackage> getPackages(string packageDir)
    497324{
    498325        vector<ModPackage> packages;
    499         packages.reserve(65536); // come on, we shouldn't need this much space...right?!
     326        packages.reserve(256);
    500327        fstream file;
    501328        string filename = "\0";
     
    504331        try
    505332        {
    506                 directory_iterator end_iter;
    507                 for (directory_iterator dir_itr("./packages"); dir_itr != end_iter; ++dir_itr)
     333                for (directory_iterator dir_itr(packageDir), end_itr; dir_itr != end_itr; ++dir_itr)
    508334                {
    509335                        file.open((dir_itr->path().string() + "/" + MODINFO_CFG).c_str());
    510                         //cout << filename << "\n";
    511336                       
    512337                        if(!file.fail())
    513338                        {
    514                                 //cout << dir_itr->path().string() + MODINFO_CFG;
    515339                                //would prefer to push a pointer to a package, but this will do for now
    516340                                packages.push_back(fileToModPackage(file));
     
    519343                        file.clear();
    520344                }
     345                sort(packages.begin(), packages.end());
    521346        }
    522347        catch (const std::exception & ex)
     
    559384                vector<string>::iterator iter;
    560385                tokenize(line, tokens);                                 //string to vector of "words"
    561                 if (tokens.capacity() >= 2) {                   //make sure they are using enough stuff
     386                if (tokens.capacity() >= 3) {                   //make sure they are using enough stuff
    562387                        iter = tokens.begin();                          //what word we are on, starts at first word
    563                         /*
     388                        /* TODO: Get this "required Installer version" code working
    564389                         if (!AEInstallVersion.compare(*iter))
    565390                         If mod is too old, skip this mod.
    566391                         */
    567392                        /*else*/if (!NameOfMod.compare(*iter))  {       //if it contains the name
    568                                 for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
    569                                         if (ARROW.compare(*iter) && NameOfMod.compare(*iter)) {                 //ignores "->" and "NameOfMod"
    570                                                 //cout << *iter;
    571                                                 //cout << " ";
     393                                for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     // iterates through the words, ends if it reaches the end of the line or a "//" comment
     394                                        if (ARROW.compare(*iter) && NameOfMod.compare(*iter)) {                 // ignores "->" and "NameOfMod"
    572395                                                package.name += *iter + " ";
    573396                                        }
     
    583406                        else if (!HasOnis.compare(*iter)) {
    584407                                iter++; iter++; 
    585                                 if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasOnis = 1; //Gotta love c++'s lack of a standard case-insensitive
    586                                 else if (!HasBSL.compare(*iter)) { // string comparer...I know my implementation here sucks. I need to change it to check each character one by one. At the moment,
    587                                 iter++; iter++;}  // using "YFR" would probably set it off. :<
    588                                
    589                                 if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasBSL = 1;
     408                                if ( boost::iequals(*iter, "Yes")) package.hasOnis = 1;
     409                        }       
     410                        else if (!HasBSL.compare(*iter)) {
     411                                if(toupper((*iter)[0]) == 'Y' && toupper((*iter)[1]) == 'E' && toupper((*iter)[2]) == 'S') package.hasBSL = true;
     412                                else if ( boost::iequals(*iter, "Addon")) package.hasAddon = true;
    590413                        }
    591414                        else if (!HasDeltas.compare(*iter)) {
     
    604427                                iter++; iter++; 
    605428                                if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.globalNeeded = 1;
    606                                 else if (toupper((*iter)[0]) + toupper((*iter)[1]) == 'N' + 'O') package.globalNeeded = 1; //Really the only place where checking for "No" is important atm.
     429                                else if (toupper((*iter)[0]) + toupper((*iter)[1]) == 'N' + 'O') package.globalNeeded = 1; // only place where checking for "No" is important atm.
    607430                        }
    608431                        else if (!Category.compare(*iter))  {   
    609                                 for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
    610                                         if (ARROW.compare(*iter) && Category.compare(*iter)) {                  //ignores "->" and "Category"
    611                                                 //cout << *iter;
    612                                                 //cout << " ";
     432                                for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     // iterates through the words, ends if it reaches end of line or a "//" comment
     433                                        if (ARROW.compare(*iter) && Category.compare(*iter)) {                  // ignores "->" and "Category"
    613434                                                package.category += *iter + " ";
    614435                                        }
     
    616437                        }
    617438                        else if (!Creator.compare(*iter))  {    //if it contains the name
    618                                 for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
    619                                         if (ARROW.compare(*iter) && Creator.compare(*iter)) {                   //ignores "->" and "Category"
    620                                                 //cout << *iter;
    621                                                 //cout << " ";
     439                                for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     // iterates through the words, ends if it reaches end of line or a "//" comment
     440                                        if (ARROW.compare(*iter) && Creator.compare(*iter)) {                   // ignores "->" and "Creator"
    622441                                                package.creator += *iter + " ";
    623442                                        }
     
    625444                        }
    626445                        else if (!Readme.compare(*iter))  {     //if it contains the name
    627                                 for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
    628                                         if (ARROW.compare(*iter) && Readme.compare(*iter)) {                    //ignores "->" and "Category"
     446                                for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     // iterates through the words, ends if it reaches end of line or a "//" comment
     447                                        if (ARROW.compare(*iter) && Readme.compare(*iter)) {                    // ignores "->" and "Readme"
    629448                                                if(!(*iter).compare("\\n")) package.readme += '\n';
    630449                                                else package.readme += *iter + " ";
     
    635454               
    636455        }
    637         package.doOutput();
     456
    638457        return package;
    639458}
    640459
    641460void recompileAll(vector<string> installedMods)
    642 {
    643 #ifdef WIN32
    644         RedirectIOToConsole();
    645         HWND hWnd = GetConsoleWindow();
    646         ShowWindow( hWnd, SW_HIDE );
    647 #endif
    648         setStatusArea("Importing levels...");
    649         //setStatusArea("Recompiling Data...");
    650         path vanilla_dir = "./packages/VanillaDats/";
     461{try {
     462        busy = 1;
     463        using namespace boost::gregorian;
     464        using namespace boost::posix_time;
     465        using boost::lexical_cast;
     466        using boost::bad_lexical_cast;
     467        path vanilla_dir = "./VanillaDats/";
    651468        string importCommand = "";
    652         char statusString[128];
    653469        int numberOfDats = 0;
    654470        int j = 1;
    655471        string datString;
     472               
     473        setStatusArea("Importing levels...");
     474       
    656475        std::stringstream out;
    657476       
    658        
     477        ptime start_time(second_clock::local_time());
    659478        clearOldDats();
    660         remove("Onisplit.log");
    661         if(splitInstances == SPLIT){
     479       
     480        if(exists("Install.log")) remove("Install.log");
     481        ofstream logfile("Install.log");
     482        logfile << "Mod Installation started " << to_simple_string(start_time) << endl;
     483        logfile.close();
     484       
     485        if(splitInstances == true)
     486        {
    662487                recursive_directory_iterator end_iter;
    663488               
     
    672497                                }
    673498                        }
    674                         catch(exception ex) {
     499                        catch(exception & ex) {
     500                                remove("Install.log");
     501                                ofstream logfile("Install.log");
    675502                               
    676                         }
    677                 }
    678                
    679                 //recursive_directory_iterator end_iter;
    680                
    681                
    682                 out << numberOfDats;
    683                 datString = out.str();
     503                                logfile << "Warning, exception " << ex.what() << "!";
     504                                setStatusArea("Warning, exception " + (string)ex.what() + "!");
     505                                logfile.close();       
     506                        }
     507                }
    684508                try {
     509                        out << numberOfDats;
     510                        datString = out.str();
    685511                        for ( recursive_directory_iterator dir_itr( vanilla_dir );
    686512                                 dir_itr != end_iter;
     
    692518                                        {
    693519                                                importCommand = strOniSplit + " " + strImportOption + " " + dir_itr->path().parent_path().string() + '/' + dir_itr->path().filename();
    694                                                 for (int i = 0; i < installedMods.size(); ++i) {
     520                                                for (unsigned int i = 0; i < installedMods.size(); ++i) {
    695521                                                        if (exists("packages/" + installedMods[i] + "/oni/" + dir_itr->path().parent_path().filename() + '/' + dir_itr->path().filename()  ))
    696522                                                                importCommand += " packages/" + installedMods[i] + "/oni/" + dir_itr->path().parent_path().filename() + '/' + dir_itr->path().filename();
    697                                                        
    698                                                         //else cout << " packages/VanillaDats/" + installedMods[i] + "/oni/";
    699523                                                }
    700                                                 importCommand += " ../GameDataFolder/" + dir_itr->path().filename() + ".dat >> Onisplit.log";
     524                                                importCommand += " ../GameDataFolder/" + dir_itr->path().filename() + ".dat >> Install.log";
    701525                                               
    702                                                 sprintf(statusString,"%d/%i\0",j,numberOfDats);
     526                                               
    703527                                                setProgressBar( (int)(1000 * (float)(j-1) / (float)numberOfDats) ); //100% * dat we're on / total dats
    704                                                 setStatusArea("Importing " +  dir_itr->path().filename() + " " + statusString);
     528                                                setStatusArea("Step " + lexical_cast<std::string>(j) + '/' + lexical_cast<std::string>(numberOfDats)+ ": Importing " +  dir_itr->path().filename() + " ");
    705529                                               
    706530                                                system(importCommand.c_str());
    707                                                 //Sleep(1000);
    708                                                 //cout << importCommand << "\n";
    709                                                 j++;
    710                                                
     531                                                j++;                                           
    711532                                        }
    712533                                }
    713534                                catch ( const std::exception & ex )
    714535                                {
    715                                         cout << "Warning, exception " << ex.what() << "!";
    716                                 }
    717                         }
    718                        
     536                                        remove("Install.log");
     537                                        ofstream logfile("Install.log");
     538                                        logfile << "Warning, exception " << ex.what() << "!";
     539                                        setStatusArea("Warning, exception " + (string)ex.what() + "!");
     540                                        logfile.close();       
     541                                }
     542                        }
    719543                }
    720544                catch( const std::exception & ex ) {
    721                         cout << "Warning, exception " << ex.what() << "!\n"
    722                         << "You probably need to re-globalize.";
    723                         //create_directory( "./packages/VanillaDats" );
    724                 }
    725                
    726         }
    727         else if(splitInstances == NOT_SPLIT){
     545                        remove("Install.log");
     546                        ofstream logfile("Install.log");
     547                        logfile << "Warning, exception " << ex.what() << "!";
     548                        setStatusArea("Warning, exception " + (string)ex.what() + "!");
     549                        logfile.close();
     550                }
     551        }
     552        else if(splitInstances == false){
    728553                directory_iterator end_iter;
    729554               
     
    732557                         ++dir_itr )
    733558                {
    734                        
    735559                        if ( is_directory( dir_itr->status() ) )
    736560                        {
    737561                                numberOfDats++;
    738562                        }
    739                        
    740                        
    741563                }
    742564               
     
    752574                                if ( is_directory( dir_itr->status() ) )
    753575                                {
    754                                         importCommand = strOniSplit + " " + strImportOption + " " + vanilla_dir.string() + dir_itr->path().filename() + " " + "../GameDataFolder/" + dir_itr->path().filename()
    755                                         + ".dat";
    756                                         for (int i = 0; i < installedMods.size(); ++i) {
     576                                        importCommand = strOniSplit + " " + strImportOption + " " + vanilla_dir.string() + dir_itr->path().filename() + " ";
     577                                        for (unsigned int i = 0; i < installedMods.size(); ++i) {
    757578                                                if (exists("packages/" + installedMods[i] + "/oni/" + dir_itr->path().filename()  ))
    758579                                                        importCommand += " packages/" + installedMods[i] + "/oni/" + dir_itr->path().filename();
    759580                                        }
    760                                         importCommand += " ../GameDataFolder/" + dir_itr->path().filename() + ".dat";
     581                                        importCommand += " ../GameDataFolder/" + dir_itr->path().filename() + ".dat >> Install.log";
    761582                                       
    762                                         sprintf(statusString,"%d/%i\0",j,numberOfDats);
    763583                                        setProgressBar( (int)(1000 * (float)(j-1) / (float)numberOfDats) ); //100% * dat we're on / total dats
    764                                         setStatusArea("Importing " +  dir_itr->path().filename() + " " + statusString);
    765                                        
     584                                        setStatusArea("Step " + lexical_cast<std::string>(j) + '/' + lexical_cast<std::string>(numberOfDats)+ ": Importing " +  dir_itr->path().filename() + " ");
    766585                                        system(importCommand.c_str());
    767                                        
    768586                                        j++;
    769587                                }
     
    771589                        catch ( const std::exception & ex )
    772590                        {
    773                                 cout << "Warning, something odd happened!\n";
    774                         }
    775                 }
    776         }
     591                                remove("Install.log");
     592                                ofstream logfile("Install.log");
     593                                logfile << "Warning, exception " << ex.what() << "!";
     594                                setStatusArea("Warning, exception " + (string)ex.what() + "!");
     595                                logfile.close();
     596                        }
     597                }
     598        }
     599       
     600        vector<string> BSLfolders;
     601        vector<string> skippedfolders;
     602
     603        ofstream BSLlog("BSL.log");
     604        for ( directory_iterator dir_itr( "../GameDataFolder/IGMD/" ), end_itr;
     605                 dir_itr != end_itr;
     606                 ++dir_itr ) {
     607                if( exists(dir_itr->path().string() + "/ignore.txt") ){
     608                        BSLfolders.push_back(dir_itr->path().filename());
     609                        skippedfolders.push_back(dir_itr->path().filename());
     610                }
     611        }
     612       
     613        for (int i = installedMods.size() - 1; i >= 0; i--) {                                                   //Iterates through the installed mods (backwards :P)
     614                for (unsigned int j = 0; j < globalPackages.size(); ++j) {                              //looking in the global packages
     615                        if (globalPackages[j].modStringName == installedMods[i]) {      //for a mod that has BSL in it
     616                                if(!(globalPackages[j].hasAddon || globalPackages[j].hasBSL)) break; //skip non-BSL
     617                                if( exists( "packages/" + globalPackages[j].modStringName + "/BSL/" ) ) {
     618                                        copyBSL("packages/" + globalPackages[j].modStringName + "/BSL", BSLfolders, globalPackages[j] );
     619                                        BSLlog << "Copied " <<  globalPackages[j].modStringName << "!\n";
     620                                }
     621                        }
     622                }
     623        }
     624       
     625        ModPackage emptyPackage;
     626        emptyPackage.modStringName = "VanillaBSL";
     627        emptyPackage.hasBSL = 1;
     628        copyBSL("packages/VanillaBSL/IGMD", BSLfolders, emptyPackage);
     629        BSLlog.close();
     630       
     631        logfile << "Writing config file";
    777632        writeInstalledMods(installedMods);
    778633        setProgressBar(1000);
    779         setStatusArea("Done!");
    780         sleep(1000);
     634       
     635        string finallyDone = "Done! You can now play Oni.";
     636        setStatusArea(finallyDone);
     637       
     638        ptime end_time(second_clock::local_time());
     639        time_period total_time (start_time, end_time);
     640        ofstream logfile2("Install.log", ios::app | ios::ate);
     641        string outstring = (string)"\n\nGlobalization ended " + to_simple_string(end_time) + "\nThe process took ";// + (string)total_time.length();
     642       
     643        logfile2 << "\nInstallation ended " << to_simple_string(end_time) << "\nThe process took " << total_time.length();
     644        logfile2.close();
     645       
     646        Sleep(1000);
    781647        setProgressBar(0);
    782        
    783 }
     648}
     649        catch(exception & ex) {
     650                remove("Install.log"); //why did we do this? :|
     651                ofstream logfile("Install.log");
     652                logfile << "Warning, exception " << ex.what() << "!";
     653                setStatusArea("Warning, exception " + (string)ex.what() + "!");
     654                logfile.close();
     655        }
     656        busy = 0;
     657}
     658
     659void copyBSL(string copypath, vector<string>& BSLfolders, ModPackage pkg)
     660{
     661        ofstream BSLlog("BSL2.log", ios::app );
     662       
     663        try {
     664                for ( directory_iterator dir_itr( copypath ), end_itr;
     665                         dir_itr != end_itr;
     666                         ++dir_itr ) {
     667                       
     668                        if ( is_directory( dir_itr->path() ) && dir_itr->path().string() != ".svn" ) { 
     669                                BSLlog << "Testing " << dir_itr->path().string() << " HasBSL: " << pkg.hasBSL << " HasAddon: " << pkg.hasAddon << "\n";
     670                                int skip_folder = 0;
     671                               
     672                                for(unsigned int k = 0; k < BSLfolders.size(); k++)             {//iterate through already found BSL folders   
     673                                        BSLlog << "testing " << dir_itr->path().filename() << " vs " << BSLfolders[k] << "\n";
     674                                        if(dir_itr->path().filename() == BSLfolders[k]) {
     675                                                skip_folder = 1;
     676                                                BSLlog << "skipping " << BSLfolders[k] << " in " << pkg.modStringName << "\n";
     677                                                break;
     678                                        }
     679                                }
     680                                if (!skip_folder && !exists("../GameDataFolder/IGMD/" + dir_itr->path().filename() + "/ignore.txt")) {
     681                                        remove_all( "../GameDataFolder/IGMD/" + dir_itr->path().filename() );
     682                                        Sleep(100);
     683                                        create_directory( "../GameDataFolder/IGMD/" + dir_itr->path().filename());
     684                                        BSLlog << "Copied " << dir_itr->path().string() << " in " << pkg.modStringName << "!\n";
     685                                        for ( directory_iterator bsl_itr( dir_itr->path() );
     686                                                 bsl_itr != end_itr;
     687                                                 bsl_itr++ ) {
     688                                                if ( bsl_itr->path().extension() == ".bsl" ) {
     689                                                        copy_file(bsl_itr->path(),  "../GameDataFolder/IGMD/" + dir_itr->path().filename() + "/" + bsl_itr->path().filename());
     690                                                }
     691                                        }
     692                                        BSLfolders.push_back( dir_itr->path().filename() ); //add back check for addon
     693                                        BSLlog << "Pushing " << dir_itr->path().filename() << "\n" ;
     694                                }
     695                        }
     696                }
     697        }
     698        catch ( const std::exception & ex )
     699        {
     700                setStatusArea("Warning, exception " + (string)ex.what() + "!");
     701                while(1) Sleep(1000);
     702        }
     703        BSLlog.close();
     704       
     705}
     706
    784707
    785708void writeInstalledMods(vector<string> installedMods)
    786 {
    787        
     709{       
    788710        if ( exists( strInstallCfg ) )
    789711        {
     
    805727        file.close();
    806728        file.clear();
    807        
    808729}
    809730
    810731vector<string> getInstallString(string Cfg)
    811732{
    812         //system(strPauseCmd);
    813         vector<string> returnval;
    814        
     733        vector<string> returnval;       
    815734        string line;
    816735        fstream file;
     
    830749}
    831750
     751/* GetUpdateStatus determines whether there is an update available. It is called once, *\
     752|  on launch, by AEInstallerApp::OnInit(), and not only passes back a #defined result   |
     753|  code, but also oversees the setting of data in the global structures currentAE and   |
     754|  updateAE, which tell the Installer all the version information it needs to know.             |
     755|                                       ---Return Values---                                                                                                     |
     756|  UPDATE_LOG_READ_ERR          -- A log file could not be opened                                                       |
     757|  UPDATE_INST_REPL_ERR         -- The Installer self-updating process failed                           |
     758|  UPDATE_MNTH_REQD_ERR         -- The update is a patch, and the monthly release it            |
     759|                                                          patches is not installed                                                                     |
     760|  UPDATE_NO_UPD_AVAIL          -- Either there isn't an update in place, or it's not           |
     761|                                                          newer than what's installed                                                          |
     762|  UPDATE_SIMP_AVAIL            -- An update is available                                                                       |
     763|  UPDATE_GLOB_AVAIL            -- An update is available that requires re-globalization        |
     764|                                                          afterwards (because of some notable change in the AE)        |
     765|  UPDATE_INST_AVAIL            -- An update is available that first requires the                       |
     766|                                                          Installer to be replaced (when the new Installer                     |
     767|                                                          launches, this function will be called again but will        |
     768|                                                          return UPDATE_SIMP_AVAIL or UPDATE_GLOB_AVAIL)                       |
     769\* UPDATE_CONT_UPD                      -- Currently unused                                                                                */
     770int GetUpdateStatus(Install_info_cfg *currentAE, Install_info_cfg *updateAE, bool *installerJustUpdated)
     771{
     772        fstream currentAECfg, updateAECfg, updateLog;
     773        string strInstaller = "Installer";
     774        string strBeing = "being";
     775        string strWas = "was"; // lol
     776#ifdef WIN32
     777        string strInstallerName = "AEInstaller.exe";
     778#else
     779        string strInstallerName = "Installer.app";
     780#endif
     781       
     782        // Try to get current AE's version info; if it doesn't exist, then the default version data for 2009-07 remains in place
     783        if (exists("packages/Globalize/Install_Info.cfg"))
     784        {
     785                currentAECfg.open("packages/Globalize/Install_Info.cfg");
     786                if (!currentAECfg.fail())
     787                {
     788                        if (!ReadInstallInfoCfg(&currentAECfg, currentAE))
     789                                return UPDATE_LOG_READ_ERR;
     790                       
     791                        currentAECfg.close();
     792                        currentAECfg.clear();
     793                }
     794                else
     795                        return UPDATE_LOG_READ_ERR;
     796        }
     797       
     798        // Is there an update folder, and is it a monthly release or a patch?
     799        if (!exists("../updates/Edition"))
     800        {
     801                strEUFN = "Edition-patch";
     802                if (!exists("../updates/Edition-patch"))
     803                        return UPDATE_NO_UPD_AVAIL;
     804        }
     805       
     806        // Unlike the current AE's version info, we *need* to find the update's version info or we won't continue
     807        string updateCfgPath = ("../updates/" + strEUFN + "/install/packages/Globalize/Install_Info.cfg");
     808        updateAECfg.open(updateCfgPath.c_str());
     809        if (!updateAECfg.fail())
     810        {
     811                if (!ReadInstallInfoCfg(&updateAECfg, updateAE))
     812                        return UPDATE_LOG_READ_ERR;
     813               
     814                updateAECfg.close();
     815                updateAECfg.clear();
     816        }
     817        else
     818                return UPDATE_LOG_READ_ERR;
     819
     820        // Now we check for an Installer update in progress
     821        if (exists("Update.log"))
     822        {
     823                updateLog.open("Update.log");
     824                if (!updateLog.fail())
     825                {
     826                        vector<string> lines;
     827                        string line;
     828                        int num_lines = 0;
     829                        bool readingInstallerVersion = false, doneReadingFile = false;
     830                       
     831                        while (!updateLog.eof() && !doneReadingFile)
     832                        {
     833                                getline(updateLog, line);
     834                                lines.push_back(line);
     835                                num_lines++;
     836                                vector<string> tokens;
     837                                vector<string>::iterator iter;
     838                                tokenize(line, tokens);
     839                                iter = tokens.begin();
     840                                if (!readingInstallerVersion && tokens.capacity() >= 4)
     841                                {
     842                                        if (!strInstaller.compare(*iter))
     843                                        {
     844                                                if (!strBeing.compare(*++iter))
     845                                                        readingInstallerVersion = true;
     846                                                else if (!strWas.compare(*iter))
     847                                                        *installerJustUpdated = true; // our third indirect return value after currentAE and updateAE
     848                                        }
     849                                }
     850                                else if (readingInstallerVersion && tokens.capacity() >= 3)
     851                                {
     852                                        readingInstallerVersion = false;
     853                                        string installerVersion = INSTALLER_VERSION;
     854                                        if (installerVersion.compare(*iter)) // then the shell script-powered replacement failed
     855                                                return UPDATE_INST_REPL_ERR;
     856                                        else
     857                                        {
     858                                                updateLog.close();
     859                                                updateLog.clear();
     860                                                Sleep(1000);
     861                                                remove("Update.log");
     862                                                ofstream newUpdateLog("Update.log");
     863                                                if (!newUpdateLog.fail())
     864                                                {
     865                                                        // Write over old log with updated information
     866                                                        ptime startTime(second_clock::local_time());
     867                                                        string strStartTime = to_simple_string(startTime);
     868                                                        string newUpdateLine = installerVersion + " on " + strStartTime;
     869                                                        for (int a = 0; a < lines.capacity() - 2; a++) // if there were even lines in the log before this at all
     870                                                        {
     871                                                                newUpdateLog << lines[a].c_str();
     872                                                                newUpdateLog << "\n";
     873                                                        }
     874                                                        newUpdateLog << "Installer was updated to:\n";
     875                                                        newUpdateLog << newUpdateLine.c_str();
     876                                                        *installerJustUpdated = true; // this value is indirectly returned to AEInstallerAp::OnInit()
     877                                                        doneReadingFile = true;
     878                                                        newUpdateLog.close();
     879                                                        newUpdateLog.clear();
     880                                                        //return UPDATE_CONT_UPD; // as noted above, we are not using this return value; in fact, we want...
     881                                                        //                                                       ...the code to continue running down through the Edition version check
     882                                                }
     883                                                else
     884                                                        return UPDATE_LOG_READ_ERR;
     885                                        }
     886                                }
     887                        }
     888                        updateLog.close();
     889                        updateLog.clear();
     890                }
     891                else
     892                        return UPDATE_LOG_READ_ERR;
     893        }
     894       
     895        if (updateAE->AEVersion.compare(currentAE->AEVersion) >= 1) // is the release update newer than what's installed?
     896        {
     897                if (!strEUFN.compare("Edition-patch")) // if update is a patch...
     898                {
     899                        if (currentAE->AEVersion.compare(updateAE->AEVersion.substr(0, updateAE->AEVersion.length() - 1))) // ...is it for a different month?
     900                                return UPDATE_MNTH_REQD_ERR;
     901                }
     902                string strNewInstallerPath = "../updates/" + strEUFN + "/install/" + strInstallerName;
     903                string installerVersion = INSTALLER_VERSION;
     904                if (updateAE->InstallerVersion.compare(installerVersion) >= 1)
     905                {
     906                        if (exists(strNewInstallerPath))
     907                                return UPDATE_INST_AVAIL;
     908                }
     909                else if (updateAE->globalizationRequired)
     910                        return UPDATE_GLOB_AVAIL;
     911                else
     912                        return UPDATE_SIMP_AVAIL;
     913        }
     914        else
     915                return UPDATE_NO_UPD_AVAIL;
     916       
     917        return UPDATE_NO_UPD_AVAIL;
     918}
     919
     920bool ReadInstallInfoCfg(fstream *fileHandler, Install_info_cfg *info_cfg)
     921{
     922        vector<string> tokens;
     923        vector<string>::iterator iter;
     924        string line;
     925        string strAEVersion = "AE_Version";
     926        string strInstallerVersion = "Installer_Version";
     927        string strDaodanVersion = "Daodan_Version";
     928        string strOniSplitVersion = "OniSplit_Version";
     929        string strGUIWinVersion = "GUI_Win_Version";
     930        string strGUIMacVersion = "GUI_Mac_Version";
     931        string strReglobalize = "Reglobalize";
     932        string strDeleteList = "Delete_List";
     933        string strArrow = "->";
     934        string strDoubleSlash = "//";
     935        string strYes = "Yes"; // this is getting silly
     936       
     937        while (getline(*fileHandler, line))
     938        {
     939                tokenize(line, tokens);
     940                iter = tokens.begin();
     941               
     942                if (tokens.size() >= 3)
     943                {
     944                        if (!strAEVersion.compare(*iter))
     945                        {
     946                                if (!strArrow.compare(*++iter))
     947                                        info_cfg->AEVersion = *++iter;
     948                                else
     949                                        return false;
     950                        }
     951                        else if (!strInstallerVersion.compare(*iter))
     952                        {
     953                                if (!strArrow.compare(*++iter))
     954                                        info_cfg->InstallerVersion = *++iter;
     955                                else
     956                                        return false;
     957                        }
     958                        else if (!strDaodanVersion.compare(*iter))
     959                        {
     960                                if (!strArrow.compare(*++iter))
     961                                        info_cfg->DaodanVersion = *++iter;
     962                                else
     963                                        return false;
     964                        }
     965                        else if (!strOniSplitVersion.compare(*iter))
     966                        {
     967                                if (!strArrow.compare(*++iter))
     968                                        info_cfg->OniSplitVersion = *++iter;
     969                                else
     970                                        return false;
     971                        }
     972                        else if (!strGUIWinVersion.compare(*iter))
     973                        {
     974                                if (!strArrow.compare(*++iter))
     975                                        info_cfg->WinGUIVersion = *++iter;
     976                                else
     977                                        return false;
     978                        }
     979                        else if (!strGUIMacVersion.compare(*iter))
     980                        {
     981                                if (!strArrow.compare(*++iter))
     982                                        info_cfg->MacGUIVersion = *++iter;
     983                                else
     984                                        return false;
     985                        }
     986                        else if (!strReglobalize.compare(*iter))
     987                        {
     988                                if (!strArrow.compare(*++iter))
     989                                {
     990                                        if (!strYes.compare(*++iter))
     991                                                info_cfg->globalizationRequired = true;
     992                                }
     993                                else
     994                                        return false;
     995                        }
     996                        else if (!strDeleteList.compare(*iter))
     997                        {
     998                                // We need to perform a totally customized parsing process on this data
     999                                if (!strArrow.compare(*++iter))
     1000                                {
     1001                                        vector<string> tokens2;
     1002                                        tokenize(line, tokens2, ","); // the paths on this line are comma-delimited, so we parse it again
     1003                                        vector<string>::iterator iter2 = tokens2.begin();
     1004                                        string finalPath = "";
     1005                                        for (; iter2 != tokens2.end(); iter2++)
     1006                                        {
     1007                                                finalPath = finalPath + *iter2;
     1008                                               
     1009                                                string::size_type loc = finalPath.find("->", 0); // the first word will have "Delete_List ->" at the front, so let's cut that off
     1010                                                if (loc != string::npos)
     1011                                                        finalPath = finalPath.substr(loc + 3, finalPath.size());
     1012                                               
     1013                                                // If a path has '//' in it, it must contain some optional comments that were at the end of the Delete_List line
     1014                                                loc = finalPath.find("//", 0);
     1015                                                if (loc != string::npos)
     1016                                                        finalPath = finalPath.substr(0, loc);
     1017                                               
     1018                                                // Trim a single space if it exists at the start or finish; putting more than one space after a comma will break this
     1019                                                if (finalPath.at(0) == ' ')
     1020                                                        finalPath = finalPath.substr(1, finalPath.size());
     1021                                                if (finalPath.at(finalPath.size() - 1) == ' ')
     1022                                                        finalPath = finalPath.substr(0, finalPath.size() - 1);
     1023
     1024                                                // If the tokenized path ends with a '\', then we assume it was followed by a comma
     1025                                                if (finalPath.at(finalPath.size() - 1) == '\\')
     1026                                                {
     1027                                                        finalPath = finalPath.substr(0, finalPath.size() - 1); // clip the '\' off the end of the string now that it served its purpose...
     1028                                                        finalPath = finalPath + ","; // ...and add the actual comma back at the end
     1029                                                }
     1030                                                else // we can add the path to deleteList, and clear the path; otherwise it will be added to on the next iteration
     1031                                                {
     1032                                                        if (StringIsLegalPathForDeletion(finalPath)) // ...and it's not violating any of our security rules as to what can be deleted...
     1033                                                                info_cfg->deleteList.push_back(finalPath); // ...then add it to our deleteList in memory
     1034                                                        finalPath.clear(); // clear the token we were building up before the next pass
     1035                                                }
     1036                                        }
     1037                                }
     1038                                else
     1039                                        return false;
     1040                        }
     1041                }
     1042                tokens.clear();
     1043        }
     1044       
     1045        return true;
     1046}
     1047
     1048// TODO: Fix security holes here
     1049/* There is currently a security hole in this function; the first occurrence of a '.' not followed by a second '.' will prevent the function from
     1050 noticing an actual occurrence of '..' later in the string; iow, it only looks after the first period it finds for a second period.
     1051 A second hole is that the last slash will be trimmed from the path, but one could still use ".//" and it would get past this function, and
     1052 possibly be interpreted by the Boost file functions as "the current directory". Iow, both of these checks need to be iterative, not one-time.
     1053 Not too concerned about this at the moment, as only we of the AE Team are supplying the install_info file that this function is connected to. -I */
     1054
     1055/* This function serves as a barrier against the Installer deleting files it shouldn't. *\
     1056|  It tests for each of the following conditions in the path it is passed:                               |
     1057|   A. '..' as the whole path or '/..', '\..' anywhere in the path                                               |
     1058|        Reason: Moving up from the parent directory, the Edition folder, would allow one        |
     1059|        to delete anything on the hard drive, so all "parent path" references are illegal.      |
     1060|   B. '/' at the beginning of the path                                                                                                  |
     1061|        Reason: In Unix, this means the path starts from root level, as opposed to the          |
     1062|        directory we will evaluate these paths as being relative to, which is Edition/.         |
     1063|   C. '.' as the whole path                                                                                                                     |
     1064|        Reason: This would mean "the Edition folder", which is not allowed to be deleted.       |
     1065|   D. 'GameDataFolder' at the end of the path                                                                                   |
     1066|        Reason: We don't allow the entire GDF to be deleted, only specific files in it.         |
     1067|   E. '*' anywhere in the path                                                                                                                  |
     1068|        Reason: We don't want this interpreted as a wildcard; it's best to only delete          |
     1069*\       files by name.                                                                                                                                         */
     1070bool StringIsLegalPathForDeletion(string word)
     1071{
     1072        string::size_type loc1, loc2;
     1073       
     1074        // Trim ending slashes in order to simplify the test
     1075        // Note that we're only altering the local copy of the string here
     1076        loc1 = word.find_last_of("\\", word.size());
     1077        if (loc1 == word.size() - 1)
     1078                word.resize(word.size() - 1);
     1079        loc1 = word.find_last_of("/", word.size());
     1080        if (loc1 == word.size() - 1)
     1081                word.resize(word.size() - 1);
     1082       
     1083        // Test B
     1084        loc1 = word.find_first_of("\\", 0);
     1085        if (loc1 == 0)
     1086                return false; // path begins with a slash, meaning root level of HD in Unix, an illegal path
     1087        loc1 = word.find_first_of("/", 0);
     1088        if (loc1 == 0)
     1089                return false; // path begins with a slash, meaning root level of HD in Unix, an illegal path
     1090       
     1091        // Test E
     1092        loc1 = word.find("*", 0);
     1093        if (loc1 != string::npos) // if we found our character before reaching the end of the string
     1094                return false; // path cannot contain the '*' character
     1095       
     1096        // Tests A (part 1) and C
     1097        loc1 = word.find(".", 0);
     1098        if (loc1 != string::npos)
     1099        {
     1100                if (word.size() == 1)
     1101                        return false; // path cannot be simply '.', referring to Edition folder itself
     1102                loc2 = word.find(".", loc1 + 1);
     1103                if (loc2 == loc1 + 1) // make sure this second period comes after the first one
     1104                        if (word.size() == 2)
     1105                                return false; // not allowed to reference a parent directory
     1106        }
     1107       
     1108        // Test A (part 2)
     1109        loc1 = word.find("/..", 0);
     1110        if (loc1 != string::npos)
     1111                return false; // not allowed to reference a parent directory
     1112        loc1 = word.find("\\..", 0);
     1113        if (loc1 != string::npos)
     1114                return false; // not allowed to reference a parent directory
     1115       
     1116        // Test D
     1117        loc1 = word.find("GameDataFolder", 0);
     1118        if (loc1 == word.size() - 14) // if "GameDataFolder" is the last 14 characters of the string...
     1119                return false; // not allowed to delete the GDF
     1120
     1121        return true;
     1122}
     1123
     1124bool ProcessInstallerUpdate(Install_info_cfg *currentAE, Install_info_cfg *updateAE)
     1125{
     1126        ofstream file;
     1127        string shellScript;
     1128       
     1129        ptime startTime(second_clock::local_time());
     1130        string strStartTime = to_simple_string(startTime);
     1131        string progressMsg = "Installer being updated to:\n" +
     1132                                                 updateAE->InstallerVersion + " on " + strStartTime;
     1133        file.open("Update.log");
     1134        if (!file.fail())
     1135                file << progressMsg.c_str();
     1136        file.close();
     1137        file.clear();
     1138       
     1139        string popenCommand = "../updates/" + strEUFN + "/install/";
     1140#ifdef WIN32
     1141        // TODO: Fill in Windows equivalent of code below :-3
     1142#else
     1143        // We can't just use '~' to mean "the home directory" because we need to check the path in C...
     1144        // ...so we actually get the current user's shortname and manually construct the path to home
     1145        FILE *fUserName = NULL;
     1146        char chrUserName[32];
     1147        fUserName = popen("whoami", "r");
     1148        fgets(chrUserName, sizeof(chrUserName), fUserName);
     1149        pclose(fUserName);
     1150        string strUserName = (string)chrUserName; // stringsblaaarrrgggghhhh
     1151        int endOfName = strUserName.find("\n", 0);
     1152        string pathToTrash = "/Users/" + strUserName.substr(0, endOfName) + "/.Trash/";
     1153        tm tmStartTime = to_tm(startTime);
     1154        pathToTrash = pathToTrash + "Old_Edition_files_" + currentAE->AEVersion + "_" + boost::lexical_cast<string>(tmStartTime.tm_hour) + "-" +
     1155        boost::lexical_cast<string>(tmStartTime.tm_min) + "-" + boost::lexical_cast<string>(tmStartTime.tm_sec); // lol
     1156        create_directory(pathToTrash);
     1157        // The script takes as a parameter the path the old Installer should go to, in quotes
     1158        popenCommand = "bash " + popenCommand + "replace_installer.sh " + pathToTrash + "/Installer.app";
     1159                                   
     1160#endif
     1161        file.close();
     1162        file.clear();
     1163        popen(popenCommand.c_str(), "r");
     1164       
     1165        return true; // returning 'true' tells the Installer to quit itself ASAP so it can be replaced by the process that is now running
     1166}
     1167
     1168bool ProcessAEUpdate(Install_info_cfg *currentAE, Install_info_cfg *updateAE, bool *installerJustUpdated)
     1169{
     1170        fstream file;
     1171        string line;
     1172        vector<string> tokens, updateStarted;
     1173        string strInstaller = "Installer";
     1174        string strWas = "was";
     1175        string strPathToEUFN = ("../updates/" + strEUFN + "/"); // strEUFN is set by GetUpdateStatus()
     1176        string strPathToEUFNInstall = ("../updates/" + strEUFN + "/install/");
     1177        string strPathToEUFNPackages = ("../updates/" + strEUFN + "/install/packages/");
     1178        string strPathToPackages = "packages/";
     1179        string strGlobalize = "Globalize/";
     1180        string strOniSplit = "OniSplit.exe";
     1181        string strDaodan = "binkw32.dll";
     1182        string strWinGUI = "onisplit_gui.exe";
     1183        string strWinGUILang = "ospgui_lang.ini";
     1184        string strMacGUI = "AETools.app";
     1185#ifdef WIN32
     1186        string strOniApp = "Oni.exe";
     1187#else
     1188        string strOniApp = "Oni.app";
     1189#endif
     1190        bool needNewTrashDir = false;
     1191        bool readingVerAndDate = false;
     1192       
     1193        // TODO: Fill in Windows equivalent of code below
     1194#ifdef WIN32
     1195        string strTrashDir = "%RECYCLE%";
     1196#else
     1197        FILE *fUserName = NULL;
     1198        char chrUserName[32];
     1199        fUserName = popen("whoami", "r");
     1200        fgets(chrUserName, sizeof(chrUserName), fUserName);
     1201        pclose(fUserName);
     1202        string strUserName = (string)chrUserName; // stringsblaaarrrgggghhhh
     1203        int endOfName = strUserName.find("\n", 0);
     1204        string strTrashDir = "/Users/" + strUserName.substr(0, endOfName) + "/.Trash/";
     1205#endif
     1206       
     1207        // Write to log that we are beginning the update process
     1208        ptime startTime(second_clock::local_time());
     1209        string strStartTime = to_simple_string(startTime);
     1210        string progressMsg = "\nEdition being updated to:\n" +
     1211                                                 updateAE->AEVersion + " on " + strStartTime;
     1212        file.open("Update.log");
     1213        if (!file.fail())
     1214                file << progressMsg.c_str();
     1215       
     1216        if (*installerJustUpdated) // then we want to know what folder in the Trash the Installer was placed in...
     1217        {
     1218                while (!file.eof()) // ...so we read the log to get the timestamp so we know the name of the folder that should be in the Trash
     1219                {
     1220                        getline(file, line);
     1221                        tokenize(line, tokens);
     1222                       
     1223                        if (tokens.capacity() >= 4)
     1224                                if (!strInstaller.compare(tokens[0]))
     1225                                        if (!strWas.compare(tokens[1]))
     1226                                                readingVerAndDate = true;
     1227                        if (readingVerAndDate && tokens.capacity() >= 3)
     1228                                tokenize(tokens[2], updateStarted, "-");
     1229                }
     1230                if (updateStarted.capacity() < 3)
     1231                        needNewTrashDir = true;
     1232                else
     1233                {
     1234                        strTrashDir = strTrashDir + "Old_Edition_files_" + currentAE->AEVersion + "-" +
     1235                                                  updateStarted[0] + "-" + updateStarted[1] + "-" + updateStarted[2] + "/";
     1236                        if (!exists(strTrashDir))
     1237                                needNewTrashDir = true;
     1238                }
     1239        }
     1240       
     1241        if (!*installerJustUpdated || needNewTrashDir) // prepare a new directory for deleted files to go to
     1242        {
     1243                tm tmStartTime = to_tm(startTime);
     1244                strTrashDir = strTrashDir + "Old_Edition_files_" + currentAE->AEVersion + "_" + boost::lexical_cast<string>(tmStartTime.tm_hour) + "-" +
     1245                                          boost::lexical_cast<string>(tmStartTime.tm_min) + "-" + boost::lexical_cast<string>(tmStartTime.tm_sec) + "/";
     1246                create_directory(strTrashDir);
     1247        }
     1248        file.close();
     1249        file.clear();
     1250
     1251        // Special code to replace our special files -- the Oni app, OniSplit, the Daodan DLL, and the GUI for OniSplit
     1252        if (exists(strPathToEUFN + strOniApp))
     1253        {
     1254                if (exists(strOniApp))
     1255                        rename((path)strOniApp, (path)(strTrashDir + strOniApp));
     1256                rename((path)(strPathToEUFN + strOniApp), (path)strOniApp);
     1257        }
     1258        if (updateAE->OniSplitVersion.compare(currentAE->OniSplitVersion) >= 1)
     1259        {
     1260                if (exists(strPathToEUFNInstall + strOniSplit))
     1261                {
     1262                        if (exists(strOniSplit))
     1263                                rename((path)strOniSplit, (path)(strTrashDir + strOniSplit));
     1264                        rename((path)(strPathToEUFNInstall + strOniSplit), (path)strOniSplit);
     1265                }
     1266        }
     1267#ifdef WIN32
     1268        if (updateAE->DaodanVersion.compare(currentAE->DaodanVersion) >= 1)
     1269        {
     1270                if (exists(strPathToEUFN + strDaodan))
     1271                {
     1272                        if (exists(("../" + strDaodan)))
     1273                                rename((path)("../" + strDaodan), (path)(strTrashDir + strDaodan));
     1274                        rename((path)(strPathToEUFN + strDaodan), (path)("../" + strDaodan));
     1275                }
     1276        }
     1277        if (updateAE->WinGUIVersion.compare(currentAE->WinGUIVersion) >= 1)
     1278        {
     1279                if (exists(strPathToEUFNInstall + strWinGUI))
     1280                {
     1281                        if (exists((path)strWinGUI))
     1282                                rename((path)strWinGUI, (path)strcat(strTrashDir, strWinGUI));
     1283                        if (exists(strWinGUILang))
     1284                                rename((path)strWinGUILang, (path)strcat(strTrashDir, strWinGUILang));
     1285                        rename((path)(strPathToEUFNInstall + strWinGUI), (path)strWinGUI);
     1286                        rename((path)(strPathToEUFNInstall + strWinGUILang), (path)strWinGUILang);
     1287                }
     1288        }
     1289#else
     1290        if (updateAE->MacGUIVersion.compare(currentAE->MacGUIVersion) >= 1)
     1291        {
     1292                if (exists(strPathToEUFN + strMacGUI))
     1293                {
     1294                        if (exists(("../" + strMacGUI)))
     1295                                rename((path)("../" + strMacGUI), (path)(strTrashDir + strMacGUI));
     1296                        rename((path)(strPathToEUFN + strMacGUI), (path)("../" + strMacGUI));
     1297                }
     1298        }
     1299#endif
     1300       
     1301        // Now we trash whatever's in DeleteList; this allows us to clear out obsolete files in the previous AE install
     1302        // Before moving a file to the Trash, we need to make sure each of the file's parent paths exists in the Trash...
     1303        // ...so we iterate through the hierarchy of the file path, checking for each one and creating it if necessary
     1304        for (vector<string>::iterator iter = updateAE->deleteList.begin(); iter != updateAE->deleteList.end(); iter++)
     1305        {
     1306                string thePath = *iter;
     1307                if (exists((path)("../" + thePath)))
     1308                {
     1309                        string aParentPath;
     1310                        string::size_type curPos = thePath.find("/", 0);
     1311                        if (curPos != string::npos)
     1312                                aParentPath = thePath.substr(0, curPos);
     1313                        string::size_type lastPos = curPos;
     1314                        while (curPos != string::npos && curPos < thePath.size())
     1315                        {
     1316                                aParentPath = aParentPath + thePath.substr(lastPos, curPos - lastPos);
     1317                                if (!exists(strTrashDir + aParentPath))
     1318                                        create_directory(strTrashDir + aParentPath);
     1319                                lastPos = curPos + 1;
     1320                                curPos = thePath.find("/", lastPos);
     1321                                aParentPath = aParentPath + "/";
     1322                        }
     1323                        rename((path)("../" + thePath), (path)(strTrashDir + thePath));
     1324                }
     1325        }
     1326       
     1327        // Now we crawl the update's package folders for newer versions and move them over, trashing ones that are already present
     1328        vector<ModPackage> updatePackages, currentPackages;
     1329        bool matchFound;
     1330        updatePackages.reserve(256);
     1331        currentPackages.reserve(256);
     1332       
     1333        currentPackages = getPackages();
     1334        updatePackages = getPackages(strPathToEUFNPackages);
     1335
     1336        for (vector<ModPackage>::iterator iter1 = updatePackages.begin(); iter1 != updatePackages.end(); iter1++)
     1337        {
     1338                matchFound = false;
     1339                for (vector<ModPackage>::iterator iter2 = currentPackages.begin(); iter2 != currentPackages.end(); iter2++)
     1340                {
     1341                        if (!iter1->modStringName.compare(iter2->modStringName))
     1342                        {
     1343                                matchFound = true;
     1344                                if (iter1->modStringVersion > iter2->modStringVersion)
     1345                                {
     1346                                        rename((path)(strPathToPackages + iter2->modStringName), (path)(strTrashDir + iter2->modStringName));
     1347                                        rename((path)(strPathToEUFNPackages + iter1->modStringName), (path)(strPathToPackages + iter1->modStringName));
     1348                                }
     1349                        }
     1350                }
     1351                if (!matchFound) // then there's no old package in the way, so just move in the one from the update
     1352                        rename((path)(strPathToEUFNPackages + iter1->modStringName), (path)(strPathToPackages + iter1->modStringName));
     1353        }
     1354       
     1355        // 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...
     1356        // ...and folders which do not exist in the current AE will be created there
     1357        vector<string> foldersToMake, filesToMove;
     1358        string thePath;
     1359        for (recursive_directory_iterator dir_itr(strPathToEUFNPackages + strGlobalize), end_itr; dir_itr != end_itr; ++dir_itr)
     1360        {
     1361                thePath = dir_itr->path().string();
     1362                MakePathLocalToGlobalize(&thePath);
     1363                if (is_regular_file(dir_itr->status()))
     1364                {
     1365                        if (dir_itr->filename().at(0) != '.') // skip over dot-files, which are invisible in Unix
     1366                                filesToMove.push_back(thePath);
     1367                }
     1368                else if (is_directory(dir_itr->status()))
     1369                {
     1370                        if (!exists(strPathToPackages + strGlobalize + thePath))
     1371                                foldersToMake.push_back(thePath);
     1372                }
     1373        }
     1374        // Sort the foldersToMake strings by length, which is a fast solution to the problem of "How do we make sure we create folder 'parent/'...
     1375        // ...before folder 'parent/child/'"?
     1376        sort(foldersToMake.begin(), foldersToMake.end(), SortBySize); // SortBySize is a custom comparison function found later in this source file
     1377        // First make the folders that don't exist in the current AE, so all the files have a place to go
     1378        for (vector<string>::iterator iter = foldersToMake.begin(); iter != foldersToMake.end(); iter++)
     1379        {
     1380                create_directory(strPathToPackages + strGlobalize + *iter);
     1381        }
     1382        for (vector<string>::iterator iter = filesToMove.begin(); iter != filesToMove.end(); iter++)
     1383        {
     1384                if (exists(strPathToPackages + strGlobalize + *iter))
     1385                        rename((path)(strPathToPackages + strGlobalize + *iter), (path)(strTrashDir + *iter));
     1386                rename((path)(strPathToEUFNPackages + strGlobalize + *iter), (path)(strPathToPackages + strGlobalize + *iter));
     1387        }
     1388       
     1389        // Clean up after ourselves, trashing any packages or programs in the update package that are not newer than the current AE
     1390        create_directory(strTrashDir + "Unneeded update files");
     1391        rename((path)strPathToEUFN, (path)(strTrashDir + "Unneeded update files/" + strEUFN));
     1392       
     1393        // Write to log that we are finished with update
     1394        ptime end_time(second_clock::local_time());
     1395        string progressMsg2 = "Edition was updated to:\n" +
     1396                                                  updateAE->AEVersion + " on " + to_simple_string(end_time);
     1397       
     1398        file.open("Update.log");
     1399       
     1400        if(!file.fail())
     1401                file.write(progressMsg2.c_str(), sizeof(progressMsg2.c_str()));
     1402       
     1403        file.close();
     1404        file.clear();
     1405       
     1406        if (updateAE->globalizationRequired)
     1407                CheckForGlobalization(true); // the 'true' value forces re-globalization
     1408       
     1409        globalPackages = getPackages(); // refresh the list in memory
     1410       
     1411        // TODO: Refresh the packages list in the window
     1412
     1413        return true;
     1414}
     1415
     1416/* MakePathLocalToGlobalize is a function used once by ProcessAEUpdate() that takes a file in an        \
     1417|  update's Globalize folder and changes its path, originally relative to the Installer, to be          |
     1418|  relative to the structure of the Globalize folder; this makes it easier to have the Installer        |
     1419\  move said file from an update's Globalize folder to the current Globalize folder.               */
     1420void MakePathLocalToGlobalize(string *installerBasedPath)
     1421{
     1422        int deleteToHere = 0;
     1423        deleteToHere = installerBasedPath->find("Globalize/");
     1424        if (deleteToHere != 0)
     1425        {
     1426                deleteToHere += strlen("Globalize/");
     1427                installerBasedPath->erase(0, deleteToHere);
     1428        }
     1429}
     1430
     1431/* SortBySize is a custom comparison function that we call when using the C++ sort() function in \
     1432\  ProcessAEUpdate() on some strings that we want to sort by length.                                                    */
     1433bool SortBySize(string a, string b)
     1434{
     1435        return (a.size() < b.size());
     1436}
     1437
    8321438//stolen token function...
    8331439void tokenize(const string& str, vector<string>& tokens, const string& delimiters)
     
    8551461                 ++dir_itr_gdf )
    8561462        {
    857                 //cout << dir_itr_gdf->path().extension() << "\n";
    8581463                if ( dir_itr_gdf->path().extension() == ".dat" || dir_itr_gdf->path().extension() == ".raw" || dir_itr_gdf->path().extension() == ".sep" ) {
    8591464                        remove( dir_itr_gdf->path() );
     
    8631468       
    8641469}
     1470
     1471// this function copies files and directories. If copying a
     1472// directory to a directory, it copies recursively.
     1473
     1474//pardon the mess, I did this at midnight, and had to fix a bug
     1475void copy( const path & from_ph,
     1476                  const path & to_ph )
     1477{
     1478        cout << to_ph.string() << "\n";
     1479        // Make sure that the destination, if it exists, is a directory
     1480        if((exists(to_ph) && !is_directory(to_ph)) || (!exists(from_ph))) cout << "error";
     1481        if(!is_directory(from_ph))
     1482        {
     1483               
     1484                if(exists(to_ph))
     1485                {
     1486                        copy_file(from_ph,to_ph/from_ph.filename());
     1487                }
     1488                else
     1489                {
     1490                        try{
     1491                               
     1492                                copy_file(from_ph,to_ph);
     1493                        }
     1494                        catch (exception ex){
     1495                                cout << from_ph.string() << " to " << to_ph.string() << "\n";
     1496                        }
     1497                }
     1498               
     1499        }
     1500        else if(from_ph.filename() != ".svn")
     1501        {
     1502                path destination;
     1503                if(!exists(to_ph))
     1504                {
     1505                        destination=to_ph;
     1506                }
     1507                else
     1508                {
     1509                        destination=to_ph/from_ph.filename();
     1510                }
     1511               
     1512                for(directory_iterator i(from_ph); i!=directory_iterator(); ++i)
     1513                {
     1514                        //the idiot who coded this in the first place (not me)
     1515                        //forgot to make a new directory. Exception city. x_x
     1516                        create_directory(destination);
     1517                        copy(*i,destination/i->filename());
     1518                }
     1519        }
     1520}
     1521
     1522void copy_directory( const path &from_dir_ph,
     1523                                        const path &to_dir_ph)
     1524{
     1525        if(!exists(from_dir_ph) || !is_directory(from_dir_ph)
     1526           || exists(to_dir_ph))
     1527                cout << !exists(from_dir_ph) << " " << !is_directory(from_dir_ph)
     1528                << " " << exists(to_dir_ph);
     1529       
     1530# ifdef BOOST_POSIX
     1531        struct stat from_stat;
     1532        if ( (::stat( from_dir_ph.string().c_str(), &from_stat ) != 0)
     1533                || ::mkdir(to_dir_ph.native_directory_string().c_str(),
     1534                                   from_stat.st_mode)!=0)
     1535# endif
     1536                }
     1537
     1538string escapePath(string input)
     1539{
     1540        string output;
     1541        string escape_me = "& ;()|<>\"'\\#*?$";
     1542        for (unsigned int i = 0; i < input.size(); i++)
     1543        {
     1544                for (unsigned int j = 0; j < escape_me.size(); j++)
     1545                        if (input[i] == escape_me[j])
     1546                                output += '\\';
     1547                output += input[i];
     1548        }
     1549        return output;
     1550}
     1551
     1552Install_info_cfg::Install_info_cfg()
     1553{
     1554        AEVersion = "2009-07b";
     1555        InstallerVersion = "1.0.1";
     1556        DaodanVersion = "1.0";
     1557        OniSplitVersion = "0.9.38.0";
     1558        WinGUIVersion = "0";
     1559        MacGUIVersion = "0";
     1560        patch = false;
     1561        globalizationRequired = false;
     1562        deleteList.reserve(255);
     1563}
     1564
     1565ModPackage::ModPackage()
     1566{
     1567        isInstalled = true; // replace with function
     1568        name = "";
     1569        modStringName = "";
     1570        modStringVersion = 0;
     1571        hasOnis = false;
     1572        hasDeltas = false;
     1573        hasBSL = false;
     1574        hasAddon = false;
     1575        hasDats = false;
     1576        category = "";
     1577        creator = "";
     1578        isEngine = false;
     1579        readme = "";
     1580        globalNeeded = true;
     1581}
     1582
     1583void Sleep(int ms)
     1584{
     1585        sleep(ms / 1000);
     1586}
     1587
     1588#ifdef WIN32
     1589
     1590void RedirectIOToConsole()
     1591{
     1592        int hConHandle;
     1593        long lStdHandle;
     1594        CONSOLE_SCREEN_BUFFER_INFO coninfo;
     1595        FILE *fp;
     1596       
     1597        // allocate a console for this app
     1598        AllocConsole();
     1599       
     1600        // set the screen buffer to be big enough to let us scroll text
     1601        GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
     1602                                                           &coninfo);
     1603        coninfo.dwSize.Y = MAX_CONSOLE_LINES;
     1604        SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
     1605                                                           coninfo.dwSize);
     1606       
     1607        // redirect unbuffered STDOUT to the console
     1608        lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
     1609        hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
     1610        fp = _fdopen( hConHandle, "w" );
     1611        *stdout = *fp;
     1612        setvbuf( stdout, NULL, _IONBF, 0 );
     1613       
     1614        // redirect unbuffered STDIN to the console
     1615        lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
     1616        hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
     1617        fp = _fdopen( hConHandle, "r" );
     1618        *stdin = *fp;
     1619        setvbuf( stdin, NULL, _IONBF, 0 );
     1620       
     1621        // redirect unbuffered STDERR to the console
     1622        lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
     1623        hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
     1624        fp = _fdopen( hConHandle, "w" );
     1625        *stderr = *fp;
     1626        setvbuf( stderr, NULL, _IONBF, 0 );
     1627       
     1628        // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
     1629        // point to console as well
     1630        ios::sync_with_stdio();
     1631}
     1632#endif
  • AE/Installer/trunk/source/installer.h

    r462 r487  
    1  #pragma once
    2 /* AE/Mod Installer header file */
     1/***************************************************************************\
     2| Project: AE Installer                                                                                                         |
     3| By: Gumby & Iritscen                                                                                                          |
     4| File: Installer.h                                                                                                                     |
     5| Function: Contains the real meat of the installation process.                         |
     6| Created: 24/05/2009 19:39:00                                                                                          |
     7\***************************************************************************/
     8
    39#ifndef DOUBLE_HEADER
    410#define DOUBLE_HEADER
    511
    6 
    712#include <string>
    813#include <vector>
     14#include <iostream>
     15#include "globals.h"
     16#ifdef WIN32
     17#ifndef __GUICON_H__
     18#define __GUICON_H__
     19#endif
    920#include <fstream>
     21#include <windows.h>
     22#include <stdio.h>
     23#include <fcntl.h>
     24#include <io.h>
    1025
    11 using namespace std;
     26void RedirectIOToConsole();
     27// maximum mumber of lines the output console should have
     28static const WORD MAX_CONSOLE_LINES = 500;
     29#endif
    1230
     31
     32#pragma mark GLOBALS
    1333static string SLASHSLASH = "//";
    1434static string DIRSLASH = "\\";
    15 string strInstallCfg = "../GameDataFolder/Add.cfg";
    16 static string strInstallerVersion = "1.0";
     35extern bool busy;
     36extern string strInstallCfg;// = "../GameDataFolder/Add.cfg";
     37extern Install_info_cfg currentAE, updateAE;
     38extern bool splitInstances;
     39extern string strImportOption;
     40extern string strOniSplit;
     41extern vector<ModPackage> globalPackages;
     42extern string strEUFN; // I don't mind long variable names, but even I think strEditionUpdateFolderName is a bit much
     43#ifndef WIN32
     44void Sleep(int ms); // crudely converts the Windows sleep() call, which operates in ms, to the Mac sleep() call that operates in seconds
     45#endif
    1746
    18 #define STRUCT_DEFS
    19 struct ModPackage
    20 {
    21         bool    isInstalled; //replace with function
    22         string  name;
    23         string  modStringName;
    24         int     modStringVersion;
    25         bool    hasOnis;
    26         bool    hasDeltas;
    27         bool    hasBSL;
    28         bool    hasAddon;
    29         bool    hasDats;
    30         string  category;
    31         string  creator;
    32         bool    isEngine;
    33         string  readme;
    34         bool    globalNeeded;
    35         ModPackage();
    3647
    37         void doOutput()
    38         {
    39                 cout << "Mod: " << name; cout << "\n"; // remove this when done
    40                 cout << "       String: " << modStringName << " v." << modStringVersion << "\n";
    41                 cout << "       Category: " << category << "\n";
    42                 cout << "       Creator: " << creator << "\n";
    43                 cout << "       HasOnis: " << hasOnis << "\n";
    44                 cout << "       HasBSL: " << hasBSL << "\n";
    45                 cout << "       HasDeltas: " << hasDeltas << "\n";
    46                 cout << "       HasDats: " << hasDats << "\n";
    47                 cout << "       IsEngine: " << isEngine << "\n";
    48                 cout << "       GlobalNeeded: " << globalNeeded << "\n";
    49                 cout << "       Readme: " << readme << "\n";
    50                 cout << "\n";
    51         }
    52 
    53              bool operator < (const ModPackage &fs) const
    54      { return (name < fs.name);}
    55 
    56      bool operator > (const ModPackage &fs) const
    57      { return (name > fs.name);}
    58 
    59      bool operator == (const ModPackage &fs) const
    60      { return (name == fs.name);}
    61 };
    62 
    63 #define METHOD_DEFS
    64 // Initialization to default values
    65 ModPackage::ModPackage()
    66 {
    67         isInstalled = true; // replace with function
    68         name = "";
    69         modStringName = "";
    70         modStringVersion = 0;
    71         hasOnis = false;
    72         hasDeltas = false;
    73         hasBSL = false;
    74         hasAddon = false;
    75         hasDats = false;
    76         category = "";
    77         creator = "";
    78         isEngine = false;
    79         readme = "";
    80         globalNeeded = true;
    81         //              void doOutput() const
    82         //              { };
    83 }
    84 
    85 #define FUNCTION_PROTOTYPES
     48#pragma mark PROTOTYPES
    8649int mainMenu(void);
    87 int globalizeData(void);
     50vector<string> getInstallString(string = strInstallCfg);
    8851int installPackages(void);
    8952int uninstallPackages(void);
    9053int listInstalledPackages(void);
    9154int printInstallerInfo(void);
    92 vector<ModPackage> getPackages(void);
    9355ModPackage fileToModPackage(fstream&);
    94 void recompileAll(vector<string>);
    95 vector<string> getInstallString(string = strInstallCfg);
     56bool StringIsLegalPathForDeletion(string);
     57vector<ModPackage> getPackages(string packageDir = "./packages");
     58void MakePathLocalToGlobalize(string*);
     59bool SortBySize(string, string);
    9660void tokenize(const string&, vector<string>&, const string& delimiters = " ");
    97 //bool getDirectoryContents(char , char &);
    9861void clearOldDats(void);
    9962void writeInstalledMods( vector<string> );
    100 void setStatusArea( string );
    101 void setProgressBar( int );
    102 
    10363void copyBSL( string, vector<string>&, ModPackage );
    104 
    105 //New copy(path, path) function. Too lazy to implement my own, this is basically how I would have done it though.
    106 //No, really. :)
    107 //Move to utilities.cpp when the time comes.
    108 using namespace boost::filesystem;
    109 using namespace std;
    110 
    111 void copy_directory( const path & from_dir_ph,
    112                                         const path & to_dir_ph );
    113 
    114 void copy( const path & from_file_ph,
    115                   const path & to_file_ph );
    116 
    117 
    118 // this function copies files and directories. If copying a
    119 // directory to a directory, it copies recursively.
    120 
    121 //pardon the mess, I did this at midnight, and had to fix a bug
    122 void copy( const path & from_ph,
    123                   const path & to_ph )
    124 {
    125         cout << to_ph.string() << "\n";
    126         // Make sure that the destination, if it exists, is a directory
    127         if((exists(to_ph) && !is_directory(to_ph)) || (!exists(from_ph))) cout << "error";
    128         if(!is_directory(from_ph))
    129         {
    130                
    131                 if(exists(to_ph))
    132                 {
    133                         copy_file(from_ph,to_ph/from_ph.filename());
    134                 }
    135                 else
    136                 {
    137                         try{
    138                                
    139                                 copy_file(from_ph,to_ph);
    140                         }
    141                         catch (exception ex){
    142                                 cout << from_ph.string() << " to " << to_ph.string() << "\n";
    143                         }
    144                 }
    145                
    146         }
    147         else if(from_ph.filename() != ".svn")
    148         {
    149                 path destination;
    150                 if(!exists(to_ph))
    151                 {
    152                         destination=to_ph;
    153                 }
    154                 else
    155                 {
    156                         destination=to_ph/from_ph.filename();
    157                 }
    158                 //not sure what this did, its going away though. probably error checking ;)
    159                 //copy_directory(from_ph,destination);
    160                
    161                 for(directory_iterator i(from_ph); i!=directory_iterator(); ++i)
    162                 {
    163                         //the idiot who coded this in the first place (not me)
    164                         //forgot to make a new directory. Exception city. x_x
    165                         create_directory(destination);
    166                         copy(*i,destination/i->filename());
    167                 }
    168         }
    169 }
    170 
    171 void copy_directory( const path &from_dir_ph,
    172                                         const path &to_dir_ph)
    173 {
    174         if(!exists(from_dir_ph) || !is_directory(from_dir_ph)
    175            || exists(to_dir_ph))
    176                 cout << !exists(from_dir_ph) << " " << !is_directory(from_dir_ph)
    177                 << " " << exists(to_dir_ph);
    178         //boost::throw_exception( filesystem_error(
    179         //"boost::filesystem::copy_directory",
    180         //from_dir_ph, to_dir_ph, boost::system::error_code() ));
    181        
    182 # ifdef BOOST_POSIX
    183         struct stat from_stat;
    184         if ( (::stat( from_dir_ph.string().c_str(), &from_stat ) != 0)
    185                 || ::mkdir(to_dir_ph.native_directory_string().c_str(),
    186                                    from_stat.st_mode)!=0)
    187 # endif
    188                 //      boost::throw_exception( filesystem_error(
    189                 //      //"boost::filesystem::copy_directory",
    190                 //      from_dir_ph, to_dir_ph, boost::system::error_code()));
    191                 }
    192 
    193 #endif
    194 
    195 #ifdef WIN32
    196 
    197 #ifndef __GUICON_H__
    198 
    199 #define __GUICON_H__
    200 
    201 
    202 
    203 void RedirectIOToConsole();
    204 
    205 
    206 
    207 #endif
     64bool ReadInstallInfoCfg(fstream *, Install_info_cfg *);
    20865
    20966/* End of File */
    21067
    211 
    212 #include <windows.h>
    213 
    214 #include <stdio.h>
    215 
    216 #include <fcntl.h>
    217 
    218 #include <io.h>
    219 
    220 #include <iostream>
    221 
    222 #include <fstream>
    223 
    224 #ifndef _USE_OLD_IOSTREAMS
    225 
    226 using namespace std;
     68//End of File
    22769
    22870#endif
    229 
    230 // maximum mumber of lines the output console should have
    231 
    232 static const WORD MAX_CONSOLE_LINES = 500;
    233 
    234 
    235 void RedirectIOToConsole()
    236 
    237 {
    238        
    239         int hConHandle;
    240        
    241         long lStdHandle;
    242        
    243         CONSOLE_SCREEN_BUFFER_INFO coninfo;
    244        
    245         FILE *fp;
    246        
    247         // allocate a console for this app
    248        
    249         AllocConsole();
    250        
    251         // set the screen buffer to be big enough to let us scroll text
    252        
    253         GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
    254                                                            
    255                                                            &coninfo);
    256        
    257         coninfo.dwSize.Y = MAX_CONSOLE_LINES;
    258        
    259         SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
    260                                                            
    261                                                            coninfo.dwSize);
    262        
    263         // redirect unbuffered STDOUT to the console
    264        
    265         lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
    266        
    267         hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    268        
    269         fp = _fdopen( hConHandle, "w" );
    270        
    271         *stdout = *fp;
    272        
    273         setvbuf( stdout, NULL, _IONBF, 0 );
    274        
    275         // redirect unbuffered STDIN to the console
    276        
    277         lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
    278        
    279         hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    280        
    281         fp = _fdopen( hConHandle, "r" );
    282        
    283         *stdin = *fp;
    284        
    285         setvbuf( stdin, NULL, _IONBF, 0 );
    286        
    287         // redirect unbuffered STDERR to the console
    288        
    289         lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
    290        
    291         hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    292        
    293         fp = _fdopen( hConHandle, "w" );
    294        
    295         *stderr = *fp;
    296        
    297         setvbuf( stderr, NULL, _IONBF, 0 );
    298        
    299        
    300         // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
    301        
    302         // point to console as well
    303        
    304         ios::sync_with_stdio();
    305        
    306 }
    307 
    308 
    309 
    310 //End of File
    311 
    312 
    313 
    314 
    315 
    316 
    317 #endif
  • AE/Installer/trunk/source/main_window.cpp

    r469 r487  
     1/***************************************************************************\
     2| Project: AE Installer                                                                                                         |
     3| By: Gumby & Iritscen                                                                                                          |
     4| File: Main_Window.cpp                                                                                                         |
     5| Function: Handles the GUI.                                                                                            |
     6| Created: 07/05/2009 20:38:25                                                                                          |
     7\***************************************************************************/
     8
    19#ifndef NTDDI_VERSION           
    210#define NTDDI_VERSION NTDDI_WIN7
    311#endif
    412#ifdef WIN32
    5  #include <windows.h>
     13#include <windows.h>
    614#include <shobjidl.h>
    715HWND Handle;
    8 
    916ITaskbarList *pTaskbarList;
    1017ITaskbarList3 *pTaskbarList3;
    1118#endif
    1219
    13 /*
    14  AE/Mod Installer
    15  by Gumby and Iritscen
    16 */
    17 
    18 // To-do: - Load credits from text resource file
    19 //                - Institute lots of checks into file-handling
    20 //                - Clear mod info fields when mod is de-selected
    21 
    22 #define DEBUG
    23 #include <stdio.h>
    24 //#include <conio.h>
    25 //#include <process.h>
    26 #include <string>
    27 #include <iostream>
    28 #include <cctype>
    29 #include <vector>
    30 #include <fstream>
    31 #include <errno.h>
    32 #include <sstream>
    33 
    34 #include "boost/filesystem.hpp" // includes all needed Boost.Filesystem declarations
    35 #include "boost/lexical_cast.hpp" //int -> string
    36 #include "boost/algorithm/string.hpp"
    37 #include "installer.h"
    38 
    39 #ifdef WIN32
    40 #include <windows.h>
    41 #else // assume we're on Mac
    42 #include <stdlib.h>
    43 #include <dirent.h>
    44 #endif
    45 
    46 
    47 const bool SPLIT = 1;
    48 const bool NOT_SPLIT = 0;
    49 bool splitInstances = SPLIT;
    50 bool busy = 0;
    51 #ifdef WIN32
    52 const string strOniSplit = "Onisplit.exe";
    53 string strImportOption = "-import:nosep";
    54 const char* strClsCmd = "cls";
    55 const char* strPauseCmd = "PAUSE";
    56 #else // set up Mac equivalents since we're in Mac OS
    57 const string strOniSplit = "mono Onisplit.exe";
    58 string strImportOption = "-import:sep";
    59 const char* strClsCmd = "clear";
    60 const char* strPauseCmd = "read -n 1 -p \"Press any key to continue\"";
    61 void Sleep(int ms) { sleep( ms / 1000 ); }
    62 #endif
    63 
    64 using namespace boost::filesystem;
    65 using namespace std;
    66 
    67 
    68 vector<string> globalInstalledMods;
    69 vector<ModPackage> globalPackages;
    70 
    71 
    72 #include "boost/date_time/gregorian/gregorian.hpp"
    73 #include "boost/date_time/date_parsing.hpp"
    74 #include "boost/date_time/posix_time/posix_time.hpp"
    75 
    76 string escapePath(string input) {
    77        
    78         string output;
    79         string escape_me = "& ;()|<>\"'\\#*?$";
    80         for(unsigned int i = 0; i < input.size(); i++)  {
    81                 for(unsigned int j = 0; j < escape_me.size(); j++) if (input[i] == escape_me[j]) output += '\\';
    82                 output += input[i];
    83         }
    84         return output;
    85 }
    86 
    87 int globalizeData(void)
    88 {
    89         busy = 1;
    90         using boost::lexical_cast;
    91         using boost::bad_lexical_cast;
    92         // using namespace boost::posix_time;
    93         using namespace boost::gregorian;
    94         using namespace boost::posix_time;
    95         ptime start_time(second_clock::local_time());
    96 
    97         setStatusArea("Globalizing!");
    98         int err = 0;
    99         int parts_done = 0;
    100         char Step_x_x[300];
    101         //char levels[i][5];
    102         remove("Globalize.log");
    103         ofstream logfile("Globalize.log");
    104         logfile << "Globalization started " << to_simple_string(start_time) << endl;
    105         try {
    106 
    107                 char levels_cstr[15][3] = {"0", "1", "2", "3", "4", "6", "8", "9", "10", "11", "12", "13", "14", "18", "19"}; // the levels Oni has...probably should have made a string array. Oops.
    108                 //const vector<double> ck(cv, &cv[CvSize]);
    109                 vector<string> levels;
    110                 for (int f = 0; f < 15; f++) {
    111                         levels.push_back(levels_cstr[f]);
    112                 }
    113                 char choice = 0;
    114 
    115                 //SetCurrentDirectory("C:/Program Files/Oni/edition/install");
    116                 ///char levels[i][3];
    117                 path Characters = "../GameDataFolder/level0_Characters";
    118                 path Particles = "../GameDataFolder/level0_Particles";
    119                 path Archive = "../GameDataFolder/Archive";
    120                 path Textures  = "../GameDataFolder/level0_Textures";
    121                 path Sounds = "../GameDataFolder/level0_Sounds";
    122                 path Animations = "../GameDataFolder/level0_Animations";
    123                 path TRAC = Animations / "level0_TRAC";
    124                 path TRAM = Animations / "level0_TRAM";
    125 
    126                 vector<path> GDFPaths;
    127                 //GDFPaths.push_back(Characters);
    128                 GDFPaths.push_back(Particles);
    129                 GDFPaths.push_back(Textures);
    130                 GDFPaths.push_back(Sounds);
    131                 GDFPaths.push_back(TRAC);
    132                 GDFPaths.push_back(TRAM);
    133 
    134 
    135                 path VanillaCharacters = "VanillaDats/level0_Final/level0_Characters/level0_Characters.oni";
    136                 path VanillaParticles = "VanillaDats/level0_Final/level0_Particles/level0_Particles.oni";
    137                 path VanillaTextures  = "VanillaDats/level0_Final/level0_Textures/level0_Textures.oni";
    138                 path VanillaSounds = "VanillaDats/level0_Final/level0_Sounds/level0_Sounds.oni";
    139                 path VanillaAnimations = "VanillaDats/level0_Final/level0_Animations/level0_Animations.oni";
    140                 path VanillaTRAC = "VanillaDats/level0_Final/level0_Animations/level0_TRAC.oni";
    141                 path VanillaTRAM = "VanillaDats/level0_Final/level0_Animations/level0_TRAM.oni";
    142 
    143                 vector<path> VanillaPaths;
    144 
    145                 //VanillaPaths.push_back(VanillaCharacters);
    146                 VanillaPaths.push_back(VanillaParticles);
    147                 VanillaPaths.push_back(VanillaTextures);
    148                 VanillaPaths.push_back(VanillaSounds);
    149                 VanillaPaths.push_back(VanillaTRAC);
    150                 VanillaPaths.push_back(VanillaTRAM);
    151 
    152                 /*
    153                 if (exists("../GameDataFolder/"))
    154                 {
    155                 //cout << "\nIt looks like you've already globalized Oni's data.\nDo you want to re-globalize?\n(This will erase existing mods installed to the AE's game data.)"
    156                 //       << "\n1. Re-globalize"
    157                 //       << "\n2. Return to main menu\n";
    158                 //choice = cin.get();
    159                 cin.ignore(128, '\n');
    160                 if (choice == '1')
    161                 remove_all("../GameDataFolder"); // remove AE GDF
    162                 if (choice == '2')
    163                 return 0;
    164                 }
    165                 */
    166                 setStatusArea("Removing old GameDataFolder...\n");
    167                 logfile <<  "Removing old GameDataFolder...\n";
    168                 remove_all( "../GameDataFolder/" );
    169                 setStatusArea("Creating needed directories...");
    170                 logfile <<  "Creating needed directories...\n";
    171                 create_directory( "../GameDataFolder/" );
    172 
    173                 create_directory( "packages" );
    174 
    175                 if (exists("VanillaDats")) remove_all("VanillaDats");
    176                 create_directory( "VanillaDats" );
    177                 create_directory( "VanillaDats/level0_Final/" );
    178                 //blah blah finish this.
    179                 //logfile <<  "VanillaDats/level0_Final/ created";
    180                 create_directory( Characters );
    181                 create_directory( Particles );
    182                 create_directory( Archive );
    183                 create_directory( Textures );
    184                 create_directory( Sounds );
    185                 create_directory( Animations );
    186                 create_directory( TRAC );
    187                 create_directory( TRAM );
    188                 int num_levels = 0;
    189                 for(int i = 1; i < 15; i++)
    190                 {
    191                         if (exists("../../GameDataFolder/level" + levels[i] + "_Final.dat")) {
    192                                 num_levels++;
    193 
    194                         }
    195                 }
    196                 logfile << "Exporting and moving...\n\n";
    197                 int total_steps =  8 + 2 * num_levels;
    198        
    199                 for(int i = 0; i < 15; i++)
    200                 {
    201 
    202                         //printf(levels[i],"%d",levels[i]); // int to char array
    203 
    204                         if (exists("../../GameDataFolder/level" + levels[i] + "_Final.dat")) {
    205                                 logfile << "level" << levels[i] << "_Final\n";
    206                                 logfile << "\tExporting level" << levels[i] << "_Final.dat\n";
    207                                 //printf(Step_x_x,"Step %d/%d: exporting level%d_final.dat", parts_done + 1,, levels[i]); setStatusArea((string)Step_x_x);
    208                                 setStatusArea("Step " + lexical_cast<std::string>(parts_done + 1) + "/" + lexical_cast<std::string>(total_steps) + " exporting level" + levels[i]+"_Final.dat");
    209                                 create_directory( "../GameDataFolder/level" + levels[i] + "_Final" );
    210                                 //                              setStatusArea(strOniSplit + " -export ../GameDataFolder/level" + levels[i] + "_Final ../../GameDataFolder/level" + levels[i] + "_Final.dat");
    211                                 system((strOniSplit + " -export ../GameDataFolder/level" + levels[i] + "_Final ../../GameDataFolder/level" + levels[i] + "_Final.dat").c_str());
    212                                 create_directory( "VanillaDats/level" + levels[i] + "_Final" );
    213                                 create_directory( "VanillaDats/level" + levels[i] + "_Final/level" + levels[i] + "_Final" );
    214                                
    215                                 //Moves the AKEV and other files into a safe directory so that level specific textures are not globalized...
    216                                 if ( strcmp(levels[i].c_str(), "0") ){
    217                                         create_directory( "../GameDataFolder/level" + levels[i] + "_Final/AKEV" );
    218                                         system((strOniSplit + " -move:overwrite ../GameDataFolder/level" + levels[i] + "_Final/AKEV ../GameDataFolder/level" + levels[i] + "_Final/AKEV*.oni").c_str());
    219 
    220                                 }
    221 
    222                                 directory_iterator end_iter;
    223                                 for ( directory_iterator dir_itr( "../GameDataFolder/level" + levels[i] + "_Final" ); dir_itr != end_iter; ++dir_itr )
    224                                 {
    225                                         //cout << dir_itr->path().filename();
    226                                         if ( is_regular_file( dir_itr->status() ) )
    227                                         {
    228                                                 if ( dir_itr->path().filename().substr(0,8) == "TXMPfail" ||
    229                                                         dir_itr->path().filename().substr(0,9) == "TXMPlevel" ||
    230                                                         ( dir_itr->path().filename().substr(0,4) == "TXMP" && dir_itr->path().filename().find("intro")!=string::npos) ||
    231                                                         dir_itr->path().filename().substr(0,4) == "TXMB" ||
    232                                                         dir_itr->path().filename() == "M3GMpowerup_lsi.oni" ||
    233                                                         dir_itr->path().filename() == "TXMPlsi_icon.oni" ||
    234                                                         ( dir_itr->path().filename().substr(0,4) == "TXMB" && dir_itr->path().filename().find("splash_screen.oni")!=string::npos)       )
    235                                                 {
    236                                                         cout <<dir_itr->path().filename() << "\n";
    237                                                         create_directory( dir_itr->path().parent_path() / "NoGlobal"); 
    238                                                         if(!exists( dir_itr->path().parent_path() / "NoGlobal" / dir_itr->filename())) rename(dir_itr->path(), dir_itr->path().parent_path() / "NoGlobal" /
    239                                                                 dir_itr->filename());
    240                                                         else remove(dir_itr->path());
    241                                                 }
    242                                                 else if (dir_itr->path().filename().substr(0,4) == "TRAC"
    243                                                         ) {
    244                                                                 cout <<dir_itr->path().filename() << "\n";
    245                                                                 if(!exists( TRAC / dir_itr->filename())) rename(dir_itr->path(), TRAC / dir_itr->filename());
    246                                                                 else remove(dir_itr->path());
    247                                                 }
    248                                                 else if (dir_itr->path().filename().substr(0,4) == "TRAM") {
    249                                                         cout <<dir_itr->path().filename() << "\n";
    250                                                         if(!exists( TRAM / dir_itr->filename())) rename(dir_itr->path(), TRAM / dir_itr->filename());
    251                                                         else remove(dir_itr->path());
    252                                                 }
    253                                                 else if (dir_itr->path().filename().substr(0,4) == "ONSK" ||
    254                                                         dir_itr->path().filename().substr(0,4) == "TXMP") {
    255                                                                 cout <<dir_itr->path().filename() << "\n";\
    256                                                                         create_directory( dir_itr->path().parent_path() / "TexFix");   
    257                                                                 if(!exists( Textures / dir_itr->filename())) rename(dir_itr->path(), Textures / dir_itr->filename());
    258                                                                 //rename(dir_itr->path(), dir_itr->path().parent_path() / "TexFix" / dir_itr->filename());
    259                                                 }
    260                                                 else if (dir_itr->path().filename().substr(0,4) == "ONCC"
    261                                                         || dir_itr->path().filename().substr(0,4) == "TRBS"
    262                                                         || dir_itr->path().filename().substr(0,4) == "ONCV"
    263                                                         || dir_itr->path().filename().substr(0,4) == "ONVL"
    264                                                         || dir_itr->path().filename().substr(0,4) == "TRMA"
    265                                                         || dir_itr->path().filename().substr(0,4) == "TRSC"
    266                                                         || dir_itr->path().filename().substr(0,4) == "TRAS") {
    267                                                                 cout <<dir_itr->path().filename() << "\n";
    268                                                                 if(!exists( Characters / dir_itr->filename())) rename(dir_itr->path(), Characters / dir_itr->filename());
    269                                                                 else remove(dir_itr->path());
    270                                                 }
    271                                                 else if (dir_itr->path().filename().substr(0,4) == "OSBD"
    272                                                         || dir_itr->path().filename().substr(0,4) == "SNDD") {
    273                                                                 cout << dir_itr->path().filename() << "\n";
    274                                                                 if(!exists( Sounds / dir_itr->filename())) rename(dir_itr->path(), Sounds / dir_itr->filename());
    275                                                                 else remove(dir_itr->path());
    276                                                 }
    277                                                 else if (dir_itr->path().filename().substr(0,5) == "BINA3"
    278                                                         || dir_itr->path().filename().substr(0,10) == "M3GMdebris"
    279                                                         || dir_itr->path().filename() == "M3GMtoxic_bubble.oni"
    280                                                         || dir_itr->path().filename().substr(0,8) == "M3GMelec"
    281                                                         || dir_itr->path().filename().substr(0,7) == "M3GMrat"
    282                                                         || dir_itr->path().filename().substr(0,7) == "M3GMjet"
    283                                                         || dir_itr->path().filename().substr(0,9) == "M3GMbomb_"
    284                                                         || dir_itr->path().filename() == "M3GMbarab_swave.oni"
    285                                                         || dir_itr->path().filename() == "M3GMbloodyfoot.oni"
    286                                                         ){
    287                                                                 cout <<dir_itr->path().filename() << "\n";
    288                                                                 if(!exists( Particles / dir_itr->filename())) rename(dir_itr->path(), Particles / dir_itr->filename());
    289                                                                 else remove(dir_itr->path());
    290                                                 }
    291                                                 else if (dir_itr->path().filename().substr(0,4) == "AGDB"
    292                                                         || dir_itr->path().filename().substr(0,4) == "TRCM") {
    293                                                                 cout <<dir_itr->path().filename() << "\n";
    294 
    295                                                                 if(!exists( Archive / dir_itr->filename())) rename(dir_itr->path(), Archive / dir_itr->filename());
    296                                                                 else remove(dir_itr->path());
    297                                                 }
    298                                                 else if (dir_itr->path().filename().substr(0,4) == "ONWC") { //fix for buggy ONWC overriding
    299                                                                 cout <<dir_itr->path().filename() << "\n";
    300 
    301                                                                 if(!exists( "VanillaDats/level0_Final/level0_Final/" +  dir_itr->filename())) rename(dir_itr->path(), "VanillaDats/level0_Final/level0_Final/" +  dir_itr->filename());
    302                                                                 else remove(dir_itr->path());
    303                                                 }
    304 
    305                                                 if (exists(dir_itr->path())) {
    306 
    307                                                 }
    308                                                 else {
    309                                                         logfile << "\tMoved file: " << dir_itr->path().filename() << "\n";
    310                                                 }
    311                                         }
    312 
    313 
    314 
    315                                 }
    316                                
    317                                 logfile << "\tCleaning up TXMPs...\n";
    318                                 system( (strOniSplit + " -move:delete " + Textures.string() + " ../GameDataFolder/level" + levels[i] + "_Final/TXMP*.oni").c_str());
    319                                
    320 
    321                                 if ( strcmp(levels[i].c_str(), "0") ){
    322                                         system((strOniSplit + " -move:overwrite ../GameDataFolder/level" + levels[i] + "_Final ../GameDataFolder/level" + levels[i] + "_Final/AKEV/AKEV*.oni").c_str());
    323                                         remove(  "../GameDataFolder/level" + levels[i] + "_Final/AKEV" );
    324                                 }
    325 
    326                                 parts_done++;
    327 
    328                                 setProgressBar( (int)(1000 * (float)(parts_done) / (float)(total_steps) ));
    329 
    330                         }
    331                 }
    332                 logfile << "Reimporting levels\n";
    333                 for (int i = 0; i < 15; i++)
    334                 {
    335                         logfile << "\tReimporting level" << levels[i] << "_Final.oni\n";
    336                         //printf(levels[i],"%d",levels[i]);
    337                         //printf(Step_x_x,"Step %d/%d: reimporting level", parts_done + 1, 7 + 2 * num_levels); setStatusArea((string)Step_x_x + levels[i] + (string)"_Final.dat");
    338                         setStatusArea("Step " + lexical_cast<std::string>(parts_done + 1) + "/" + lexical_cast<std::string>(total_steps) + " reimporting level" + levels[i]+"_Final.oni");
    339                         logfile << (strOniSplit + " " + strImportOption + " ../GameDataFolder/level" + levels[i] + "_Final VanillaDats/level" + levels[i] + "_Final/level"
    340                                 + levels[i] + "_Final/level" + levels[i] + "_Final.oni >> Globalize.log").c_str() << '\n';
    341                         string sys_str = (strOniSplit + " " + strImportOption + " ../GameDataFolder/level" + levels[i] + "_Final VanillaDats/level" + levels[i] + "_Final/level"
    342                                 + levels[i] + "_Final/level" + levels[i] + "_Final.oni");
    343                                 system(sys_str.c_str() );
    344                         setProgressBar( (int)(1000 * (float)(parts_done) / (float)(total_steps) ));
    345                         parts_done++;
    346                 }
    347                 //create_directory( VanillaCharacters.parent_path() );
    348                 create_directory( VanillaParticles.parent_path() );
    349                 create_directory( VanillaTextures.parent_path() );
    350                 create_directory( VanillaSounds.parent_path() );
    351                 create_directory( VanillaAnimations.remove_filename() );
    352 
    353                 for(unsigned int j = 0; j < GDFPaths.size(); j++) {
    354                         logfile << "\tReimporting " << GDFPaths[j].filename() << ".oni\n";
    355                         setStatusArea("Step " + lexical_cast<std::string>(parts_done + 1) + "/" + lexical_cast<std::string>(total_steps) + ": reimporting " + GDFPaths[j].filename() );
    356                         system((strOniSplit + " " + strImportOption + " " + GDFPaths[j].string() + " " + VanillaPaths[j].string()).c_str());
    357                         parts_done++;
    358                         setProgressBar( (int)(1000 * (float)(parts_done) / (float)(total_steps) ));
    359                 }
    360                 logfile << "\nMoving level0_Characters\n";
    361                 setStatusArea("Step " + lexical_cast<std::string>(parts_done + 1) + "/" + lexical_cast<std::string>(total_steps) + ": moving level0_Characters" );     
    362                 copy((path)"../GameDataFolder/level0_Characters", (path)("VanillaDats/level0_Final"));
    363                 GDFPaths.push_back( Characters );
    364                 for(int i = 0; i < GDFPaths.size(); i++)
    365                 {
    366                         directory_iterator end_iter;
    367                         for ( directory_iterator dir_itr( GDFPaths[i] ); dir_itr != end_iter; ++dir_itr )
    368                         {
    369                                 try
    370                                 {
    371 
    372 
    373                                         rename(dir_itr->path(), "../GameDataFolder/level0_Final/" + dir_itr->path().filename() );
    374                                 }
    375                                 catch(exception &ex) {
    376 
    377                                 }
    378                         }
    379                 }
    380                 /*
    381                 printf(Step_x_x,"Step %d/%d: reimporting level0_Characters", parts_done,7 + 2 * num_levels); setStatusArea((string)Step_x_x);setProgressBar( (int)(1000 * (float)(parts_done) / (float)(7 + 2 * num_levels) ));
    382                 system((strOniSplit + " " + strImportOption + " " + Characters.string() + " " + VanillaCharacters.string()).c_str());
    383                 parts_done++; printf(Step_x_x,"Step %d/%d: reimporting level0_Particles", parts_done,7 + 2 * num_levels); setStatusArea((string)Step_x_x);setProgressBar( (int)(1000 * (float)(parts_done) / (float)(7 + 2 * num_levels) ));
    384                 system((strOniSplit + " " + strImportOption + " " + Particles.string() + " " + VanillaParticles.string()).c_str());
    385                 parts_done++; printf(Step_x_x,"Step %d/%d: reimporting level0_Textures", parts_done,7 + 2 * num_levels); setStatusArea((string)Step_x_x);setProgressBar( (int)(1000 * (float)(parts_done) / (float)(7 + 2 * num_levels) ));
    386                 system((strOniSplit + " " + strImportOption + " " + Textures.string() + " " + VanillaTextures.string()).c_str());
    387                 //system((strOniSplit   + " " + strImportOption + (string)" " + Animations.string() + (string)" " + VanillaAnimations.string()).c_str());
    388                 parts_done++; printf(Step_x_x,"Step %d/%d: reimporting level0_TRAC", parts_done,7 + 2 * num_levels); setStatusArea((string)Step_x_x);setProgressBar( (int)(1000 * (float)(parts_done) / (float)(7 + 2 * num_levels) ));
    389                 system((strOniSplit + " " + strImportOption + " " + TRAC.string() + " " + VanillaTRAC.string()).c_str());
    390                 parts_done++; printf(Step_x_x,"Step %d/%d: reimporting level0_Sounds", parts_done,7 + 2 * num_levels); setStatusArea((string)Step_x_x);setProgressBar( (int)(1000 * (float)(parts_done) / (float)(7 + 2 * num_levels) ));
    391                 system((strOniSplit + " " + strImportOption + " " + Sounds.string() + " " + VanillaSounds.string()).c_str());
    392                 parts_done++; printf(Step_x_x,"Step %d/%d: reimporting level0_TRAM", parts_done,7 + 2 * num_levels); setStatusArea((string)Step_x_x);setProgressBar( (int)(1000 * (float)(parts_done) / (float)(7 + 2 * num_levels) ));
    393                 system((strOniSplit + " " + strImportOption + " " + TRAM.string() + " " + VanillaTRAM.string()).c_str());
    394                 //parts_done++; setStatusArea((string)"Copying level scripts...");setProgressBar( (int)(1000 * (float)(parts_done) / (float)(7 + 2 * num_levels) ));
    395                 if (exists("../GameDataFolder/IGMD")) remove_all("../GameDataFolder/IGMD");
    396                 */
    397                 create_directory((path)"../GameDataFolder/IGMD");
    398                 copy((path)"packages/VanillaBSL/IGMD", (path)"../GameDataFolder");
    399                 setProgressBar( 1000 );
    400 
    401                 if(exists("../../persist.dat")) if(!exists("../persist.dat"))
    402                
    403                         //TODO: Concactate level0 Dirs.
    404 
    405                         copy("../../persist.dat","..");
    406                 if(exists("../../key_config.txt"))if(!exists("../key_config.txt"))
    407                         copy("../../key_config.txt","..");
    408                
    409 #ifndef WIN32
    410                 /* 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).
    411                    Tests for presence of prefs with [ -f ] before doing anything so it doesn't create a partial prefs file -- just in case user has never
    412                    run Oni before :-p */
    413                 string fullAEpath = escapePath(system_complete(".").parent_path().parent_path().string()); // get full path for edition/
    414                 char prefsCommand[300] = "[ -f ~/Library/Preferences/com.godgames.oni.plist ] && defaults write com.godgames.oni RetailInstallationPath -string '";
    415                 strcat(prefsCommand, fullAEpath.c_str()); // get path of edition/ folder (Oni wants the folder that *contains* the GDF)
    416                 strcat(prefsCommand, "'"); // path string is enclosed in single quotes to avoid the need to escape UNIX-unfriendly characters
    417                 system(prefsCommand);
    418                
    419 #endif
    420                
    421                
    422                 setStatusArea((string)"Done! Now select your mod packages and click install.");
    423                 //      while(1) Sleep(-1);
    424 
    425         }
    426         catch (exception & ex) {
    427                 setStatusArea("Warning, handled exception: " + (string)ex.what());
    428         }
    429 
    430         ptime end_time(second_clock::local_time());
    431         time_period total_time (start_time, end_time);
    432         logfile << "\n\nGlobalization ended " << to_simple_string(end_time) << "\nThe process took " << total_time.length();
    433         //total_time.length().hours();
    434         logfile.close();
    435         busy = 0;
    436         return err;
    437 }
    438 
    439 
    440 vector<ModPackage> getPackages(void)
    441 {
    442         vector<ModPackage> packages;
    443         packages.reserve(65536); // come on, we shouldn't need this much space...right?!
    444         fstream file;
    445         string filename = "\0";
    446         string MODINFO_CFG = "Mod_Info.cfg";
    447 
    448         try
    449         {
    450                 for (directory_iterator dir_itr("./packages"), end_itr; dir_itr != end_itr; ++dir_itr)
    451                 {
    452                         file.open((dir_itr->path().string() + "/" + MODINFO_CFG).c_str());
    453                         //cout << filename << "\n";
    454 
    455                         if(!file.fail())
    456                         {
    457                                 //cout << dir_itr->path().string() + MODINFO_CFG;
    458                                 //would prefer to push a pointer to a package, but this will do for now
    459                                 packages.push_back(fileToModPackage(file));
    460                         }       
    461                         file.close();
    462                         file.clear();
    463                 }
    464                 sort(packages.begin(), packages.end());
    465         }
    466         catch (const std::exception & ex)
    467         {
    468                 cout << "Warning, something odd happened!\n";
    469         }
    470 
    471         return packages;
    472 }
    473 
    474 ModPackage fileToModPackage(fstream &file)
    475 {
    476         /*
    477         This converts a file to a ModPackage struct.
    478 
    479         A few notes...
    480         "iter" is the current word we are on. I should have named it "token" or something, but I don't have multiple iterators, so its ok.
    481         I refer to (*iter) at the beginning of each if statement block. I could probably store it as a variable, but I'm pretty sure that dereferencing a pointer\iterator isn't much
    482         slower than reading a variable.
    483         */
    484         ModPackage package;
    485         string line;
    486         static string NameOfMod = "NameOfMod";  //used for comparing to the current token...
    487         //I could have done it in reverse (*iter).compare("ModString") or 
    488         static string ARROW = "->";                             //did something like "ModString".compare(*iter), and it would have been
    489         static string ModString = "ModString";  //functionably the same.
    490         static string HasOnis = "HasOnis";
    491         static string HasDeltas = "HasDeltas";
    492         static string HasBSL = "HasBSL";
    493         static string HasDats = "HasDats";
    494         static string IsEngine = "IsEngine";
    495         static string Readme = "Readme";
    496         static string GlobalNeeded = "GlobalNeeded";
    497         static string Category = "Category";
    498         static string Creator = "Creator";
    499         while (! file.eof() )
    500         {
    501                 getline (file,line);
    502                 vector<string> tokens;
    503                 vector<string>::iterator iter;
    504                 tokenize(line, tokens);                                 //string to vector of "words"
    505                 if (tokens.capacity() >= 2) {                   //make sure they are using enough stuff
    506                         iter = tokens.begin();                          //what word we are on, starts at first word
    507                         /*
    508                         if (!AEInstallVersion.compare(*iter))
    509                         If mod is too old, skip this mod.
    510                         */
    511                         /*else*/if (!NameOfMod.compare(*iter))  {       //if it contains the name
    512                                 for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
    513                                         if (ARROW.compare(*iter) && NameOfMod.compare(*iter)) {                 //ignores "->" and "NameOfMod"
    514                                                 //cout << *iter;
    515                                                 //cout << " ";
    516                                                 package.name += *iter + " ";
    517                                         }
    518                                 }
    519 
    520                         }
    521                         else if (!ModString.compare(*iter)) {
    522                                 iter++; iter++;
    523                                 package.modStringName = *iter;
    524                                 iter++;
    525                                 package.modStringVersion = atoi((*iter).c_str());
    526                         }
    527                         else if (!HasOnis.compare(*iter)) {
    528                                 iter++; iter++; 
    529                                 if ( boost::iequals(*iter, "Yes")) package.hasOnis = 1;
    530                         }       
    531                         else if (!HasBSL.compare(*iter)) { // string comparer...I know my implementation here sucks. I need to change it to check each character one by one. At the moment,
    532                                 iter++; iter++;  // using "YFR" would probably set it off. :<
    533                                 if ( boost::iequals(*iter, "Yes")) package.hasBSL = 1;
    534                                 else if ( boost::iequals(*iter, "Addon")) package.hasAddon = 1;
    535                         }
    536                         else if (!HasDeltas.compare(*iter)) {
    537                                 iter++; iter++; 
    538                                 if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasDeltas = 1;
    539                         }
    540                         else if (!HasDats.compare(*iter)) {
    541                                 iter++; iter++; 
    542                                 if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasDats = 1;
    543                         }
    544                         else if (!IsEngine.compare(*iter)) {
    545                                 iter++; iter++; 
    546                                 if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.isEngine = 1;
    547                         }
    548                         else if (!GlobalNeeded.compare(*iter)) {
    549                                 iter++; iter++; 
    550                                 if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.globalNeeded = 1;
    551                                 else if (toupper((*iter)[0]) + toupper((*iter)[1]) == 'N' + 'O') package.globalNeeded = 1; //Really the only place where checking for "No" is important atm.
    552                         }
    553                         else if (!Category.compare(*iter))  {   
    554                                 for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
    555                                         if (ARROW.compare(*iter) && Category.compare(*iter)) {                  //ignores "->" and "Category"
    556                                                 //cout << *iter;
    557                                                 //cout << " ";
    558                                                 package.category += *iter + " ";
    559                                         }
    560                         }
    561                 }
    562                 else if (!Creator.compare(*iter))  {    //if it contains the name
    563                         for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
    564                                 if (ARROW.compare(*iter) && Creator.compare(*iter)) {                   //ignores "->" and "Category"
    565                                         //cout << *iter;
    566                                         //cout << " ";
    567                                         package.creator += *iter + " ";
    568                                 }
    569                         }
    570                 }
    571                 else if (!Readme.compare(*iter))  {     //if it contains the name
    572                         for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
    573                                 if (ARROW.compare(*iter) && Readme.compare(*iter)) {                    //ignores "->" and "Category"
    574                                         if(!(*iter).compare("\\n")) package.readme += '\n';
    575                                         else package.readme += *iter + " ";
    576                                 }
    577                         }
    578                 }
    579         }
    580 
    581 }
    582 package.doOutput();
    583 return package;
    584 }
    585 
    586 void recompileAll(vector<string> installedMods)
    587 {try {
    588         busy = 1;
    589         using namespace boost::gregorian;
    590         using namespace boost::posix_time;
    591         using boost::lexical_cast;
    592         using boost::bad_lexical_cast;
    593                 path vanilla_dir = "./VanillaDats/";
    594         string importCommand = "";
    595         char statusString[128];
    596         int numberOfDats = 0;
    597         int j = 1;
    598         string datString;
    599        
    600 
    601         setStatusArea("Importing levels...");
    602         //setStatusArea("Recompiling Data...");
    603 
    604         std::stringstream out;
    605 
    606         ptime start_time(second_clock::local_time());
    607         clearOldDats();
    608        
    609         if(exists("Install.log")) remove("Install.log");
    610         ofstream logfile("Install.log");
    611         logfile << "Mod Installation started " << to_simple_string(start_time) << endl;
    612         logfile.close();
    613 
    614 
    615         if(splitInstances == SPLIT){
    616                 recursive_directory_iterator end_iter;
    617 
    618                 for ( recursive_directory_iterator dir_itr( vanilla_dir );
    619                         dir_itr != end_iter;
    620                         ++dir_itr )
    621                 {
    622                         try{
    623                                 if ( is_directory( dir_itr->status() ) &&  dir_itr.level() == 1)
    624                                 {
    625                                         numberOfDats++;
    626                                 }
    627                         }
    628                         catch(exception & ex) {
    629                                         remove("Install.log");
    630                                         ofstream logfile("Install.log");
    631 
    632 
    633                                         logfile << "Warning, exception " << ex.what() << "!";
    634                                         setStatusArea("Warning, exception " + (string)ex.what() + "!");
    635                                         logfile.close();       
    636                         }
    637                 }
    638                 try {
    639                 //recursive_directory_iterator end_iter;
    640                
    641 
    642                 out << numberOfDats;
    643                 datString = out.str();
    644                         for ( recursive_directory_iterator dir_itr( vanilla_dir );
    645                                 dir_itr != end_iter;
    646                                 ++dir_itr )
    647                         {
    648                                 try
    649                                 {
    650                                         if ( is_directory( dir_itr->status() ) &&  dir_itr.level() == 1)
    651                                         {
    652                                                 importCommand = strOniSplit + " " + strImportOption + " " + dir_itr->path().parent_path().string() + '/' + dir_itr->path().filename();
    653                                                 for (unsigned int i = 0; i < installedMods.size(); ++i) {
    654                                                         if (exists("packages/" + installedMods[i] + "/oni/" + dir_itr->path().parent_path().filename() + '/' + dir_itr->path().filename()  ))
    655                                                                 importCommand += " packages/" + installedMods[i] + "/oni/" + dir_itr->path().parent_path().filename() + '/' + dir_itr->path().filename();
    656 
    657                                                         //else cout << " VanillaDats/" + installedMods[i] + "/oni/";
    658                                                 }
    659                                                 importCommand += " ../GameDataFolder/" + dir_itr->path().filename() + ".dat >> Install.log";
    660 
    661                                                
    662                                                 setProgressBar( (int)(1000 * (float)(j-1) / (float)numberOfDats) ); //100% * dat we're on / total dats
    663                                                 setStatusArea("Step " + lexical_cast<std::string>(j) + '/' + lexical_cast<std::string>(numberOfDats)+ ": Importing " +  dir_itr->path().filename() + " ");
    664 
    665                                                 system(importCommand.c_str());
    666                                                 //Sleep(1000);
    667                                                 //cout << importCommand << "\n";
    668                                                 j++;
    669 
    670                                         }
    671                                 }
    672                                 catch ( const std::exception & ex )
    673                                 {
    674 
    675                                         remove("Install.log");
    676                                         ofstream logfile("Install.log");
    677 
    678 
    679                                         logfile << "Warning, exception " << ex.what() << "!";
    680                                         setStatusArea("Warning, exception " + (string)ex.what() + "!");
    681                                         logfile.close();       
    682                                 }
    683                         }
    684 
    685                 }
    686                 catch( const std::exception & ex ) {
    687 
    688                         remove("Install.log");
    689                         ofstream logfile("Install.log");
    690 
    691 
    692                         logfile << "Warning, exception " << ex.what() << "!";
    693                         setStatusArea("Warning, exception " + (string)ex.what() + "!");
    694                         logfile.close();
    695                 }
    696 
    697         }
    698         else if(splitInstances == NOT_SPLIT){
    699                 directory_iterator end_iter;
    700 
    701                 for ( directory_iterator dir_itr( vanilla_dir );
    702                         dir_itr != end_iter;
    703                         ++dir_itr )
    704                 {
    705 
    706                         if ( is_directory( dir_itr->status() ) )
    707                         {
    708                                 numberOfDats++;
    709                         }
    710 
    711 
    712                 }
    713 
    714                 out << numberOfDats;
    715                 datString = out.str();
    716 
    717                 for ( directory_iterator dir_itr( vanilla_dir );
    718                         dir_itr != end_iter;
    719                         ++dir_itr )
    720                 {
    721                         try
    722                         {
    723                                 if ( is_directory( dir_itr->status() ) )
    724                                 {
    725                                         importCommand = strOniSplit + " " + strImportOption + " " + vanilla_dir.string() + dir_itr->path().filename() + " ";
    726                                         for (unsigned int i = 0; i < installedMods.size(); ++i) {
    727                                                 if (exists("packages/" + installedMods[i] + "/oni/" + dir_itr->path().filename()  ))
    728                                                         importCommand += " packages/" + installedMods[i] + "/oni/" + dir_itr->path().filename();
    729                                         }
    730                                         importCommand += " ../GameDataFolder/" + dir_itr->path().filename() + ".dat >> Install.log";
    731 
    732 
    733                                         setProgressBar( (int)(1000 * (float)(j-1) / (float)numberOfDats) ); //100% * dat we're on / total dats
    734                                         setStatusArea("Step " + lexical_cast<std::string>(j) + '/' + lexical_cast<std::string>(numberOfDats)+ ": Importing " +  dir_itr->path().filename() + " ");
    735 
    736                                         system(importCommand.c_str());
    737 
    738                                         j++;
    739                                 }
    740                         }
    741                         catch ( const std::exception & ex )
    742                         {
    743 
    744                                 remove("Install.log");
    745                                 ofstream logfile("Install.log");
    746 
    747 
    748                                 logfile << "Warning, exception " << ex.what() << "!";
    749                                 setStatusArea("Warning, exception " + (string)ex.what() + "!");
    750                                 logfile.close();
    751                         }}
    752         }
    753 
    754 
    755 
    756        
    757 
    758 
    759 
    760 
    761                
    762                
    763                 vector<string> BSLfolders;
    764                 vector<string> skippedfolders;
    765 
    766                
    767 ofstream BSLlog("BSL.log");
    768                 for ( directory_iterator dir_itr( "../GameDataFolder/IGMD/" ), end_itr;
    769                         dir_itr != end_itr;
    770                         ++dir_itr ) {
    771                                 if( exists(dir_itr->path().string() + "/ignore.txt") ){
    772                                         BSLfolders.push_back(dir_itr->path().filename());
    773                                         skippedfolders.push_back(dir_itr->path().filename());
    774                                 }
    775                 }
    776 
    777                 for (int i = installedMods.size() - 1; i >= 0; i--) {                                                   //Iterates through the installed mods (backwards :P)
    778                         for (unsigned int j = 0; j < globalPackages.size(); ++j) {                              //looking in the global packages
    779                                 if (globalPackages[j].modStringName == installedMods[i]) {      //for a mod that has BSL in it
    780                                 /*BSLlog << "Testing " << globalPackages[j].modStringName << "\n"
    781                                                 << "HasBSL: " << globalPackages[j].hasBSL << "\n"
    782                                                 << "HasAddon: " << globalPackages[j].hasAddon << "\n";*/
    783                                         if(!(globalPackages[j].hasAddon || globalPackages[j].hasBSL)) break; //skip non-BSL
    784                                         if( exists( "packages/" + globalPackages[j].modStringName + "/BSL/" ) ) {
    785                                         copyBSL("packages/" + globalPackages[j].modStringName + "/BSL", BSLfolders, globalPackages[j] );
    786                                         BSLlog << "Copied " <<  globalPackages[j].modStringName << "!\n";
    787                                         }
    788 
    789                                 }
    790 
    791                         }
    792                 }
    793 
    794                 ModPackage emptyPackage;
    795                 emptyPackage.modStringName = "VanillaBSL";
    796                 emptyPackage.hasBSL = 1;
    797                 copyBSL("packages/VanillaBSL/IGMD", BSLfolders, emptyPackage);
    798                 BSLlog.close();
    799        
    800 
    801         logfile << "Writing config file";
    802         writeInstalledMods(installedMods);
    803         setProgressBar(1000);
    804        
    805         string finallyDone = "Done! You can now play Oni.";
    806        
    807 
    808        
    809         setStatusArea(finallyDone);
    810 
    811         ptime end_time(second_clock::local_time());
    812         time_period total_time (start_time, end_time);
    813 
    814 
    815         ofstream logfile2("Install.log", ios::app | ios::ate);
    816         string outstring = (string)"\n\nGlobalization ended " + to_simple_string(end_time) + "\nThe process took ";// + (string)total_time.length();
    817 
    818         logfile2 << "\nInstallation ended " << to_simple_string(end_time) << "\nThe process took " << total_time.length();
    819 
    820         //logfile2.write(outstring.c_str(), outstring.length());
    821         logfile2.close();
    822 
    823         //total_time.length().hours();
    824 
    825         Sleep(1000);
    826         setProgressBar(0);
    827 
    828         }
    829         catch(exception & ex) {
    830                 remove("Install.log"); //why did we do this? :|
    831                 ofstream logfile("Install.log");
    832 
    833 
    834                 logfile << "Warning, exception " << ex.what() << "!";
    835                 setStatusArea("Warning, exception " + (string)ex.what() + "!");
    836                 logfile.close();       
    837         }
    838         busy = 0;
    839 }
    840 
    841 void copyBSL(string copypath, vector<string>& BSLfolders, ModPackage pkg) {
    842 
    843         ofstream BSLlog("BSL2.log", ios::app );
    844        
    845         try {
    846                 for ( directory_iterator dir_itr( copypath ), end_itr;
    847                         dir_itr != end_itr;
    848                         ++dir_itr ) {
    849 
    850                                 if ( is_directory( dir_itr->path() ) && dir_itr->path().string() != ".svn" ) { 
    851                                         BSLlog << "Testing " << dir_itr->path().string() << " HasBSL: " << pkg.hasBSL << " HasAddon: " << pkg.hasAddon << "\n";
    852                                         int skip_folder = 0;
    853 
    854                                         for(unsigned int k = 0; k < BSLfolders.size(); k++)             {//iterate through already found BSL folders   
    855                                                 BSLlog << "testing " << dir_itr->path().filename() << " vs " << BSLfolders[k] << "\n";
    856                                                 if(dir_itr->path().filename() == BSLfolders[k]) {
    857                                                         skip_folder = 1;
    858                                                         BSLlog << "skipping " << BSLfolders[k] << " in " << pkg.modStringName << "\n";
    859                                                         break;
    860                                                 }
    861                                         }
    862                                         if (!skip_folder && !exists("../GameDataFolder/IGMD/" + dir_itr->path().filename() + "/ignore.txt")) {
    863                                                 remove_all( "../GameDataFolder/IGMD/" + dir_itr->path().filename() );
    864                                                 Sleep(100);
    865                                                 create_directory( "../GameDataFolder/IGMD/" + dir_itr->path().filename());
    866                                                 BSLlog << "Copied " << dir_itr->path().string() << " in " << pkg.modStringName << "!\n";
    867                                                 for ( directory_iterator bsl_itr( dir_itr->path() );
    868                                                         bsl_itr != end_itr;
    869                                                         bsl_itr++ ) {
    870                                                                 if ( bsl_itr->path().extension() == ".bsl" ) {
    871                                                                         copy_file(bsl_itr->path(),  "../GameDataFolder/IGMD/" + dir_itr->path().filename() + "/" + bsl_itr->path().filename());
    872                                                                 }
    873                                                 }
    874                                                 BSLfolders.push_back( dir_itr->path().filename() ); //add back check for addon
    875                                                 BSLlog << "Pushing " << dir_itr->path().filename() << "\n" ;
    876                                         }
    877                                 }
    878                 }
    879         }
    880         catch ( const std::exception & ex )
    881         {
    882                 setStatusArea("Warning, exception " + (string)ex.what() + "!");
    883                 while(1) Sleep(1000);
    884         }
    885         BSLlog.close();
    886        
    887 }
    888 
    889 
    890 void writeInstalledMods(vector<string> installedMods)
    891 {
    892 
    893         if ( exists( strInstallCfg ) )
    894         {
    895                 remove( strInstallCfg );
    896         }
    897 
    898         ofstream file(strInstallCfg.c_str());
    899 
    900         vector<string>list = installedMods;
    901         vector<string>::iterator begin_iter = list.begin();
    902         vector<string>::iterator end_iter = list.end();
    903 
    904         sort( list.begin(), list.end() );
    905 
    906         for( ; begin_iter != end_iter; ++begin_iter) {
    907                 file << *begin_iter << " ";
    908         }
    909 
    910         file.close();
    911         file.clear();
    912 
    913 }
    914 
    915 vector<string> getInstallString(string Cfg)
    916 {
    917         //system(strPauseCmd);
    918         vector<string> returnval;
    919 
    920         string line;
    921         fstream file;
    922 
    923         if (exists( Cfg ))
    924         {
    925                 file.open(Cfg.c_str());
    926                 getline(file, line);
    927                 tokenize(line, returnval);
    928                 file.close();
    929                 file.clear();
    930                 sort(returnval.begin(), returnval.end());
    931         }
    932         else cout << "fail";
    933 
    934         return returnval;
    935 }
    936 
    937 //stolen token function...
    938 void tokenize(const string& str, vector<string>& tokens, const string& delimiters)
    939 {
    940         // Skip delimiters at beginning.
    941         string::size_type lastPos = str.find_first_not_of(delimiters, 0);
    942         // Find first "non-delimiter".
    943         string::size_type pos     = str.find_first_of(delimiters, lastPos);
    944 
    945         while (string::npos != pos || string::npos != lastPos)
    946         {
    947                 // Found a token, add it to the vector.
    948                 tokens.push_back(str.substr(lastPos, pos - lastPos));
    949                 // Skip delimiters.  Note the "not_of"
    950                 lastPos = str.find_first_not_of(delimiters, pos);
    951                 // Find next "non-delimiter"
    952                 pos = str.find_first_of(delimiters, lastPos);
    953         }
    954 }
    955 
    956 void clearOldDats(void) {
    957         directory_iterator end_iter_gdf;
    958         for ( directory_iterator dir_itr_gdf( "../GameDataFolder" );
    959                 dir_itr_gdf != end_iter_gdf;
    960                 ++dir_itr_gdf )
    961         {
    962                 //cout << dir_itr_gdf->path().extension() << "\n";
    963                 if ( dir_itr_gdf->path().extension() == ".dat" || dir_itr_gdf->path().extension() == ".raw" || dir_itr_gdf->path().extension() == ".sep" ) {
    964                         remove( dir_itr_gdf->path() );
    965                 }
    966 
    967         }
    968 
    969 }
    970 
    971 #include "boost/thread.hpp"
    97220#include <boost/thread/mutex.hpp>
    973 
    974 /////////////////////////////////////////////////////////////////////////////
    975 // Name:        main_window.cpp
    976 // Purpose:     
    977 // Author:     
    978 // Modified by:
    979 // Created:     07/05/2009 20:38:25
    980 // RCS-ID:     
    981 // Copyright:   
    982 // Licence:     
    983 /////////////////////////////////////////////////////////////////////////////
    984 
    98521// For compilers that support precompilation, includes "wx/wx.h".
    98622#include "wx/wxprec.h"
     
    99632////@begin includes
    99733#include "about.h"
     34#include "main_window.h"
     35#include "installer.h"
    99836////@end includes
    999 
    1000 #include "main_window.h"
    100137
    100238////@begin XPM images
     
    100844////@end XPM images
    100945
    1010 //#define wxDebug 1;
    1011 //#define wxUSE_UNICODE 1;
     46bool busy = false;
     47vector<string> globalInstalledMods;
     48vector<ModPackage> globalPackages;
     49// Variable declarations
     50#ifdef WIN32
     51bool splitInstances = true;
     52string strImportOption = "-import:nosep";
     53string strOniSplit = "Onisplit.exe";
     54#else
     55bool splitInstances = false;
     56string strImportOption = "-import:sep";
     57string strOniSplit = "mono Onisplit.exe";
     58#endif
    101259
    101360/*
     
    1093140}
    1094141
    1095 
    1096142/*
    1097143* MainWindow destructor
     
    1103149        ////@end MainWindow destruction
    1104150}
    1105 
    1106151
    1107152/*
     
    1129174    ReglobalizeButton = NULL;
    1130175        ////@end MainWindow member initialisation
    1131 
    1132 }
    1133 
     176}
    1134177
    1135178/*
     
    1169212    itemMenu42->Append(wxID_OPTIONS, _("Show Advanced Options..."), wxEmptyString, wxITEM_CHECK);
    1170213    menuBar->Append(itemMenu42, _("Options"));
    1171     wxMenu* itemMenu44 = new wxMenu;
    1172214#ifdef WIN32
    1173215        itemMenu44->Append(wxID_ABOUT, _("About"), wxEmptyString, wxITEM_NORMAL);
     
    1242284    StatusArea->SetName(_T("StatusArea"));
    1243285    StatusArea->SetFieldsCount(1);
    1244     StatusArea->SetStatusText(_("AE Installer v1.0.1"), 0);
     286        string versionText = "AE Installer v" + (string)INSTALLER_VERSION;
     287    StatusArea->SetStatusText(versionText.c_str(), 0);
    1245288    itemBoxSizer2->Add(StatusArea, 0, wxGROW|wxALL, 0);
    1246289
     
    1312355        ::CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList, (void **)&pTaskbarList);
    1313356#endif
    1314 
    1315 
    1316         /*if ( exists( "../../GameDataFolder/level0_Final.sep" ) ) {
    1317                 strImportOption = "-import:sep";
    1318                 splitInstances = NOT_SPLIT;
    1319         }
    1320         else {
    1321                 strImportOption = "-import:nosep";
    1322                 splitInstances = SPLIT;
    1323         }*/
    1324        
    1325 
    1326 #ifndef WIN32
    1327                 strImportOption = "-import:sep";
    1328                 splitInstances = NOT_SPLIT;
    1329 #else
    1330                 strImportOption = "-import:nosep";
    1331                 splitInstances = SPLIT;
    1332 #endif
    1333 
    1334 #ifndef WIN32
    1335         strImportOption = "-import:sep";
    1336         splitInstances = NOT_SPLIT;
    1337 #else
    1338         strImportOption = "-import:nosep";
    1339         splitInstances = SPLIT;
    1340 #endif
    1341357       
    1342358        globalPackages = getPackages();
     
    1352368        OptionsPanel->Hide();
    1353369       
    1354 //#ifndef WIN32
    1355 //      itemMenu37->Append(wxID_ABOUT, _("About"), wxEmptyString, wxITEM_NORMAL);
    1356        
    1357 //#endif
    1358        
    1359         if(splitInstances == SPLIT) SeperatedRadio->SetValue(true);
     370        if(splitInstances) SeperatedRadio->SetValue(true);
    1360371        else CompleteRadio->SetValue(true);
    1361372        if(strImportOption == "-import:nosep") NoSepRadio->SetValue(true);
    1362373        else SepRadio->SetValue(true);
    1363 
    1364374
    1365375#ifdef WIN32
     
    1368378        ShowWindow( hWnd, SW_HIDE );
    1369379#endif
    1370 
    1371         //MainWindow::SetSize(MainWindow::GetRect().GetWidth(), MainWindow::GetRect().GetHeight()-OptionsPanel->GetRect().GetHeight() );
    1372 }
    1373 
     380}
    1374381
    1375382/*
     
    1382389        case wxCHK_UNCHECKED:
    1383390                for(unsigned int i = 0; i < globalPackages.size(); i++) Mods_CheckboxList->Check(i, false);
    1384                 //SelectAll->Set3StateValue(wxCHK_CHECKED);
    1385391                break;
    1386392        case wxCHK_CHECKED:
    1387393                for(unsigned int i = 0; i < globalPackages.size(); i++) Mods_CheckboxList->Check(i, true);
    1388                 //SelectAll->Set3StateValue(wxCHK_UNCHECKED);
    1389394                break;
    1390395        case wxCHK_UNDETERMINED:
    1391396                for(unsigned int i = 0; i < globalPackages.size(); i++) Mods_CheckboxList->Check(i, false);
    1392                 //SelectAll->Set3StateValue(wxCHK_CHECKED);
    1393397                break;
    1394 
    1395         }
    1396 
    1397 }
    1398 
     398        }
     399}
    1399400
    1400401/*
     
    1404405void MainWindow::ModList_OnCreate( wxWindowCreateEvent& event )
    1405406{
    1406 
    1407407
    1408408}
     
    1457457wxIcon MainWindow::GetIconResource( const wxString& name )
    1458458{
    1459 
    1460459        // Icon retrieval
    1461460        ////@begin MainWindow icon retrieval
     
    1470469}
    1471470
    1472 
    1473471/*
    1474472* wxEVT_COMMAND_LISTBOX_SELECTED event handler for Mods_CheckboxList1
     
    1477475void MainWindow::OnModsCheckboxList1Selected( wxCommandEvent& event )
    1478476{
    1479         //event.GetSelection
    1480477        titleText->SetValue(globalPackages[event.GetSelection()].name.c_str());
    1481478        creatorText->SetValue(globalPackages[event.GetSelection()].creator.c_str());
    1482479        descriptionText->SetValue(globalPackages[event.GetSelection()].readme.c_str());
    1483 
    1484         //creatorText->Refresh();
    1485 }
    1486 
     480}
    1487481
    1488482/*
     
    1519513                this->SetSize(this->GetRect().GetWidth(), this->GetRect().GetHeight()-OptionsPanel->GetRect().GetHeight());}
    1520514        else {
    1521 //              Uncomment this when we release, it gets annoying if you are testing globalization a lot ;)
    1522                 wxMessageDialog* YesNoDialog = new wxMessageDialog(this,                        "WARNING: These options are for advanced users only, use with caution.",
     515                wxMessageDialog* YesNoDialog = new wxMessageDialog(this, "WARNING: These options are for advanced users only, use with caution.",
    1523516                                                                                                                   "AE Installer Alert",  wxOK | wxICON_EXCLAMATION     , wxDefaultPosition);
    1524517                YesNoDialog->ShowModal();
     
    1529522}
    1530523
    1531 
    1532524/*
    1533525* wxEVT_COMMAND_MENU_SELECTED event handler for wxID_EXIT
     
    1539531}
    1540532
    1541 
    1542533/*
    1543534* wxEVT_COMMAND_BUTTON_CLICKED event handler for Install_Button
    1544535*/
    1545 
    1546536
    1547537struct recompile
     
    1555545               
    1556546        }
    1557 
    1558547        vector<string> thePackages;
    1559548};
     
    1565554}
    1566555
    1567 
    1568 
    1569556void MainWindow::OnInstallButtonClick( wxCommandEvent& event )
    1570557{
    1571 
    1572558        vector<string> localPackages;
    1573559        localPackages.push_back("00000Globalize");
     
    1576562                sort(localPackages.begin(), localPackages.end());
    1577563                localPackages[0] = "Globalize";
    1578                 //MainWindow::MainWindow().Hide();     
    1579                 //      boost::thread thrd2(recompileAll(localPackages) );
    1580                 //MainWindow::MainWindow().Show();
    1581564                this->InstallButton->Disable();
    1582565                this->ReglobalizeButton->Disable();
     
    1587570                recompileAll(localPackages);
    1588571#endif
    1589 
    1590572                this->InstallButton->Enable();
    1591573                this->ReglobalizeButton->Enable();
    1592574        }
    1593 
    1594 
    1595 }
    1596 
    1597 /*void setStatusArea( string s ) {
    1598 //TheStatusBar = MainWindow::StatusArea;
    1599 (**TheStatusBar).SetStatusText(_(s.c_str()), 0);
    1600 
    1601 //MainWindow::MainWindow().SetSize(MainWindow::MainWindow().GetRect().GetWidth(), MainWindow::MainWindow().GetRect().GetHeight()+1);
    1602 
    1603 //MainWindow::StatusBar->SetLabel("Importing Files...");
    1604 //StatusBar->SetLabel(s);
    1605 //->SetLabel(s);
    1606 
    1607 }*/
    1608 
    1609 void setProgressBar( int i ) {
    1610         //TheProgressBar->SetValue(
     575}
     576
     577void setProgressBar( int i )
     578{
    1611579#ifdef WIN32
    1612        
    1613 
    1614 
    1615580if (SUCCEEDED(pTaskbarList->QueryInterface(IID_ITaskbarList3, (void **)&pTaskbarList3)))
    1616581{
    1617        
    1618582        pTaskbarList3->SetProgressValue(Handle,i, 1000);
    1619         if ( i == 0 ) {
    1620 
    1621         pTaskbarList3->SetProgressState(Handle,TBPF_NOPROGRESS);
    1622         }
    1623 }
    1624 
    1625 
     583        if ( i == 0 )
     584        {
     585                pTaskbarList3->SetProgressState(Handle,TBPF_NOPROGRESS);
     586        }
     587}
    1626588#endif
    1627589        TheProgressBar->SetValue(i);
    1628 
    1629 }
    1630 
     590}
    1631591
    1632592/*
     
    1642602}
    1643603
    1644 
    1645604/*
    1646605* wxEVT_COMMAND_MENU_SELECTED event handler for wxID_ABOUT
     
    1651610        ////@begin wxEVT_COMMAND_MENU_SELECTED event handler for wxID_ABOUT in MainWindow.
    1652611    // Before editing this code, remove the block markers.
     612        // TODO: Make About window work again!
    1653613    About* window = new About(this);
    1654     int returnValue = window->ShowModal();
    1655614    window->Destroy();
    1656615        ////@end wxEVT_COMMAND_MENU_SELECTED event handler for wxID_ABOUT in MainWindow.
    1657616}
    1658617
    1659 
    1660618/*
    1661619* wxEVT_COMMAND_RADIOBUTTON_SELECTED event handler for NoSep_RadioButton
     
    1667625}
    1668626
    1669 
    1670627/*
    1671628* wxEVT_COMMAND_RADIOBUTTON_SELECTED event handler for Sep_RadioButton
     
    1677634}
    1678635
    1679 
    1680636/*
    1681637* wxEVT_COMMAND_RADIOBUTTON_SELECTED event handler for Separated_RadioButton
     
    1688644void MainWindow::OnCompleteRadioButtonSelected( wxCommandEvent& event )
    1689645{
    1690         splitInstances = NOT_SPLIT;
    1691 
    1692 }
    1693 
     646        splitInstances = false;
     647}
    1694648
    1695649/*
     
    1702656}
    1703657
    1704 
    1705658/*
    1706659* wxEVT_COMMAND_MENU_SELECTED event handler for wxID_LOAD
    1707660*/
    1708661
    1709 
    1710 
    1711 
    1712 void MainWindow::refreshMods (vector<string> s) {
    1713 
     662// TODO: Make refreshMods actually refresh the list in the window of available mods so we can see any new package info and deleted mods are removed from the list
     663void MainWindow::refreshMods (vector<string> s)
     664{
    1714665        Mods_CheckboxList->Clear();
    1715         //globalInstalledMods = getPackages();
    1716666        for (unsigned int i = 0; i < globalPackages.size(); i++) {
    1717667                Mods_CheckboxList->Append(globalPackages[i].name.c_str());
    1718                 if( binary_search(s.begin(), s.end(), globalPackages[i].modStringName ) ) Mods_CheckboxList->Check(i);
    1719                 //else Mods_CheckboxList->Check(i,0);
    1720 
     668                if( binary_search(s.begin(), s.end(), globalPackages[i].modStringName ) )
     669                        Mods_CheckboxList->Check(i);
    1721670        }
    1722671}
     
    1738687                refreshMods(getInstallString( string(openFileDialog->GetPath()) ));
    1739688        }
    1740 
    1741 
    1742 }
    1743 
     689}
    1744690
    1745691/*
     
    1761707        if ( openFileDialog->ShowModal() == wxID_OK )
    1762708        {
    1763 
    1764 
    1765                 //Mods_CheckboxList->
    1766 
    1767 
    1768 
    1769                 //
    1770 
    1771709                if ( exists( openFileDialog->GetPath().c_str() ) )
    1772710                {
     
    1789727                file.close();
    1790728                file.clear();
    1791 
    1792                 //SetCurrentFilename(openFileDialog->GetFilename());
    1793                 //theText->LoadFile(openFileDialog->GetFilename());
    1794                 //SetStatusText(GetCurrentFilename(), 0);
    1795                 //SetStatusText(openFileDialog->GetDirectory(),1);
    1796         }
    1797 }
    1798 
    1799 
     729        }
     730}
    1800731
    1801732/*
     
    1805736void MainWindow::OnReGlobalizeButtonClick( wxCommandEvent& event )
    1806737{
    1807         wxMessageDialog* YesNoDialog = new wxMessageDialog(this,                        "WARNING: This will DELETE the Edition's GameDataFolder and recreate it from the vanilla Oni game data. \n Are you SURE you want to do this? ", "AE Installer Alert",  wxYES_NO | wxICON_EXCLAMATION    , wxDefaultPosition);
    1808 
    1809         if (YesNoDialog->ShowModal() == wxID_NO) { //if the user said no...
    1810 
    1811         }
    1812         else {
    1813        
     738        string YesNoMsg = "WARNING: This will DELETE the Edition's GameDataFolder and recreate it from the vanilla Oni game data.\n";
     739        YesNoMsg = YesNoMsg + "Are you SURE you want to do this?";
     740        wxMessageDialog* YesNoDialog = new wxMessageDialog(this, YesNoMsg.c_str(), "AE Installer Alert",  wxYES_NO | wxICON_EXCLAMATION , wxDefaultPosition);
     741
     742        if (YesNoDialog->ShowModal() == wxID_NO)
     743        {
     744                //if the user said no...
     745        }
     746        else
     747        {
    1814748                this->InstallButton->Disable();
    1815749                this->ReglobalizeButton->Disable();
    1816 
    1817750#ifdef WIN32
    1818 
    1819751                boost::thread thrd2(globalizeData);
    1820752                //globalizeData();
     
    1825757                globalizeData();
    1826758#endif
    1827                
    1828759                this->InstallButton->Enable();
    1829760                this->ReglobalizeButton->Enable();
    1830761        }
    1831 
    1832762}
    1833763/*
    1834764* wxEVT_COMMAND_RADIOBUTTON_SELECTED event handler for Separated_RadioButton
    1835765*/
    1836 
    1837 /*void MainWindow::OnSeparatedRadioButtonSelected( wxCommandEvent& event )
    1838 {
    1839 ////@begin wxEVT_COMMAND_RADIOBUTTON_SELECTED event handler for Separated_RadioButton in MainWindow.
    1840 // Before editing this code, remove the block markers.
    1841 event.Skip();
    1842 ////@end wxEVT_COMMAND_RADIOBUTTON_SELECTED event handler for Separated_RadioButton in MainWindow.
    1843 }*/
    1844 
    1845766
    1846767/*
     
    1850771void MainWindow::OnSeperatedRadioButtonSelected( wxCommandEvent& event )
    1851772{
    1852 splitInstances = SPLIT;
    1853 }
    1854 
     773        splitInstances = true;
     774}
  • AE/Installer/trunk/source/main_window.h

    r385 r487  
     1/***************************************************************************\
     2| Project: AE Installer                                                                                                         |
     3| By: Gumby & Iritscen                                                                                                          |
     4| File: Main_Window.h                                                                                                           |
     5| Function: Handles GUI.                                                                                                        |
     6| Created: 07/05/2009 20:38:25                                                                                          |
     7\***************************************************************************/
    18
    2 
    3 /////////////////////////////////////////////////////////////////////////////
    4 // Name:        main_window.h
    5 // Purpose:     
    6 // Author:     
    7 // Modified by:
    8 // Created:     07/05/2009 20:38:25
    9 // RCS-ID:     
    10 // Copyright:   
    11 // Licence:     
    12 /////////////////////////////////////////////////////////////////////////////
    139
    1410#ifndef _MAINWINDOW_H_
    1511#define _MAINWINDOW_H_
    1612
    17 
    1813/*!
    1914 * Includes
    2015 */
    21 
     16#pragma mark INCLUDES
    2217////@begin includes
     18#include "wx/bmpbuttn.h"
     19#include "wx/checkbox.h"
     20#include "wx/checklst.h"
    2321#include "wx/frame.h"
     22#include "wx/gauge.h"
     23#include "wx/generic/panelg.h"
     24#include "wx/radiobut.h"
    2425#include "wx/splitter.h"
    2526#include "wx/statline.h"
    2627#include "wx/statusbr.h"
     28#include "wx/textctrl.h"
     29#include <vector>
     30using namespace std;
    2731////@end includes
    2832
     
    3943 * Control identifiers
    4044 */
    41 
     45#pragma mark DEFINES
    4246////@begin control identifiers
    4347#define ID_MAINWINDOW 10000
     
    6973////@end control identifiers
    7074
    71 
    7275/*!
    7376 * MainWindow class declaration
    7477 */
    7578
    76 using namespace std;
    77 
    78 #include <vector>
    79 
     79#pragma mark CLASS DECLARATIONS
    8080class MainWindow: public wxFrame
    8181{   
     
    8686    /// Constructors
    8787    MainWindow();
    88     MainWindow( wxWindow* parent, wxWindowID id = SYMBOL_MAINWINDOW_IDNAME, const wxString& caption = SYMBOL_MAINWINDOW_TITLE, const wxPoint& pos = SYMBOL_MAINWINDOW_POSITION, const wxSize& size = SYMBOL_MAINWINDOW_SIZE, long style = SYMBOL_MAINWINDOW_STYLE );
     88    MainWindow( wxWindow* parent, wxWindowID id = SYMBOL_MAINWINDOW_IDNAME, const wxString& caption = SYMBOL_MAINWINDOW_TITLE,
     89                           const wxPoint& pos = SYMBOL_MAINWINDOW_POSITION, const wxSize& size = SYMBOL_MAINWINDOW_SIZE, long style = SYMBOL_MAINWINDOW_STYLE );
    8990
    90     bool Create( wxWindow* parent, wxWindowID id = SYMBOL_MAINWINDOW_IDNAME, const wxString& caption = SYMBOL_MAINWINDOW_TITLE, const wxPoint& pos = SYMBOL_MAINWINDOW_POSITION, const wxSize& size = SYMBOL_MAINWINDOW_SIZE, long style = SYMBOL_MAINWINDOW_STYLE );
     91    bool Create( wxWindow* parent, wxWindowID id = SYMBOL_MAINWINDOW_IDNAME, const wxString& caption = SYMBOL_MAINWINDOW_TITLE,
     92                                const wxPoint& pos = SYMBOL_MAINWINDOW_POSITION, const wxSize& size = SYMBOL_MAINWINDOW_SIZE, long style = SYMBOL_MAINWINDOW_STYLE );
    9193
    9294    /// Destructor
     
    190192#endif
    191193    // _MAINWINDOW_H_
    192 void doglobalizeData(void);
Note: See TracChangeset for help on using the changeset viewer.