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

Last change on this file since 306 was 306, checked in by gumby, 11 years ago
File size: 12.2 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#ifdef DEBUG
70#ifdef WIN32
71        string path = ".\\packages"; //only for my build. :P
72         _chdir(path.c_str());
73
74         _chdir("..");
75         cout << path;
76#else
77        string path = "K:\\Oni\\edition\\install\\packages"; //change this, 'scen.
78#endif
79#else
80        string path = ".";
81#endif
82
83        string filename = "\0";
84        string MODINFO_CFG = "Mod_Info.cfg";
85
86        try
87        {
88
89
90        directory_iterator end_iter;
91        for ( directory_iterator dir_itr( "./packages" );
92                dir_itr != end_iter;
93                ++dir_itr )
94        {
95
96               
97                file.open( (dir_itr->path().string() + "/" + MODINFO_CFG ).c_str());
98
99                //cout << filename << "\n";
100
101                if(!file.fail() )
102                {
103                        cout << dir_itr->path().string() + MODINFO_CFG ;
104                        //would prefer to push a pointer to a package, but this will do for now
105                        packages.push_back( fileToModPackage(file) );
106
107                }       
108                file.close();
109                file.clear();
110
111
112
113        }
114
115
116        }
117        catch ( const std::exception & ex )
118        {
119                cout << "Warning, something odd happened!\n";
120        }
121
122        return packages;
123}
124
125ModPackage fileToModPackage(fstream &file) {
126        /*
127        This converts a file to a ModPackage struct.
128
129        A few notes...
130        "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.
131        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.
132        */
133        ModPackage package;
134        string line;
135        static string NameOfMod = "NameOfMod";  //used for comparing to the current token...
136        //I could have done it in reverse (*iter).compare("ModString") or 
137        static string ARROW = "->";                             //did something like "ModString".compare(*iter), and it would have been
138        static string ModString = "ModString";  //functionably the same.
139        static string HasOnis = "HasOnis";
140        static string HasDeltas = "HasDeltas";
141        static string HasBSL = "HasBSL";
142        static string HasDats = "HasDats";
143        static string IsEngine = "IsEngine";
144        static string Readme = "Readme";
145        static string GlobalNeeded = "GlobalNeeded";
146        static string Category = "Category";
147        static string Creator = "Creator";
148        while (! file.eof() )
149        {
150                getline (file,line);
151                vector<string> tokens; 
152                vector<string>::iterator iter;
153                Tokenize(line, tokens);                                 //string to vector of "words"
154                if (tokens.capacity() >= 2) {                   //make sure they are using enough stuff
155                        iter = tokens.begin();                          //what word we are on, starts at first word
156                        /*
157                        if (!AEInstallVersion.compare(*iter))
158                        If mod is too old, skip this mod.
159                        */
160                        /*else*/if (!NameOfMod.compare(*iter))  {       //if it contains the name
161                                for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
162                                        if (ARROW.compare(*iter) && NameOfMod.compare(*iter)) {                 //ignores "->" and "NameOfMod"
163                                                //cout << *iter;
164                                                //cout << " ";
165                                                package.name += *iter + " ";
166                                        }
167                                }
168
169                        }
170                        else if (!ModString.compare(*iter)) {
171                                iter++; iter++;
172                                package.modStringName = *iter;
173                                iter++;
174                                package.modStringVersion = atoi((*iter).c_str());
175                        }
176                        else if (!HasOnis.compare(*iter)) {
177                                iter++; iter++; 
178                                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. :<
179                        }
180                        else if (!HasBSL.compare(*iter)) {
181                                iter++; iter++; 
182                                if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasBSL = 1;
183                        }
184                        else if (!HasDeltas.compare(*iter)) {
185                                iter++; iter++; 
186                                if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasDeltas = 1;
187                        }
188                        else if (!HasDats.compare(*iter)) {
189                                iter++; iter++; 
190                                if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasDats = 1;
191                        }
192                        else if (!IsEngine.compare(*iter)) {
193                                iter++; iter++; 
194                                if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.isEngine = 1;
195                        }
196                        else if (!GlobalNeeded.compare(*iter)) {
197                                iter++; iter++; 
198                                if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.globalNeeded = 1;
199                                else if (toupper((*iter)[0]) + toupper((*iter)[1]) == 'N' + 'O') package.globalNeeded = 1; //Really the only place where checking for "No" is important atm.
200                        }
201                        else if (!Category.compare(*iter))  {   
202                                for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
203                                        if (ARROW.compare(*iter) && Category.compare(*iter)) {                  //ignores "->" and "Category"
204                                                //cout << *iter;
205                                                //cout << " ";
206                                                package.category += *iter + " ";
207                                        }
208                                }
209                        }
210                        else if (!Creator.compare(*iter))  {    //if it contains the name
211                                for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
212                                        if (ARROW.compare(*iter) && Creator.compare(*iter)) {                   //ignores "->" and "Category"
213                                                //cout << *iter;
214                                                //cout << " ";
215                                                package.creator += *iter + " ";
216                                        }
217                                }
218                        }
219                        else if (!Readme.compare(*iter))  {     //if it contains the name
220                                for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) {     //interates through the words, ends if it reaches the end of the line or a "//" comment
221                                        if (ARROW.compare(*iter) && Readme.compare(*iter)) {                    //ignores "->" and "Category"
222                                                //cout << *iter;
223                                                //cout << " ";
224                                                package.readme += *iter + " ";
225                                        }
226                                }
227                        }
228                }
229
230        }
231        package.doOutput();
232        return package;
233}
234
235int mainMenu(void) {
236        int choice = '0';
237        bool ok = FALSE;
238        cout << "1. Install new packages\n";
239        cout << "2. Uninstall packages\n";
240        cout << "3. See what is installed\n";
241        cout << "4. About AE\n";
242        cout << "5. Quit\n\n";
243
244        do {
245                ok = TRUE;
246                choice = cin.get();
247                cin.ignore(128, '\n');
248                switch(choice) {
249                        case '1':
250                                installPackages();
251                                break;
252                        case '2':
253                                uninstallPackages();
254                                break;
255                        case '3':
256                                //listInstalledPackages();
257                                break;
258                        case '5':
259                                return 0;
260                        default:
261                                ok = FALSE;
262                }
263        } while(ok == FALSE);
264        return 0;
265}
266
267
268void installPackages() {
269        ModPackage package;
270        vector<string> installed_packages;
271        vector<ModPackage> packages; 
272        vector<ModPackage>::iterator iter;
273        iter = packages.begin();
274        vector<string> installString;
275        packages = getPackages();
276        vector<string> installedMods = getInstallString();
277
278        if (packages.empty()) {
279                cout << "Error: You have no packages!\n";
280                return;
281        }
282        cout << "Detecting installed packages...\n";
283       
284        int index = 1;
285        char  choice = '0';
286        for (vector<ModPackage>::iterator package_iter = packages.begin(); package_iter != packages.end(); ++package_iter) {
287                if (!binary_search(installedMods.begin(), installedMods.end(), package_iter->modStringName)) { //package_iter->isInstalled :< I forgot about this...
288                        //cout << index << " ";
289                        system("cls");
290                        cout << (*package_iter).name <<"\n";
291                        for( int character = 1; character <= (*package_iter).name.length() - 1; character++) cout << char(196); //does extended ASCII work in UNIX?
292                        cout << "\n"
293                                << (*package_iter).readme << "\n"
294                                << "\n"
295                                << "Please enter a number choice\n"
296                                << " 1. Install\n"
297                                << " 2. Don't Install\n"
298                                << "";
299                        index++;
300                        choice = 0;
301                       
302                        do {
303                        choice = cin.get();
304                        cin.ignore(1280, '\n');
305                        } while(choice == 0);
306                        if (choice == '1') {
307                                cout << "\nInstalling...\n\n";
308                                if ( package_iter->hasOnis || ( package_iter->hasDeltas /*(*package_iter).isUnpacked */ )) {
309                                        installedMods.push_back(package_iter->modStringName);                           
310                                               
311                                                system("PAUSE");
312                                               
313
314                                }
315                        }
316
317                }
318        }
319        if (index == 1) {
320                cout << "Error: All packages are already installed\n";
321                return;
322        }
323        sort(installedMods.begin(), installedMods.end());
324         
325         //system(Onisplit.c_str());
326        RecompileAll(installedMods);
327         system("PAUSE");
328}
329void uninstallPackages() {
330        ;
331}
332
333void getInstalledPackages() {
334        ;
335}
336
337void RecompileAll(vector<string> installedMods) {
338        cout << "Recompiling Data...\n";
339        path vanilla_dir = "./packages/VanillaDats/";
340        string importCommand = "";
341        if(splitInstances == SPLIT){
342                recursive_directory_iterator end_iter;
343                                try {
344                for ( recursive_directory_iterator dir_itr( vanilla_dir );
345                        dir_itr != end_iter;
346                        ++dir_itr )
347                {
348                        try
349                        {
350                                if ( is_directory( dir_itr->status() ) &&  dir_itr.level() == 1)
351                                {
352                                        importCommand =  Onisplit + " " + import + " " + dir_itr->path().parent_path().string() + '/' + dir_itr->path().filename();
353                                        for (int i = 0; i < installedMods.size(); ++i) {
354                                                if (exists("packages/" + installedMods[i] + "/oni/" + dir_itr->path().parent_path().filename() + '/' + dir_itr->path().filename()  ))
355                                                        importCommand += " packages/" + installedMods[i] + "/oni/" + dir_itr->path().parent_path().filename() + '/' + dir_itr->path().filename();
356                                               
357                                                //else cout << " packages/VanillaDats/" + installedMods[i] + "/oni/";
358                                                }
359                                        importCommand += " ../GameDataFolder/" + dir_itr->path().filename() + ".dat";
360                                                system(importCommand.c_str());
361//cout << importCommand << "\n";
362                                }
363                        }
364                        catch ( const std::exception & ex )
365                        {
366                                cout << "Warning, exception " << ex.what() << "!";
367                        }
368                }
369                                }
370                                catch( const std::exception & ex ) {
371                                        cout << "Warning, exception " << ex.what() << "!\n"
372                                                << "You probably need to reGlobalize.";
373                                        create_directory( "./packages/VanillaDats" );
374                                }
375
376        }
377        else if(splitInstances == NOT_SPLIT){
378                directory_iterator end_iter;
379                for ( directory_iterator dir_itr( vanilla_dir );
380                        dir_itr != end_iter;
381                        ++dir_itr )
382                {
383                        try
384                        {
385                                if ( is_directory( dir_itr->status() ) )
386                                {
387                                        system((Onisplit + " " + import + " " + vanilla_dir.string() + dir_itr->path().filename() + " " + "../GameDataFolder/" + dir_itr->path().filename() + ".dat").c_str());
388                                }
389                        }
390                        catch ( const std::exception & ex )
391                        {
392                                cout << "Warning, something odd happened!\n";
393                        }
394                }
395
396
397
398        }
399}
400
401vector<string> getInstallString() {
402        system("PAUSE");
403        vector<string> returnval;
404                string file_name = "../GameDataFolder/ImportList.cfg";
405                string line;
406                fstream file;
407                if( exists(file_name) ) {
408                        file.open(file_name.c_str());
409                        getline (file,line);
410                        Tokenize(line, returnval);             
411                        file.close();
412                        file.clear();
413                        sort(returnval.begin(), returnval.end());
414                                       
415                }
416                else cout << "fail";
417               
418        return returnval;
419}
Note: See TracBrowser for help on using the repository browser.