source: AE/Installer/trunk/source/subs.cpp @ 307

Last change on this file since 307 was 307, checked in by gumby, 11 years ago
File size: 11.9 KB
Line 
1#define DEBUG
2/*
3AE\Mod Installer.
4
5Needs getPackages() now!
6*/
7//#include <dir.h>
8#include <string>
9
10#include <direct.h>
11
12#include "boost/filesystem/operations.hpp"
13#include "boost/filesystem/path.hpp"
14#include "boost/filesystem.hpp"   // includes all needed Boost.Filesystem declarations
15#include <iostream>               // for std::cout
16         // for ease of tutorial presentation;
17                                  //  a namespace alias is preferred practice in real code
18
19#include <cctype>
20#include <iostream>
21#include "methods.h"
22#include <vector>
23#include <fstream>
24
25
26
27#include <errno.h>
28#ifdef WIN32
29//      #include "Include\dirent.h"
30        #include <windows.h>
31        static const string Onisplit = "Onisplit.exe";
32        string import = "-import:nosep";
33#else
34#include <stdlib.h>
35#include <dirent.h> //??? is this included for Macs?
36        string import = "-import:sep";
37        static const string Onisplit = "./mono Onisplit.exe";
38#endif
39
40
41
42using namespace boost::filesystem; 
43using namespace std;
44//bool FALSE = 0;
45//bool TRUE = 0;
46
47const bool SPLIT = 1;
48const bool NOT_SPLIT = 0;
49
50bool splitInstances = SPLIT;
51
52int main(void)
53{
54       
55        //      SetConsoleTitle("AE Installer"); windows junk, convert to SDL
56        //      system("color 0A");
57
58        cout << "\nWelcome to the AE installer!\n";
59
60        cout << "\nWhat would you like to do?\n";
61
62        return mainMenu();
63}
64
65vector<ModPackage> getPackages(void) {
66        vector<ModPackage> packages;
67        packages.reserve(65536); //comeon, we shouldn't need this much space...right?!
68        fstream file;
69
70
71        string filename = "\0";
72        string MODINFO_CFG = "Mod_Info.cfg";
73
74        try
75        {
76
77
78        directory_iterator end_iter;
79        for ( directory_iterator dir_itr( "./packages" );
80                dir_itr != end_iter;
81                ++dir_itr )
82        {
83
84               
85                file.open( (dir_itr->path().string() + "/" + MODINFO_CFG ).c_str());
86
87                //cout << filename << "\n";
88
89                if(!file.fail() )
90                {
91                        cout << dir_itr->path().string() + MODINFO_CFG ;
92                        //would prefer to push a pointer to a package, but this will do for now
93                        packages.push_back( fileToModPackage(file) );
94
95                }       
96                file.close();
97                file.clear();
98
99
100
101        }
102
103
104        }
105        catch ( const std::exception & ex )
106        {
107                cout << "Warning, something odd happened!\n";
108        }
109
110        return packages;
111}
112
113ModPackage fileToModPackage(fstream &file) {
114        /*
115        This converts a file to a ModPackage struct.
116
117        A few notes...
118        "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.
119        I refer to (*iter) at the beginning of each if statement block. I could probably store it as a variable, but I'm pretty sure that dereferencing a pointer\iterator isn't much slower than reading a variable.
120        */
121        ModPackage package;
122        string line;
123        static string NameOfMod = "NameOfMod";  //used for comparing to the current token...
124        //I could have done it in reverse (*iter).compare("ModString") or 
125        static string ARROW = "->";                             //did something like "ModString".compare(*iter), and it would have been
126        static string ModString = "ModString";  //functionably the same.
127        static string HasOnis = "HasOnis";
128        static string HasDeltas = "HasDeltas";
129        static string HasBSL = "HasBSL";
130        static string HasDats = "HasDats";
131        static string IsEngine = "IsEngine";
132        static string Readme = "Readme";
133        static string GlobalNeeded = "GlobalNeeded";
134        static string Category = "Category";
135        static string Creator = "Creator";
136        while (! file.eof() )
137        {
138                getline (file,line);
139                vector<string> tokens; 
140                vector<string>::iterator iter;
141                Tokenize(line, tokens);                                 //string to vector of "words"
142                if (tokens.capacity() >= 2) {                   //make sure they are using enough stuff
143                        iter = tokens.begin();                          //what word we are on, starts at first word
144                        /*
145                        if (!AEInstallVersion.compare(*iter))
146                        If mod is too old, skip this mod.
147                        */
148                        /*else*/if (!NameOfMod.compare(*iter))  {       //if it contains the name
149                                for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
150                                        if (ARROW.compare(*iter) && NameOfMod.compare(*iter)) {                 //ignores "->" and "NameOfMod"
151                                                //cout << *iter;
152                                                //cout << " ";
153                                                package.name += *iter + " ";
154                                        }
155                                }
156
157                        }
158                        else if (!ModString.compare(*iter)) {
159                                iter++; iter++;
160                                package.modStringName = *iter;
161                                iter++;
162                                package.modStringVersion = atoi((*iter).c_str());
163                        }
164                        else if (!HasOnis.compare(*iter)) {
165                                iter++; iter++; 
166                                if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasOnis = 1; //Gotta love c++'s lack of a standard case-insensitive string comparer...I know my implementation here sucks. I need to change it to check each character one by one. At the moment, using "YFR" would probably set it off. :<
167                        }
168                        else if (!HasBSL.compare(*iter)) {
169                                iter++; iter++; 
170                                if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasBSL = 1;
171                        }
172                        else if (!HasDeltas.compare(*iter)) {
173                                iter++; iter++; 
174                                if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasDeltas = 1;
175                        }
176                        else if (!HasDats.compare(*iter)) {
177                                iter++; iter++; 
178                                if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasDats = 1;
179                        }
180                        else if (!IsEngine.compare(*iter)) {
181                                iter++; iter++; 
182                                if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.isEngine = 1;
183                        }
184                        else if (!GlobalNeeded.compare(*iter)) {
185                                iter++; iter++; 
186                                if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.globalNeeded = 1;
187                                else if (toupper((*iter)[0]) + toupper((*iter)[1]) == 'N' + 'O') package.globalNeeded = 1; //Really the only place where checking for "No" is important atm.
188                        }
189                        else if (!Category.compare(*iter))  {   
190                                for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
191                                        if (ARROW.compare(*iter) && Category.compare(*iter)) {                  //ignores "->" and "Category"
192                                                //cout << *iter;
193                                                //cout << " ";
194                                                package.category += *iter + " ";
195                                        }
196                                }
197                        }
198                        else if (!Creator.compare(*iter))  {    //if it contains the name
199                                for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
200                                        if (ARROW.compare(*iter) && Creator.compare(*iter)) {                   //ignores "->" and "Category"
201                                                //cout << *iter;
202                                                //cout << " ";
203                                                package.creator += *iter + " ";
204                                        }
205                                }
206                        }
207                        else if (!Readme.compare(*iter))  {     //if it contains the name
208                                for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
209                                        if (ARROW.compare(*iter) && Readme.compare(*iter)) {                    //ignores "->" and "Category"
210                                                //cout << *iter;
211                                                //cout << " ";
212                                                package.readme += *iter + " ";
213                                        }
214                                }
215                        }
216                }
217
218        }
219        package.doOutput();
220        return package;
221}
222
223int mainMenu(void) {
224        int choice = '0';
225        bool ok = FALSE;
226        cout << "1. Install new packages\n";
227        cout << "2. Uninstall packages\n";
228        cout << "3. See what is installed\n";
229        cout << "4. About AE\n";
230        cout << "5. Quit\n\n";
231
232        do {
233                ok = TRUE;
234                choice = cin.get();
235                cin.ignore(128, '\n');
236                switch(choice) {
237                        case '1':
238                                installPackages();
239                                break;
240                        case '2':
241                                uninstallPackages();
242                                break;
243                        case '3':
244                                //listInstalledPackages();
245                                break;
246                        case '5':
247                                return 0;
248                        default:
249                                ok = FALSE;
250                }
251        } while(ok == FALSE);
252        return 0;
253}
254
255
256void installPackages() {
257        ModPackage package;
258        vector<string> installed_packages;
259        vector<ModPackage> packages; 
260        vector<ModPackage>::iterator iter;
261        iter = packages.begin();
262        vector<string> installString;
263        packages = getPackages();
264        vector<string> installedMods = getInstallString();
265
266        if (packages.empty()) {
267                cout << "Error: You have no packages!\n";
268                return;
269        }
270        cout << "Detecting installed packages...\n";
271       
272        int index = 1;
273        char  choice = '0';
274        for (vector<ModPackage>::iterator package_iter = packages.begin(); package_iter != packages.end(); ++package_iter) {
275                if (!binary_search(installedMods.begin(), installedMods.end(), package_iter->modStringName)) { //package_iter->isInstalled :< I forgot about this...
276                        //cout << index << " ";
277                        system("cls");
278                        cout << (*package_iter).name <<"\n";
279                        for( int character = 1; character <= (*package_iter).name.length() - 1; character++) cout << char(196); //does extended ASCII work in UNIX?
280                        cout << "\n"
281                                << (*package_iter).readme << "\n"
282                                << "\n"
283                                << "Please enter a number choice\n"
284                                << " 1. Install\n"
285                                << " 2. Don't Install\n"
286                                << "";
287                        index++;
288                        choice = 0;
289                       
290                        do {
291                        choice = cin.get();
292                        cin.ignore(1280, '\n');
293                        } while(choice == 0);
294                        if (choice == '1') {
295                                cout << "\nInstalling...\n\n";
296                                if ( package_iter->hasOnis || ( package_iter->hasDeltas /*(*package_iter).isUnpacked */ )) {
297                                        installedMods.push_back(package_iter->modStringName);                           
298                                               
299                                                system("PAUSE");
300                                               
301
302                                }
303                        }
304
305                }
306        }
307        if (index == 1) {
308                cout << "Error: All packages are already installed\n";
309                return;
310        }
311        sort(installedMods.begin(), installedMods.end());
312         
313         //system(Onisplit.c_str());
314        RecompileAll(installedMods);
315         system("PAUSE");
316}
317void uninstallPackages() {
318        ;
319}
320
321void getInstalledPackages() {
322        ;
323}
324
325void RecompileAll(vector<string> installedMods) {
326        cout << "Recompiling Data...\n";
327        path vanilla_dir = "./packages/VanillaDats/";
328        string importCommand = "";
329        if(splitInstances == SPLIT){
330                recursive_directory_iterator end_iter;
331                                try {
332                for ( recursive_directory_iterator dir_itr( vanilla_dir );
333                        dir_itr != end_iter;
334                        ++dir_itr )
335                {
336                        try
337                        {
338                                if ( is_directory( dir_itr->status() ) &&  dir_itr.level() == 1)
339                                {
340                                        importCommand =  Onisplit + " " + import + " " + dir_itr->path().parent_path().string() + '/' + dir_itr->path().filename();
341                                        for (int i = 0; i < installedMods.size(); ++i) {
342                                                if (exists("packages/" + installedMods[i] + "/oni/" + dir_itr->path().parent_path().filename() + '/' + dir_itr->path().filename()  ))
343                                                        importCommand += " packages/" + installedMods[i] + "/oni/" + dir_itr->path().parent_path().filename() + '/' + dir_itr->path().filename();
344                                               
345                                                //else cout << " packages/VanillaDats/" + installedMods[i] + "/oni/";
346                                                }
347                                        importCommand += " ../GameDataFolder/" + dir_itr->path().filename() + ".dat";
348                                                system(importCommand.c_str());
349//cout << importCommand << "\n";
350                                }
351                        }
352                        catch ( const std::exception & ex )
353                        {
354                                cout << "Warning, exception " << ex.what() << "!";
355                        }
356                }
357                                }
358                                catch( const std::exception & ex ) {
359                                        cout << "Warning, exception " << ex.what() << "!\n"
360                                                << "You probably need to reGlobalize.";
361                                        create_directory( "./packages/VanillaDats" );
362                                }
363
364        }
365        else if(splitInstances == NOT_SPLIT){
366                directory_iterator end_iter;
367                for ( directory_iterator dir_itr( vanilla_dir );
368                        dir_itr != end_iter;
369                        ++dir_itr )
370                {
371                        try
372                        {
373                                if ( is_directory( dir_itr->status() ) )
374                                {
375                                        system((Onisplit + " " + import + " " + vanilla_dir.string() + dir_itr->path().filename() + " " + "../GameDataFolder/" + dir_itr->path().filename() + ".dat").c_str());
376                                }
377                        }
378                        catch ( const std::exception & ex )
379                        {
380                                cout << "Warning, something odd happened!\n";
381                        }
382                }
383
384
385
386        }
387}
388
389vector<string> getInstallString() {
390        system("PAUSE");
391        vector<string> returnval;
392                string file_name = "../GameDataFolder/ImportList.cfg";
393                string line;
394                fstream file;
395                if( exists(file_name) ) {
396                        file.open(file_name.c_str());
397                        getline (file,line);
398                        Tokenize(line, returnval);             
399                        file.close();
400                        file.clear();
401                        sort(returnval.begin(), returnval.end());
402                                       
403                }
404                else cout << "fail";
405               
406        return returnval;
407}
Note: See TracBrowser for help on using the repository browser.