/* AE\Mod Installer. Needs getPackages() now! */ #include //#include #include #include #include "methods.h" #include #include #include #ifdef WIN32 #include "Include\dirent.h" #else #include //??? is this included for Macs? #endif #include #include using namespace std; bool FALSE = 0; bool TRUE = 0; int main(void) { // SetConsoleTitle("AE Installer"); windows junk, convert to SDL // system("color 0A"); cout << "\nWelcome to the AE installer!\n"; cout << "\nWhat would you like to do?\n"; return mainMenu(); } vector getPackages(void) { vector packages; packages.reserve(256); //thats 63 or 64 pointers to packages...i think. :P Reserving this improves performance when we add new pointers fstream file; #ifdef WIN32 string path = "K:\\Oni\\edition\\install\\packages"; //only for my build. :P #else string path = "K:\\Oni\\edition\\install\\packages"; //change this, 'scen. #endif string filename = "\0"; string MODINFO_CFG = "\\Mod_Info.cfg"; DIR *pdir; struct dirent *pent; pdir = opendir( path.c_str() ); //"." refers to the current dir if (!pdir){ printf ("opendir() failure; terminating"); exit(1); } errno=0; while (( pent = readdir(pdir) )){ filename = path + '\\' + pent->d_name + MODINFO_CFG; file.open(filename.c_str()); //cout << filename << "\n"; if(!file.fail() ) { //file.open(filename.c_str(), fstream::out); //do stuff like adding to vector :P //would prefer to push a pointer to a package, but this will do for now packages.push_back( fileToModPackage(file) ); } file.close(); file.clear(); } if (errno){ printf ("readdir() failure; terminating"); exit(1); } closedir(pdir); return packages; } ModPackage fileToModPackage(fstream &file) { /* This converts a file to a ModPackage struct. A few notes... "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. 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. */ ModPackage package; string line; static string NameOfMod = "NameOfMod"; //used for comparing to the current token... static string SLASHSLASH = "//"; //I could have done it in reverse (*iter).compare("ModString") or static string ARROW = "->"; //did something like "ModString".compare(*iter), and it would have been static string ModString = "ModString"; //functionably the same. static string HasOnis = "HasOnis"; static string HasDeltas = "HasDeltas"; static string HasBSL = "HasBSL"; static string HasDats = "HasDats"; static string IsEngine = "IsEngine"; static string Readme = "Readme"; static string GlobalNeeded = "GlobalNeeded"; static string Category = "Category"; static string Creator = "Creator"; while (! file.eof() ) { getline (file,line); vector tokens; vector::iterator iter; Tokenize(line, tokens); //string to vector of "words" if (tokens.capacity() >= 2) { //make sure they are using enough stuff iter = tokens.begin(); //what word we are on, starts at first word /* if (!AEInstallVersion.compare(*iter)) If mod is too old, skip this mod. */ /*else*/if (!NameOfMod.compare(*iter)) { //if it contains the name for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) { //interates through the words, ends if it reaches the end of the line or a "//" comment if (ARROW.compare(*iter) && NameOfMod.compare(*iter)) { //ignores "->" and "NameOfMod" //cout << *iter; //cout << " "; package.name += *iter + " "; } } } else if (!ModString.compare(*iter)) { iter++; iter++; package.modStringName = *iter; iter++; package.modStringVersion = atoi((*iter).c_str()); } else if (!HasOnis.compare(*iter)) { iter++; iter++; 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. :< } else if (!HasBSL.compare(*iter)) { iter++; iter++; if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasBSL = 1; } else if (!HasDeltas.compare(*iter)) { iter++; iter++; if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasDeltas = 1; } else if (!HasDats.compare(*iter)) { iter++; iter++; if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.hasDats = 1; } else if (!IsEngine.compare(*iter)) { iter++; iter++; if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.isEngine = 1; } else if (!GlobalNeeded.compare(*iter)) { iter++; iter++; if (toupper((*iter)[0]) + toupper((*iter)[1]) + toupper((*iter)[2]) == 'Y' + 'E' + 'S') package.globalNeeded = 1; else if (toupper((*iter)[0]) + toupper((*iter)[1]) == 'N' + 'O') package.globalNeeded = 1; //Really the only place where checking for "No" is important atm. } else if (!Category.compare(*iter)) { for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) { //interates through the words, ends if it reaches the end of the line or a "//" comment if (ARROW.compare(*iter) && Category.compare(*iter)) { //ignores "->" and "Category" //cout << *iter; //cout << " "; package.category += *iter + " "; } } } else if (!Creator.compare(*iter)) { //if it contains the name for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) { //interates through the words, ends if it reaches the end of the line or a "//" comment if (ARROW.compare(*iter) && Creator.compare(*iter)) { //ignores "->" and "Category" //cout << *iter; //cout << " "; package.creator += *iter + " "; } } } else if (!Readme.compare(*iter)) { //if it contains the name for ( ; iter !=tokens.end() && SLASHSLASH.compare(*iter); iter++) { //interates through the words, ends if it reaches the end of the line or a "//" comment if (ARROW.compare(*iter) && Readme.compare(*iter)) { //ignores "->" and "Category" //cout << *iter; //cout << " "; package.readme += *iter + " "; } } } } } package.doOutput(); return package; } int mainMenu(void) { int choice = '0'; bool ok = FALSE; cout << "1. Install new packages\n"; cout << "2. Uninstall packages\n"; cout << "3. See what is installed\n"; cout << "4. About AE\n"; cout << "5. Quit\n\n"; do { ok = TRUE; choice = cin.get(); cin.ignore(1); switch(choice) { case '1': installPackages(); break; case '2': uninstallPackages(); break; case '3': //listInstalledPackages(); break; case '5': return 0; default: ok = FALSE; } } while(ok == FALSE); return 0; } void installPackages() { ModPackage package; vector installed_packages; vector packages; // = getPackages() vector::iterator iter; iter = packages.begin(); getPackages(); if (packages.empty()) { cout << "Error: You have no packages!\n"; return; } cout << "Detecting installed packages...\n"; for(int i = 0; i < packages.size();) { package = *iter; if(!package.isInstalled){ packages.erase(iter); } else { i++; iter++; } } if (packages.empty()) { cout << "Error: You have no installed packages!\n"; return; } //listInstalledPackages(packages); } void uninstallPackages() { ; } void getInstalledPackages() { ; }