Subversion Repositories spk

Rev

Rev 50 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

// PluginManager.cpp : main project file.

#include "stdafx.h"
#include "Forms\MainGui.h"
#include "Forms\StartUp.h"
#include "Languages.h"

using namespace PluginManager;
using namespace Microsoft::Win32;
using namespace System::IO;

#include <spk.h>
#undef GetTempPath
#undef GetCurrentDirectory

CPackages       packages;
CLanguages      Language;



[STAThreadAttribute]
int main(array<System::String ^> ^args)
{
        // Enabling Windows XP visual effects before any controls are created
        Application::EnableVisualStyles();
        Application::SetCompatibleTextRenderingDefault(false); 

        System::String ^tempDir = System::IO::Path::GetTempPath();
        System::String ^mydoc = Environment::GetFolderPath(Environment::SpecialFolder::Personal );
        System::String ^progfile = Environment::GetFolderPath(Environment::SpecialFolder::ProgramFiles );

        CyStringList dirList;
        CyStringList remDirList;
        System::String ^gameArgs;
        System::String ^openPackage;

        Language.SetLanguage(44);

        bool Advanced = false, fromLauncher = false, silent = false;
        for ( int i = 0; i < args->Length; i++ )
        {
                CyString arg = CyStringFromSystemString(args[i]);

                // its a switch
                if ( arg.Left(2) == "--" )
                {
                        CyString argSwitch = arg.GetToken(":", 1, 1).ToLower();
                        CyString rest = arg.GetToken(":", 2);
                        if ( rest[0] == '"' && rest[rest.Length() - 1] != '"' )
                        {
                                rest.Erase(0, 1);
                                while ( i < args->Length )
                                {
                                        i++;
                                        CyString argCheck = CyStringFromSystemString(args[i]);
                                        rest += " ";
                                        rest += argCheck;
                                        if ( argCheck.Right(1) == "\"" )
                                                break;
                                }
                        }

                        if ( rest.Right(1) == "\"" )
                                rest.Truncate(rest.Length() - 1);

                        if ( argSwitch == "--dir" && !rest.Empty() )
                        {
                                CyString gameName = packages.GetGameName(rest);
                                if ( !gameName.Empty() )
                                        dirList.PushBack(rest, gameName);
                        }

                        if ( argSwitch == "--advanced" )
                                Advanced = true;
                        else if ( argSwitch == "--fromlauncher" )
                                fromLauncher = true;
                        else if ( argSwitch == "--silent" )
                                silent = true;
                        else if ( argSwitch == "--forceemp" )
                                packages.SetForceEMP(true);
                        else if ( argSwitch == "--gamerun" && !rest.Empty() )
                        {
                                gameArgs = SystemStringFromCyString(rest);
                                break;
                        }
                        else if ( argSwitch == "--noresume" )
                        {
                                RegistryKey ^searchKey = Registry::CurrentUser->CreateSubKey("Software\\Egosoft\\PluginManagerSettings");
                                if ( searchKey )
                                        searchKey->SetValue("DontAutoResume", 1);
                        }
                        else if ( argSwitch == "--resume" )
                        {
                                int zero = 0;
                                RegistryKey ^searchKey = Registry::CurrentUser->CreateSubKey("Software\\Egosoft\\PluginManagerSettings");
                                if ( searchKey )
                                        searchKey->SetValue("DontAutoResume", zero);
                        }
                }
                // otherwise it must be a file to open
                else
                        openPackage = SystemStringFromCyString(arg);
        }

        //TODO: Load languge xml
        //Language.LoadLanguages();

        // get the last language used
        RegistryKey ^searchKeyLang = Registry::CurrentUser->OpenSubKey("Software\\Egosoft\\PluginManagerSettings");
        if ( searchKeyLang )
        {
                int lang = System::Convert::ToInt32(searchKeyLang->GetValue("Language"));
                if ( lang )
                        Language.SetLanguage(lang);
        }


        bool firstInstance = false;
        System::Threading::Mutex ^mut = gcnew System::Threading::Mutex(false, "Local\\XPluginManagerLite", firstInstance);
        if ( !firstInstance )
        {
                if ( openPackage )
                {
                        if ( File::Exists(mydoc + "\\Egosoft\\pluginmanager_load.dat") )
                        {
                                StreamWriter ^sw = File::AppendText(mydoc + "\\Egosoft\\pluginmanager_load.dat");
                                try 
                                {
                                        sw->WriteLine("File: " + openPackage);
                                }
                                finally
                                {
                                        if ( sw )
                                                delete (IDisposable ^)sw;
                                }
                        }
                        else
                        {
                                StreamWriter ^sw = File::CreateText(mydoc + "\\Egosoft\\pluginmanager_load.dat");
                                try 
                                {
                                        sw->WriteLine("File: " + openPackage);
                                }
                                finally
                                {
                                        if ( sw )
                                                delete (IDisposable ^)sw;
                                }
                        }
                }
                else if ( !silent )
                        MessageBox::Show(SystemStringFromCyString(Language.GetText_Startup(LANGSTARTUP_ANOTHERINSTANCE)), SystemStringFromCyString(Language.GetText_Startup(LANGSTARTUP_ANOTHERINSTANCE_TITLE)), MessageBoxButtons::OK, MessageBoxIcon::Stop);
                return 0;
        }

        RegistryKey ^searchKey = Registry::CurrentUser->CreateSubKey("Software\\Egosoft\\PluginManagerSettings");
        if ( searchKey )
        {
                searchKey->SetValue("Run", System::Windows::Forms::Application::ExecutablePath);
                searchKey->SetValue("Version", (float)PMLVERSION);
                searchKey->SetValue("Beta", (int)PMLBETA);
        }


        if ( File::Exists(mydoc + "\\Egosoft\\pluginmanager_load.dat") )
                File::Delete(mydoc + "\\Egosoft\\pluginmanager_load.dat");
        if ( File::Exists(tempDir + "\\AutoUpdater_old.exe") )
                File::Delete(tempDir + "\\AutoUpdater_old.exe");

        packages.Startup(".", CyStringFromSystemString(tempDir), CyStringFromSystemString(mydoc), "");
        packages.SetRenameText(true);

        // Create the main window and run it
        MainGui ^gui = gcnew MainGui(&packages, &dirList, &remDirList, Advanced);
        gui->AddGameArgs(gameArgs);

        // load in the config file
        CFileIO configFile(CyStringFromSystemString(mydoc) + "/Egosoft/pluginmanager.dat");
        bool anyDirs = false;
        if ( configFile.Exists() )
        {
                std::vector<CyString> *readFile = configFile.ReadLines();
                if ( readFile )
                {
                        for ( int i = 0; i < (int)readFile->size(); i++ )
                        {
                                CyString line(readFile->at(i));
                                CyString cmd = line.GetToken(":", 1, 1).lower();
                                CyString rest = line.GetToken(":", 2).RemoveFirstSpace();

                                if ( cmd == "dir" )
                                {
                                        // first check its on the list
                                        if ( !dirList.FindString(rest) )
                                        {
                                                CyString gameName = packages.GetGameName(rest);
                                                if ( !gameName.Empty() )
                                                {
                                                        int lang = packages.GetGameLanguage(rest);
                                                        if ( lang )
                                                                dirList.PushBack(rest, CyString::Number(lang) + "|" + gameName);
                                                        else
                                                                dirList.PushBack(rest, gameName);
                                                        anyDirs = true;
                                                }
                                        }
                                }
                                else if ( cmd == "remdir" )
                                {
                                        // first check its on the list
                                        if ( !remDirList.FindString(rest) )
                                        {
                                                remDirList.PushBack(rest);
                                                anyDirs = true;
                                        }
                                }
                                else if ( cmd == "experimental" )
                                        gui->SetExperimental(true);
                                else if ( cmd == "filterships" )
                                        gui->SetShips(true);
                                else if ( cmd == "filtersigned" )
                                        gui->SetOnlySigned(true);
                                else if ( cmd == "modselectordetails" )
                                        gui->SetModSelectorDetails(true);
                                else if ( cmd == "cheat" )
                                        gui->SetCheat(true);
                                else if ( cmd == "downloadable" )
                                        gui->SetDownloadable(true);
                                else if ( cmd == "noautoupdate" )
                                        gui->SetAutoUpdate(false);
                                else if ( cmd == "managersize" )
                                        gui->SetSize(rest.GetToken(" ", 2, 2).ToInt(), rest.GetToken(" ", 1, 1).ToInt());
                                else if ( cmd == "managerpos" )
                                        gui->Location = System::Drawing::Point(rest.GetToken(" ", 1, 1).ToInt(), rest.GetToken(" ", 2, 2).ToInt());
                                else if ( cmd == "managermax" )
                                        gui->WindowState = FormWindowState::Maximized;
                                else if ( cmd == "tips" )
                                        gui->SetTips(rest.GetToken(" ", 1, 1).ToInt(), rest.GetToken(" ", 2, 2).ToInt());
                                else if ( cmd == "ignorejoy" )
                                        gui->SetIgnoreJoy(rest.ToInt());
                                else if ( cmd == "savegamemanager" )
                                        gui->SetSaveGameManager(rest.ToInt());
                                else if ( cmd == "restoremodified" ) {
                                        CPackages p;
                                        p.Startup(".", CyStringFromSystemString(tempDir), CyStringFromSystemString(mydoc), "");
                                        if ( p.Read(rest) ) {
                                                p.SetVanilla(false);
                                                p.PrepareEnableFromVanilla();
                                                p.EnablePreparedPackages(0, 0, 0);
                                                p.CloseDir();
                                        }
                                }
                        }

                        delete readFile;
                }
        }

        CyStringList gameDirs;
        gameDirs.PushBack("HKCU\\Software\\Deepsilver\\X2 The Threat", "INSTALL_DIR");
        gameDirs.PushBack("HKCU\\Software\\Deepsilver\\X3 Reunion", "INSTALL_DIR");
        gameDirs.PushBack("HKCU\\Software\\Egosoft\\X3TC", "INSTALL_DIR");
        gameDirs.PushBack("Steam\\x2 - the threat");
        gameDirs.PushBack("Steam\\x3 - reunion");
        gameDirs.PushBack("Steam\\x3 terran conflict");
        // some custom directories to look for
        gameDirs.PushBack("%PROGRAMFILES%\\Egosoft\\X2 The Threat");
        gameDirs.PushBack("%PROGRAMFILES%\\Egosoft\\X3 Reunion");
        gameDirs.PushBack("%PROGRAMFILES%\\Egosoft\\X3 Terran Conflict");
        gameDirs.PushBack("C:\\Games\\X2");
        gameDirs.PushBack("C:\\Games\\X3");
        gameDirs.PushBack("C:\\Games\\X3TC");
        gameDirs.PushBack("D:\\Games\\X2");
        gameDirs.PushBack("D:\\Games\\X3");
        gameDirs.PushBack("D:\\Games\\X3TC");

        for ( SStringList *strNode = gameDirs.Head(); strNode; strNode = strNode->next )
        {
                CyString sFirst = strNode->str.GetToken("\\", 1, 1);
                CyString sRest = strNode->str.GetToken("\\", 2);

                if ( sFirst.Compare("HKCU") || sFirst.Compare("HKLM") )
                {
                        RegistryKey ^searchKey = nullptr;
                        if ( sFirst.Compare("HKCU") )
                                searchKey = Registry::CurrentUser->OpenSubKey(SystemStringFromCyString(sRest));
                        else if ( sFirst.Compare("HKLM") )
                                searchKey = Registry::LocalMachine->OpenSubKey(SystemStringFromCyString(sRest));

                        if ( searchKey )
                        {
                                System::String ^regRead = System::Convert::ToString(searchKey->GetValue(SystemStringFromCyString(strNode->data)));
                                if ( regRead )
                                {
                                        CyString dir = CyStringFromSystemString(regRead);
                                        gui->GetGameDirs(dir, anyDirs, anyDirs);
                                }
                        }
                }
                else if ( sFirst.Compare("Steam") )
                {
                        RegistryKey ^steamKey = Registry::CurrentUser->OpenSubKey("Software\\Valve\\Steam");
                        if ( steamKey )
                        {
                                System::String ^regRead = System::Convert::ToString(steamKey->GetValue("SteamPath"));
                                if ( regRead )
                                {
                                        CyString steamDir = CyStringFromSystemString(regRead);
                                        CyString dir = steamDir + "\\steamapps\\common\\" + sRest;
                                        dir = dir.FindReplace("/","\\");
                                        dir = dir.FindReplace("\\\\", "\\");
                                        gui->GetGameDirs(dir, anyDirs, anyDirs);
                                }
                        }
                }
                else
                {
                        CyString dir = strNode->str;
                        dir = dir.FindReplace("/","\\");
                        dir = dir.FindReplace("\\\\", "\\");
                        dir = dir.FindReplace("%PROGRAMFILES%", CyStringFromSystemString(progfile));
                        gui->GetGameDirs(dir, anyDirs, anyDirs);
                }
        }

        // no directories?
        if ( dirList.Empty() )
        {
                OpenFileDialog ^ofd = gcnew OpenFileDialog();
                ofd->Filter = "X-Universe Executable|";
                String ^games = "";
                for ( int i = 0; i < packages.GetGameExe()->GetNumGames(); i++ )
                {
                        SGameExe *exe = packages.GetGameExe()->GetGame(i);
                        if ( i ) ofd->Filter += ";";
                        ofd->Filter += SystemStringFromCyString(exe->sExe);
                        games += "|" + SystemStringFromCyString(exe->sName) + "|" + SystemStringFromCyString(exe->sExe);
                }
                ofd->Filter += games;
                ofd->FilterIndex = 1;
                ofd->RestoreDirectory = true;
                if ( ofd->ShowDialog() == System::Windows::Forms::DialogResult::OK )
                {
                        CyString dir = CyStringFromSystemString(IO::FileInfo(ofd->FileName).DirectoryName);
                        if ( !dir.Empty() )
                        {
                                CyString gameName = packages.GetGameName(dir);
                                if ( !gameName.Empty() )
                                {
                                        remDirList.Remove(dir);
                                        gui->GetGameDirs(dir, false, true);
                                }
                        }
                }
        }

        // still no directories, quit
        if ( dirList.Empty() )
                return 1;

        CyString dir = dirList.First();

        StartUp ^startup = gcnew StartUp(&packages, &dir, (openPackage) ? true : false, Advanced);
        Application::Run(startup);
        if ( packages.IsOldPluginManager() )
        {
                if ( MessageBox::Show("Game directory: " + SystemStringFromCyString(dir) + "\nIs currently being controled by the old plugin manager\nIf you continue, you will be unable to use the old version again\nDo you wish to continue?", "Update Game Directory", MessageBoxButtons::YesNo, MessageBoxIcon::Question) != System::Windows::Forms::DialogResult::Yes )
                        return 0;
        }

        // opening a package from command line
        if ( openPackage )
        {
                if ( gui->InstallPackage(openPackage, true, false, false) )
                {
                        if ( !packages.GetModKey().Empty() )
                                PluginManager::WriteRegistryValue(packages.GetModKey(), packages.GetSelectedModName());
                        packages.CloseDir(0, 0, true);
                        return 0;
                }
                return 1;
        }

        gui->UpdateDirList();
        gui->UpdateControls();
        gui->UpdatePackages();
        gui->StartCheckTimer();

        System::String ^mod = PluginManager::ReadRegistryValue(packages.GetModKey());
        packages.SetMod(CyStringFromSystemString(mod));

        gui->CheckProtectedDir();
        Application::Run(gui);

        // close directory 
        if ( packages.IsLoaded() )
        {
                if ( !packages.GetModKey().Empty() )
                        PluginManager::WriteRegistryValue(packages.GetModKey(), packages.GetSelectedModName());
                if ( packages.AnyUnusedShared() )
                {
                        if ( MessageBox::Show("You have some unused shared files, would you like to remove these?", "Remove Shared Files", MessageBoxButtons::YesNo, MessageBoxIcon::Question) == System::Windows::Forms::DialogResult::Yes)
                                packages.RemoveUnusedSharedFiles();
                }
                packages.CloseDir(0, 0, true);
        }

        CyStringList restoreModified;
        if ( gui->GetDownloadFile() )
        {
                if ( System::IO::File::Exists(".\\AutoUpdater.exe") )
                {
                        // rename the autoupdater
                        System::String ^dir = System::IO::FileInfo(System::Windows::Forms::Application::ExecutablePath).DirectoryName;
                        if ( System::IO::File::Exists(tempDir + "\\AutoUpdater_old.exe") )
                                System::IO::File::Delete(tempDir + "\\AutoUpdater_old.exe");
                        System::IO::File::Copy(dir + "\\AutoUpdater.exe", tempDir + "\\AutoUpdater_old.exe");

                        System::Diagnostics::ProcessStartInfo ^info = nullptr;
                        if ( System::IO::File::Exists(tempDir + "\\AutoUpdater_old.exe") )
                                info = gcnew System::Diagnostics::ProcessStartInfo(tempDir + "\\AutoUpdater_old.exe");
                        else 
                        {
                                MessageBox::Show("Error trying to update the Plugin Manager\nUnable to load AutoUpdater", "AutoUpdate", MessageBoxButtons::OK, MessageBoxIcon::Warning);
                                System::Windows::Forms::Application::Restart();
                                return 0;
                        }

                        if ( info )
                        {
                                info->WorkingDirectory = dir;
                                info->Arguments = "\"" + gui->GetDownloadFile() + "\" \"" + System::Windows::Forms::Application::ExecutablePath + "\"";
                                info->UseShellExecute = false;
                                info->WindowStyle = System::Diagnostics::ProcessWindowStyle::Normal;
                                System::Diagnostics::Process ^process = System::Diagnostics::Process::Start(info);
                        }
                }
                else
                {
                        MessageBox::Show("Error trying to update the Plugin Manager\nUnable to load AutoUpdater", "AutoUpdate", MessageBoxButtons::OK, MessageBoxIcon::Warning);
                        System::Windows::Forms::Application::Restart();
                }
        }
        else if ( gui->GetRunFile() )
        {
                System::String ^dir = System::IO::FileInfo(System::Windows::Forms::Application::ExecutablePath).DirectoryName;

                // manager was run from the launcher, ie the launcher is still running, send a message to run the game instead of loading another one
                if ( fromLauncher )
                {
                        StreamWriter ^sw = File::CreateText(mydoc + "\\Egosoft\\launchgame.dat");
                        try 
                        {
                                sw->WriteLine("File:" + gui->GetRunFile());
                                if ( gui->GetGameArgs() && gui->GetGameArgs()->Length )
                                        sw->WriteLine("Args:" + gui->GetGameArgs());
                        }
                        finally
                        {
                                if ( sw )
                                        delete (IDisposable ^)sw;
                        }
                }
                else
                {
                        if ( System::IO::File::Exists(dir + "\\GameLauncher.exe") )
                        {
                                System::Diagnostics::ProcessStartInfo ^info = gcnew System::Diagnostics::ProcessStartInfo(dir + "\\GameLauncher.exe");
                                if ( info )
                                {
                                        if ( packages.GetCurrentGameFlags() & EXEFLAG_ADDON ) {
                                                CPackages p;
                                                p.Startup(".", CyStringFromSystemString(tempDir), CyStringFromSystemString(mydoc), "");
                                                CyString baseDir = CFileIO(CyStringFromSystemString(gui->GetRunFile())).GetDir();
                                                if ( p.Read(baseDir) ) {
                                                        if ( !p.IsVanilla() ) {
                                                                p.SetVanilla(true);
                                                                p.PrepareDisableForVanilla();
                                                                p.EnablePreparedPackages(0, 0, 0);
                                                                restoreModified.PushBack(baseDir);
                                                        }
                                                        p.CloseDir();                                                   
                                                }
                                        }

                                        info->WorkingDirectory = dir;
                                        if ( gui->GetGameArgs() && gui->GetGameArgs()->Length )
                                                info->Arguments = "\"" + gui->GetRunFile() + "\" \"" + System::Windows::Forms::Application::ExecutablePath + "\" \"" + gui->GetGameArgs() + "\"";
                                        else
                                                info->Arguments = "\"" + gui->GetRunFile() + "\" \"" + System::Windows::Forms::Application::ExecutablePath + "\"";
                                        info->UseShellExecute = false;
                                        info->WindowStyle = System::Diagnostics::ProcessWindowStyle::Normal;
                                        System::Diagnostics::Process ^process = System::Diagnostics::Process::Start(info);
                                }
                        }
                }
        }

        // write config
        std::vector<CyString> writeLines;
        for ( SStringList *strNode = dirList.Head(); strNode; strNode = strNode->next )
        {
                writeLines.push_back(CyString("Dir:") + strNode->str);
                CyString data;
                if ( strNode->data.IsIn("|") )
                {
                        data = CPackages::ConvertLanguage(strNode->data.GetToken("|", 1, 1).ToInt()) + "|";
                        data += strNode->data.GetToken("|", 2);
                }
                else
                        data = strNode->data;

                CyString exe = CFileIO(packages.GetGameExe()->GetGameRunExe(strNode->str)).GetFullFilename();
                writeLines.push_back(CyString("DirExe:") + data + "|" + exe);

                // do the log files
                writeLines.push_back(CyString("GameLog:") + packages.GetLogDirectory(exe) + "|" + exe);

        }
        for ( SStringList *strNode = remDirList.Head(); strNode; strNode = strNode->next )
                writeLines.push_back(CyString("RemDir:") + strNode->str);
        if ( gui->IsExperimental() )
                writeLines.push_back("Experimental:");
        if ( gui->IsShips() )
                writeLines.push_back("FilterShips:");
        if ( gui->IsOnlySigned() )
                writeLines.push_back("FilterSigned:");
        if ( gui->IsCheat() )
                writeLines.push_back("Cheat:");
        writeLines.push_back(CyString("SaveGameManager:") + (long)gui->GetSaveGameManager());
        if ( gui->IsDownloadable() )
                writeLines.push_back("Downloadable:");
        if ( gui->IsModSelectorDetailsShowing() )
                writeLines.push_back("ModSelectorDetails:");
        if ( !gui->IsAutoUpdate() )
                writeLines.push_back("NoAutoUpdate:");
        if ( gui->WindowState == FormWindowState::Normal )
        {
                writeLines.push_back(CyString("ManagerSize:") + (long)gui->Size.Height + " " + (long)gui->Size.Width);
                writeLines.push_back(CyString("ManagerPos:") + (long)gui->Location.X + " " + (long)gui->Location.Y);
        }
        else
        {
                writeLines.push_back(CyString("ManagerPos:") + (long)gui->RestoreBounds.Location.X + " " + (long)gui->RestoreBounds.Location.Y);
                writeLines.push_back(CyString("ManagerSize:") + (long)gui->RestoreBounds.Size.Height + " " + (long)gui->RestoreBounds.Size.Width);
        }

        if ( gui->WindowState == FormWindowState::Maximized )
                writeLines.push_back("ManagerMax:");
        if ( gui->GetIgnoreJoy() )
                writeLines.push_back(CyString("IgnoreJoy:") + gui->GetIgnoreJoy());

        for ( int i = 0; i < gui->GetMaxTips(); i++ )
        {
                int tips = gui->GetTips(i);
                if ( tips == -1 )
                        continue;
                writeLines.push_back(CyString("Tips: ") + (long)i + " " + (long)tips);
        }

        for ( SStringList *rm = restoreModified.Head(); rm; rm = rm->next ) {
                writeLines.push_back(CyString("RestoreModified: ") + rm->str);
        }

        // write settings
        configFile.WriteFile(&writeLines);

        return 0;
}