Changeset 487
- Timestamp:
- Dec 30, 2009, 2:51:38 AM (15 years ago)
- Location:
- AE
- Files:
-
- 1 added
- 11 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 \***************************************************************************/ 22 8 23 9 ////@begin includes 24 10 ////@end includes 25 11 #include "globals.h" 26 12 #include "about.h" 27 13 28 14 ////@begin XPM images 29 15 ////@end XPM images 30 31 16 32 17 /* … … 126 111 itemPanel3->SetSizer(itemBoxSizer4); 127 112 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 ); 129 129 itemBoxSizer4->Add(itemStaticText5, 0, wxALIGN_LEFT|wxALL, 5); 130 130 -
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 \***************************************************************************/ 11 8 12 9 #ifndef _ABOUT_H_ 13 10 #define _ABOUT_H_ 14 15 11 16 12 /*! -
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 11 11 #include "boost/thread.hpp" 12 #include <boost/thread/mutex.hpp>12 #include "boost/thread/mutex.hpp" 13 13 #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" 27 17 28 18 ////@begin includes 29 19 ////@end includes 30 20 31 #include "aeinstallerapp.h" 32 #include <string> 21 Install_info_cfg currentAE, updateAE; 22 MainWindow* TheWindow; 33 23 34 24 ////@begin XPM images … … 88 78 */ 89 79 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. */ 90 83 bool AEInstallerApp::OnInit() 91 84 { … … 93 86 // Remove the comment markers above and below this block 94 87 // to make permanent changes to the code. 95 96 88 #if wxUSE_XPM 97 89 wxImage::AddHandler(new wxXPMHandler); … … 111 103 TheWindow = mainWindow; 112 104 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(¤tAE, &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(¤tAE, &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(¤tAE, &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(¤tAE, &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 182 bool CheckForRequiredSoftware(void) 183 { 113 184 #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) 118 197 system("start http://www.microsoft.com/downloads/details.aspx?familyid=0856eacb-4362-4b0d-8edd-aab15c5e04f5"); 119 }120 198 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); 143 218 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 225 bool 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 155 235 if (YesNoDialog->ShowModal() == wxID_NO) // if the user said no... 236 { 156 237 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 161 244 #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 179 254 return true; 180 255 } 181 256 182 183 void setStatusArea( string s ){257 void setStatusArea(string s) 258 { 184 259 wxString wxs(s.c_str(), wxConvUTF8); 185 260 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); 207 262 } 208 263 … … 218 273 ////@end AEInstallerApp cleanup 219 274 } 220 void doglobalizeData() {221 //TheWindow->Disable(); 275 void doglobalizeData() 276 { 222 277 globalizeData(); 223 278 #ifdef WIN32 224 279 while(1) Sleep(-1); 225 280 #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 \***************************************************************************/ 11 8 12 9 #ifndef _AEINSTALLERAPP_H_ … … 19 16 20 17 ////@begin includes 18 #include "wx/app.h" 21 19 #include "wx/image.h" 22 20 #include "main_window.h" 23 21 ////@end includes 24 25 string escapePath(string input);26 22 27 23 /*! … … 82 78 #endif 83 79 // _AEINSTALLERAPP_H_ 84 int globalizeData(void); 80 85 81 void globalize2(void); 86 MainWindow* TheWindow; 82 bool CheckForRequiredSoftware(void); 83 void 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 \***************************************************************************/ 11 8 12 // For compilers that support precompilation, includes "wx/wx.h".13 #include "wx/wxprec.h"14 15 #ifdef __BORLANDC__16 #pragma hdrstop17 #endif18 19 #ifndef WX_PRECOMP20 #include "wx/wx.h"21 #endif22 9 23 10 ////@begin includes 24 11 ////@end includes 25 12 #include "globals.h" 26 13 #include "app_resources.h" 27 14 -
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 11 9 12 10 #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 5 11 6 12 #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" 20 17 #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 20 using namespace boost::gregorian; 21 using namespace boost::posix_time; 22 23 // externs declared in installer.h 24 string strInstallCfg = "../GameDataFolder/Add.cfg"; 25 string strEUFN = "Edition"; // GetUpdateStatus() may set this to "Edition-patch" later, but this is the assumed name of the new Edition folder in Updates/ 26 27 int 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!"); 72 37 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 150 50 path Characters = "../GameDataFolder/level0_Characters"; 151 51 path Particles = "../GameDataFolder/level0_Particles"; … … 156 56 path TRAC = Animations / "level0_TRAC"; 157 57 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"; 172 87 create_directory( "../GameDataFolder/" ); 88 173 89 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/" ); 178 94 create_directory( Characters ); 179 95 create_directory( Particles ); … … 184 100 create_directory( TRAC ); 185 101 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; 186 112 187 113 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 ) 201 133 { 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 } 202 220 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()); 271 227 272 228 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"; 278 241 for (int i = 0; i < 15; i++) 279 242 { 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 } 292 253 create_directory( VanillaParticles.parent_path() ); 293 254 create_directory( VanillaTextures.parent_path() ); 294 255 create_directory( VanillaSounds.parent_path() ); 295 256 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"); 305 285 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; 310 320 return err; 311 321 } 312 322 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) 323 vector<ModPackage> getPackages(string packageDir) 497 324 { 498 325 vector<ModPackage> packages; 499 packages.reserve( 65536); // come on, we shouldn't need this much space...right?!326 packages.reserve(256); 500 327 fstream file; 501 328 string filename = "\0"; … … 504 331 try 505 332 { 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) 508 334 { 509 335 file.open((dir_itr->path().string() + "/" + MODINFO_CFG).c_str()); 510 //cout << filename << "\n";511 336 512 337 if(!file.fail()) 513 338 { 514 //cout << dir_itr->path().string() + MODINFO_CFG;515 339 //would prefer to push a pointer to a package, but this will do for now 516 340 packages.push_back(fileToModPackage(file)); … … 519 343 file.clear(); 520 344 } 345 sort(packages.begin(), packages.end()); 521 346 } 522 347 catch (const std::exception & ex) … … 559 384 vector<string>::iterator iter; 560 385 tokenize(line, tokens); //string to vector of "words" 561 if (tokens.capacity() >= 2) { //make sure they are using enough stuff386 if (tokens.capacity() >= 3) { //make sure they are using enough stuff 562 387 iter = tokens.begin(); //what word we are on, starts at first word 563 /* 388 /* TODO: Get this "required Installer version" code working 564 389 if (!AEInstallVersion.compare(*iter)) 565 390 If mod is too old, skip this mod. 566 391 */ 567 392 /*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" 572 395 package.name += *iter + " "; 573 396 } … … 583 406 else if (!HasOnis.compare(*iter)) { 584 407 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-insensitive586 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; 590 413 } 591 414 else if (!HasDeltas.compare(*iter)) { … … 604 427 iter++; iter++; 605 428 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 theonly 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. 607 430 } 608 431 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" 613 434 package.category += *iter + " "; 614 435 } … … 616 437 } 617 438 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" 622 441 package.creator += *iter + " "; 623 442 } … … 625 444 } 626 445 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 theline or a "//" comment628 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" 629 448 if(!(*iter).compare("\\n")) package.readme += '\n'; 630 449 else package.readme += *iter + " "; … … 635 454 636 455 } 637 package.doOutput(); 456 638 457 return package; 639 458 } 640 459 641 460 void 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/"; 651 468 string importCommand = ""; 652 char statusString[128];653 469 int numberOfDats = 0; 654 470 int j = 1; 655 471 string datString; 472 473 setStatusArea("Importing levels..."); 474 656 475 std::stringstream out; 657 476 658 477 ptime start_time(second_clock::local_time()); 659 478 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 { 662 487 recursive_directory_iterator end_iter; 663 488 … … 672 497 } 673 498 } 674 catch(exception ex) { 499 catch(exception & ex) { 500 remove("Install.log"); 501 ofstream logfile("Install.log"); 675 502 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 } 684 508 try { 509 out << numberOfDats; 510 datString = out.str(); 685 511 for ( recursive_directory_iterator dir_itr( vanilla_dir ); 686 512 dir_itr != end_iter; … … 692 518 { 693 519 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) { 695 521 if (exists("packages/" + installedMods[i] + "/oni/" + dir_itr->path().parent_path().filename() + '/' + dir_itr->path().filename() )) 696 522 importCommand += " packages/" + installedMods[i] + "/oni/" + dir_itr->path().parent_path().filename() + '/' + dir_itr->path().filename(); 697 698 //else cout << " packages/VanillaDats/" + installedMods[i] + "/oni/";699 523 } 700 importCommand += " ../GameDataFolder/" + dir_itr->path().filename() + ".dat >> Onisplit.log";524 importCommand += " ../GameDataFolder/" + dir_itr->path().filename() + ".dat >> Install.log"; 701 525 702 sprintf(statusString,"%d/%i\0",j,numberOfDats);526 703 527 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() + " "); 705 529 706 530 system(importCommand.c_str()); 707 //Sleep(1000); 708 //cout << importCommand << "\n"; 709 j++; 710 531 j++; 711 532 } 712 533 } 713 534 catch ( const std::exception & ex ) 714 535 { 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 } 719 543 } 720 544 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){ 728 553 directory_iterator end_iter; 729 554 … … 732 557 ++dir_itr ) 733 558 { 734 735 559 if ( is_directory( dir_itr->status() ) ) 736 560 { 737 561 numberOfDats++; 738 562 } 739 740 741 563 } 742 564 … … 752 574 if ( is_directory( dir_itr->status() ) ) 753 575 { 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) { 757 578 if (exists("packages/" + installedMods[i] + "/oni/" + dir_itr->path().filename() )) 758 579 importCommand += " packages/" + installedMods[i] + "/oni/" + dir_itr->path().filename(); 759 580 } 760 importCommand += " ../GameDataFolder/" + dir_itr->path().filename() + ".dat ";581 importCommand += " ../GameDataFolder/" + dir_itr->path().filename() + ".dat >> Install.log"; 761 582 762 sprintf(statusString,"%d/%i\0",j,numberOfDats);763 583 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() + " "); 766 585 system(importCommand.c_str()); 767 768 586 j++; 769 587 } … … 771 589 catch ( const std::exception & ex ) 772 590 { 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"; 777 632 writeInstalledMods(installedMods); 778 633 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); 781 647 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 659 void 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 784 707 785 708 void writeInstalledMods(vector<string> installedMods) 786 { 787 709 { 788 710 if ( exists( strInstallCfg ) ) 789 711 { … … 805 727 file.close(); 806 728 file.clear(); 807 808 729 } 809 730 810 731 vector<string> getInstallString(string Cfg) 811 732 { 812 //system(strPauseCmd); 813 vector<string> returnval; 814 733 vector<string> returnval; 815 734 string line; 816 735 fstream file; … … 830 749 } 831 750 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 */ 770 int 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(¤tAECfg, 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 920 bool 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. */ 1070 bool 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 1124 bool 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 1168 bool 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. */ 1420 void 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. */ 1433 bool SortBySize(string a, string b) 1434 { 1435 return (a.size() < b.size()); 1436 } 1437 832 1438 //stolen token function... 833 1439 void tokenize(const string& str, vector<string>& tokens, const string& delimiters) … … 855 1461 ++dir_itr_gdf ) 856 1462 { 857 //cout << dir_itr_gdf->path().extension() << "\n";858 1463 if ( dir_itr_gdf->path().extension() == ".dat" || dir_itr_gdf->path().extension() == ".raw" || dir_itr_gdf->path().extension() == ".sep" ) { 859 1464 remove( dir_itr_gdf->path() ); … … 863 1468 864 1469 } 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 1475 void 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 1522 void 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 1538 string 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 1552 Install_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 1565 ModPackage::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 1583 void Sleep(int ms) 1584 { 1585 sleep(ms / 1000); 1586 } 1587 1588 #ifdef WIN32 1589 1590 void 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 3 9 #ifndef DOUBLE_HEADER 4 10 #define DOUBLE_HEADER 5 11 6 7 12 #include <string> 8 13 #include <vector> 14 #include <iostream> 15 #include "globals.h" 16 #ifdef WIN32 17 #ifndef __GUICON_H__ 18 #define __GUICON_H__ 19 #endif 9 20 #include <fstream> 21 #include <windows.h> 22 #include <stdio.h> 23 #include <fcntl.h> 24 #include <io.h> 10 25 11 using namespace std; 26 void RedirectIOToConsole(); 27 // maximum mumber of lines the output console should have 28 static const WORD MAX_CONSOLE_LINES = 500; 29 #endif 12 30 31 32 #pragma mark GLOBALS 13 33 static string SLASHSLASH = "//"; 14 34 static string DIRSLASH = "\\"; 15 string strInstallCfg = "../GameDataFolder/Add.cfg"; 16 static string strInstallerVersion = "1.0"; 35 extern bool busy; 36 extern string strInstallCfg;// = "../GameDataFolder/Add.cfg"; 37 extern Install_info_cfg currentAE, updateAE; 38 extern bool splitInstances; 39 extern string strImportOption; 40 extern string strOniSplit; 41 extern vector<ModPackage> globalPackages; 42 extern string strEUFN; // I don't mind long variable names, but even I think strEditionUpdateFolderName is a bit much 43 #ifndef WIN32 44 void Sleep(int ms); // crudely converts the Windows sleep() call, which operates in ms, to the Mac sleep() call that operates in seconds 45 #endif 17 46 18 #define STRUCT_DEFS19 struct ModPackage20 {21 bool isInstalled; //replace with function22 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();36 47 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 86 49 int mainMenu(void); 87 int globalizeData(void);50 vector<string> getInstallString(string = strInstallCfg); 88 51 int installPackages(void); 89 52 int uninstallPackages(void); 90 53 int listInstalledPackages(void); 91 54 int printInstallerInfo(void); 92 vector<ModPackage> getPackages(void);93 55 ModPackage fileToModPackage(fstream&); 94 void recompileAll(vector<string>); 95 vector<string> getInstallString(string = strInstallCfg); 56 bool StringIsLegalPathForDeletion(string); 57 vector<ModPackage> getPackages(string packageDir = "./packages"); 58 void MakePathLocalToGlobalize(string*); 59 bool SortBySize(string, string); 96 60 void tokenize(const string&, vector<string>&, const string& delimiters = " "); 97 //bool getDirectoryContents(char , char &);98 61 void clearOldDats(void); 99 62 void writeInstalledMods( vector<string> ); 100 void setStatusArea( string );101 void setProgressBar( int );102 103 63 void 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 64 bool ReadInstallInfoCfg(fstream *, Install_info_cfg *); 208 65 209 66 /* End of File */ 210 67 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 227 69 228 70 #endif 229 230 // maximum mumber of lines the output console should have231 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 app248 249 AllocConsole();250 251 // set the screen buffer to be big enough to let us scroll text252 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 console264 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 console276 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 console288 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 clog301 302 // point to console as well303 304 ios::sync_with_stdio();305 306 }307 308 309 310 //End of File311 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 1 9 #ifndef NTDDI_VERSION 2 10 #define NTDDI_VERSION NTDDI_WIN7 3 11 #endif 4 12 #ifdef WIN32 5 13 #include <windows.h> 6 14 #include <shobjidl.h> 7 15 HWND Handle; 8 9 16 ITaskbarList *pTaskbarList; 10 17 ITaskbarList3 *pTaskbarList3; 11 18 #endif 12 19 13 /*14 AE/Mod Installer15 by Gumby and Iritscen16 */17 18 // To-do: - Load credits from text resource file19 // - Institute lots of checks into file-handling20 // - Clear mod info fields when mod is de-selected21 22 #define DEBUG23 #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 declarations35 #include "boost/lexical_cast.hpp" //int -> string36 #include "boost/algorithm/string.hpp"37 #include "installer.h"38 39 #ifdef WIN3240 #include <windows.h>41 #else // assume we're on Mac42 #include <stdlib.h>43 #include <dirent.h>44 #endif45 46 47 const bool SPLIT = 1;48 const bool NOT_SPLIT = 0;49 bool splitInstances = SPLIT;50 bool busy = 0;51 #ifdef WIN3252 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 OS57 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 #endif63 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 GDF162 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 array203 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 overriding299 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 try370 {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 WIN32410 /* 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 never412 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 characters417 system(prefsCommand);418 419 #endif420 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 try449 {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 now459 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 much482 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") or488 static string ARROW = "->"; //did something like "ModString".compare(*iter), and it would have been489 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 stuff506 iter = tokens.begin(); //what word we are on, starts at first word507 /*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 name512 for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) { //interates through the words, ends if it reaches the end of the line or a "//" comment513 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 "//" comment555 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 name563 for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) { //interates through the words, ends if it reaches the end of the line or a "//" comment564 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 name572 for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) { //interates through the words, ends if it reaches the end of the line or a "//" comment573 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 try649 {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 dats663 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 try722 {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 dats734 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 packages779 if (globalPackages[j].modStringName == installedMods[i]) { //for a mod that has BSL in it780 /*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-BSL784 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 folders855 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 addon875 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"972 20 #include <boost/thread/mutex.hpp> 973 974 /////////////////////////////////////////////////////////////////////////////975 // Name: main_window.cpp976 // Purpose:977 // Author:978 // Modified by:979 // Created: 07/05/2009 20:38:25980 // RCS-ID:981 // Copyright:982 // Licence:983 /////////////////////////////////////////////////////////////////////////////984 985 21 // For compilers that support precompilation, includes "wx/wx.h". 986 22 #include "wx/wxprec.h" … … 996 32 ////@begin includes 997 33 #include "about.h" 34 #include "main_window.h" 35 #include "installer.h" 998 36 ////@end includes 999 1000 #include "main_window.h"1001 37 1002 38 ////@begin XPM images … … 1008 44 ////@end XPM images 1009 45 1010 //#define wxDebug 1; 1011 //#define wxUSE_UNICODE 1; 46 bool busy = false; 47 vector<string> globalInstalledMods; 48 vector<ModPackage> globalPackages; 49 // Variable declarations 50 #ifdef WIN32 51 bool splitInstances = true; 52 string strImportOption = "-import:nosep"; 53 string strOniSplit = "Onisplit.exe"; 54 #else 55 bool splitInstances = false; 56 string strImportOption = "-import:sep"; 57 string strOniSplit = "mono Onisplit.exe"; 58 #endif 1012 59 1013 60 /* … … 1093 140 } 1094 141 1095 1096 142 /* 1097 143 * MainWindow destructor … … 1103 149 ////@end MainWindow destruction 1104 150 } 1105 1106 151 1107 152 /* … … 1129 174 ReglobalizeButton = NULL; 1130 175 ////@end MainWindow member initialisation 1131 1132 } 1133 176 } 1134 177 1135 178 /* … … 1169 212 itemMenu42->Append(wxID_OPTIONS, _("Show Advanced Options..."), wxEmptyString, wxITEM_CHECK); 1170 213 menuBar->Append(itemMenu42, _("Options")); 1171 wxMenu* itemMenu44 = new wxMenu;1172 214 #ifdef WIN32 1173 215 itemMenu44->Append(wxID_ABOUT, _("About"), wxEmptyString, wxITEM_NORMAL); … … 1242 284 StatusArea->SetName(_T("StatusArea")); 1243 285 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); 1245 288 itemBoxSizer2->Add(StatusArea, 0, wxGROW|wxALL, 0); 1246 289 … … 1312 355 ::CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_ITaskbarList, (void **)&pTaskbarList); 1313 356 #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 WIN321327 strImportOption = "-import:sep";1328 splitInstances = NOT_SPLIT;1329 #else1330 strImportOption = "-import:nosep";1331 splitInstances = SPLIT;1332 #endif1333 1334 #ifndef WIN321335 strImportOption = "-import:sep";1336 splitInstances = NOT_SPLIT;1337 #else1338 strImportOption = "-import:nosep";1339 splitInstances = SPLIT;1340 #endif1341 357 1342 358 globalPackages = getPackages(); … … 1352 368 OptionsPanel->Hide(); 1353 369 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); 1360 371 else CompleteRadio->SetValue(true); 1361 372 if(strImportOption == "-import:nosep") NoSepRadio->SetValue(true); 1362 373 else SepRadio->SetValue(true); 1363 1364 374 1365 375 #ifdef WIN32 … … 1368 378 ShowWindow( hWnd, SW_HIDE ); 1369 379 #endif 1370 1371 //MainWindow::SetSize(MainWindow::GetRect().GetWidth(), MainWindow::GetRect().GetHeight()-OptionsPanel->GetRect().GetHeight() ); 1372 } 1373 380 } 1374 381 1375 382 /* … … 1382 389 case wxCHK_UNCHECKED: 1383 390 for(unsigned int i = 0; i < globalPackages.size(); i++) Mods_CheckboxList->Check(i, false); 1384 //SelectAll->Set3StateValue(wxCHK_CHECKED);1385 391 break; 1386 392 case wxCHK_CHECKED: 1387 393 for(unsigned int i = 0; i < globalPackages.size(); i++) Mods_CheckboxList->Check(i, true); 1388 //SelectAll->Set3StateValue(wxCHK_UNCHECKED);1389 394 break; 1390 395 case wxCHK_UNDETERMINED: 1391 396 for(unsigned int i = 0; i < globalPackages.size(); i++) Mods_CheckboxList->Check(i, false); 1392 //SelectAll->Set3StateValue(wxCHK_CHECKED);1393 397 break; 1394 1395 } 1396 1397 } 1398 398 } 399 } 1399 400 1400 401 /* … … 1404 405 void MainWindow::ModList_OnCreate( wxWindowCreateEvent& event ) 1405 406 { 1406 1407 407 1408 408 } … … 1457 457 wxIcon MainWindow::GetIconResource( const wxString& name ) 1458 458 { 1459 1460 459 // Icon retrieval 1461 460 ////@begin MainWindow icon retrieval … … 1470 469 } 1471 470 1472 1473 471 /* 1474 472 * wxEVT_COMMAND_LISTBOX_SELECTED event handler for Mods_CheckboxList1 … … 1477 475 void MainWindow::OnModsCheckboxList1Selected( wxCommandEvent& event ) 1478 476 { 1479 //event.GetSelection1480 477 titleText->SetValue(globalPackages[event.GetSelection()].name.c_str()); 1481 478 creatorText->SetValue(globalPackages[event.GetSelection()].creator.c_str()); 1482 479 descriptionText->SetValue(globalPackages[event.GetSelection()].readme.c_str()); 1483 1484 //creatorText->Refresh(); 1485 } 1486 480 } 1487 481 1488 482 /* … … 1519 513 this->SetSize(this->GetRect().GetWidth(), this->GetRect().GetHeight()-OptionsPanel->GetRect().GetHeight());} 1520 514 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.", 1523 516 "AE Installer Alert", wxOK | wxICON_EXCLAMATION , wxDefaultPosition); 1524 517 YesNoDialog->ShowModal(); … … 1529 522 } 1530 523 1531 1532 524 /* 1533 525 * wxEVT_COMMAND_MENU_SELECTED event handler for wxID_EXIT … … 1539 531 } 1540 532 1541 1542 533 /* 1543 534 * wxEVT_COMMAND_BUTTON_CLICKED event handler for Install_Button 1544 535 */ 1545 1546 536 1547 537 struct recompile … … 1555 545 1556 546 } 1557 1558 547 vector<string> thePackages; 1559 548 }; … … 1565 554 } 1566 555 1567 1568 1569 556 void MainWindow::OnInstallButtonClick( wxCommandEvent& event ) 1570 557 { 1571 1572 558 vector<string> localPackages; 1573 559 localPackages.push_back("00000Globalize"); … … 1576 562 sort(localPackages.begin(), localPackages.end()); 1577 563 localPackages[0] = "Globalize"; 1578 //MainWindow::MainWindow().Hide();1579 // boost::thread thrd2(recompileAll(localPackages) );1580 //MainWindow::MainWindow().Show();1581 564 this->InstallButton->Disable(); 1582 565 this->ReglobalizeButton->Disable(); … … 1587 570 recompileAll(localPackages); 1588 571 #endif 1589 1590 572 this->InstallButton->Enable(); 1591 573 this->ReglobalizeButton->Enable(); 1592 574 } 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 577 void setProgressBar( int i ) 578 { 1611 579 #ifdef WIN32 1612 1613 1614 1615 580 if (SUCCEEDED(pTaskbarList->QueryInterface(IID_ITaskbarList3, (void **)&pTaskbarList3))) 1616 581 { 1617 1618 582 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 } 1626 588 #endif 1627 589 TheProgressBar->SetValue(i); 1628 1629 } 1630 590 } 1631 591 1632 592 /* … … 1642 602 } 1643 603 1644 1645 604 /* 1646 605 * wxEVT_COMMAND_MENU_SELECTED event handler for wxID_ABOUT … … 1651 610 ////@begin wxEVT_COMMAND_MENU_SELECTED event handler for wxID_ABOUT in MainWindow. 1652 611 // Before editing this code, remove the block markers. 612 // TODO: Make About window work again! 1653 613 About* window = new About(this); 1654 int returnValue = window->ShowModal();1655 614 window->Destroy(); 1656 615 ////@end wxEVT_COMMAND_MENU_SELECTED event handler for wxID_ABOUT in MainWindow. 1657 616 } 1658 617 1659 1660 618 /* 1661 619 * wxEVT_COMMAND_RADIOBUTTON_SELECTED event handler for NoSep_RadioButton … … 1667 625 } 1668 626 1669 1670 627 /* 1671 628 * wxEVT_COMMAND_RADIOBUTTON_SELECTED event handler for Sep_RadioButton … … 1677 634 } 1678 635 1679 1680 636 /* 1681 637 * wxEVT_COMMAND_RADIOBUTTON_SELECTED event handler for Separated_RadioButton … … 1688 644 void MainWindow::OnCompleteRadioButtonSelected( wxCommandEvent& event ) 1689 645 { 1690 splitInstances = NOT_SPLIT; 1691 1692 } 1693 646 splitInstances = false; 647 } 1694 648 1695 649 /* … … 1702 656 } 1703 657 1704 1705 658 /* 1706 659 * wxEVT_COMMAND_MENU_SELECTED event handler for wxID_LOAD 1707 660 */ 1708 661 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 663 void MainWindow::refreshMods (vector<string> s) 664 { 1714 665 Mods_CheckboxList->Clear(); 1715 //globalInstalledMods = getPackages();1716 666 for (unsigned int i = 0; i < globalPackages.size(); i++) { 1717 667 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); 1721 670 } 1722 671 } … … 1738 687 refreshMods(getInstallString( string(openFileDialog->GetPath()) )); 1739 688 } 1740 1741 1742 } 1743 689 } 1744 690 1745 691 /* … … 1761 707 if ( openFileDialog->ShowModal() == wxID_OK ) 1762 708 { 1763 1764 1765 //Mods_CheckboxList->1766 1767 1768 1769 //1770 1771 709 if ( exists( openFileDialog->GetPath().c_str() ) ) 1772 710 { … … 1789 727 file.close(); 1790 728 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 } 1800 731 1801 732 /* … … 1805 736 void MainWindow::OnReGlobalizeButtonClick( wxCommandEvent& event ) 1806 737 { 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 { 1814 748 this->InstallButton->Disable(); 1815 749 this->ReglobalizeButton->Disable(); 1816 1817 750 #ifdef WIN32 1818 1819 751 boost::thread thrd2(globalizeData); 1820 752 //globalizeData(); … … 1825 757 globalizeData(); 1826 758 #endif 1827 1828 759 this->InstallButton->Enable(); 1829 760 this->ReglobalizeButton->Enable(); 1830 761 } 1831 1832 762 } 1833 763 /* 1834 764 * wxEVT_COMMAND_RADIOBUTTON_SELECTED event handler for Separated_RadioButton 1835 765 */ 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 1845 766 1846 767 /* … … 1850 771 void MainWindow::OnSeperatedRadioButtonSelected( wxCommandEvent& event ) 1851 772 { 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 \***************************************************************************/ 1 8 2 3 /////////////////////////////////////////////////////////////////////////////4 // Name: main_window.h5 // Purpose:6 // Author:7 // Modified by:8 // Created: 07/05/2009 20:38:259 // RCS-ID:10 // Copyright:11 // Licence:12 /////////////////////////////////////////////////////////////////////////////13 9 14 10 #ifndef _MAINWINDOW_H_ 15 11 #define _MAINWINDOW_H_ 16 12 17 18 13 /*! 19 14 * Includes 20 15 */ 21 16 #pragma mark INCLUDES 22 17 ////@begin includes 18 #include "wx/bmpbuttn.h" 19 #include "wx/checkbox.h" 20 #include "wx/checklst.h" 23 21 #include "wx/frame.h" 22 #include "wx/gauge.h" 23 #include "wx/generic/panelg.h" 24 #include "wx/radiobut.h" 24 25 #include "wx/splitter.h" 25 26 #include "wx/statline.h" 26 27 #include "wx/statusbr.h" 28 #include "wx/textctrl.h" 29 #include <vector> 30 using namespace std; 27 31 ////@end includes 28 32 … … 39 43 * Control identifiers 40 44 */ 41 45 #pragma mark DEFINES 42 46 ////@begin control identifiers 43 47 #define ID_MAINWINDOW 10000 … … 69 73 ////@end control identifiers 70 74 71 72 75 /*! 73 76 * MainWindow class declaration 74 77 */ 75 78 76 using namespace std; 77 78 #include <vector> 79 79 #pragma mark CLASS DECLARATIONS 80 80 class MainWindow: public wxFrame 81 81 { … … 86 86 /// Constructors 87 87 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 ); 89 90 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 ); 91 93 92 94 /// Destructor … … 190 192 #endif 191 193 // _MAINWINDOW_H_ 192 void doglobalizeData(void);
Note:
See TracChangeset
for help on using the changeset viewer.