Subversion Repositories spk

Rev

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

#ifndef __PACKAGES_H__
#define __PACKAGES_H__

#include "SpkFile.h"
#include "GameExe.h"
#include "XspFile.h"
#include "archive/unzip.h"

#include "MultiSpkFile.h"
#include "VirtualFileSystem.h"
#include "Utils/StringList.h"

#include "spkdefines.h"

class CFileIO;

namespace SPK {
        class COriginalFiles;
}

using namespace SPK;

class SPKEXPORT CPackages
{
public:
        static Utils::String ConvertLanguage(int lang);
        static SAvailablePackage *CreateAvailablePackageData(CBaseFile *package);
        static Utils::String FormatAvailablePackageData(CBaseFile *package);
        static Utils::String FormatAvailablePackageData(SAvailablePackage *package);
        static Utils::String CreateFromPackagerScript(CPackages *packages, const Utils::String &filename);
        static int GeneratePackageUpdateData(CyString dir, bool includeSingle = true);

        CPackages ();
        ~CPackages ();

        bool isOldDir(const Utils::String &dir);
        bool Read(CyString dir, CProgressInfo *progress = NULL);
        bool read(const Utils::String &dir, CProgressInfo *progress = NULL);
        void Startup(CyString dir, CyString tempDir, CyString myDoc, CyString mod = NullString);
        void startup(const Utils::String &dir, const Utils::String &tempDir, const Utils::String &myDoc);
        void startup(const Utils::String &dir, const Utils::String &tempDir, const Utils::String &myDoc, const Utils::String &mod);

        bool extractAll(CBaseFile *baseFile, const Utils::String &dir, int game, bool includedir = true, CProgressInfo *progress = NULL) const;
        bool generatePackagerScript(CBaseFile *baseFile, bool wildcard, Utils::CStringList *list, int game, bool datafile = false) const;
        CBaseFile *LoadPackagerScript(const Utils::String &filename, int compression, Utils::String (*askFunc)(const Utils::String &), Utils::CStringList *malformedLines = NULL, Utils::CStringList *unknownCommands = NULL, Utils::CStringList *variables = NULL, CProgressInfo *progress = NULL);
        CyStringList *GetGlobals() { return &m_lGlobals; }
        CyStringList *GetFakePatchOrder() { return &m_lFakePatchOrder; }
        Utils::String getCurrentDirectory() const;
        static CyString GetTempDirectory() { return m_sTempDir; }
        static const Utils::String &tempDirectory() { return m_sTempDir; }
        CyString GetMyDocuments() { return m_sMyDoc; }
        const Utils::String &myDocuments() { return m_sMyDoc; }
        CGameExe *GetGameExe() { return &m_gameExe; }
        CLinkList<CBaseFile> *GetInstallPackageList() { return &m_lInstallList; }

        // installing/uninstalling
        bool            InstallPackage ( CBaseFile *package, CyStringList *errors, CProgressInfo *progress = NULL, bool disabled = false );
        CBaseFile               *OpenPackage ( CyString file, int *error, CProgressInfo *progress = NULL, int readtype = SPKREAD_ALL, int flags = READFLAG_NONE );
        CMultiSpkFile   *OpenMultiPackage(CyString file, int *error, CProgressInfo *progress = NULL);
        bool            OpenMultiPackage ( CyString file, CLinkList<CBaseFile> *packageList, int *error, CProgressInfo *progress = NULL );
        int                     CheckInstallPackage(CBaseFile *package, int check = IC_ALL);
        bool            RemoveFile(C_File *file, CyStringList *errors = NULL);
        void            PrepareUninstallPackage(CBaseFile *package);
        bool            UninstallPreparedPackages(CyStringList *errors, CProgressInfo *progress, CLinkList<CBaseFile> *uninstalledPackages = NULL, CLinkList<CBaseFile> *disabledPackages = NULL);
        void            ConvertOldPackage(CBaseFile *p);
        void            PurgeUninstallScripts(CBaseFile *package, CyStringList *errors);
        int             PrepareInstallPackage(CBaseFile *package, bool disabled = false, bool force = false, int check = IC_ALL);
        int                     InstallPreparedPackages(CyStringList *errors, CProgressInfo *progress, CLinkList<CBaseFile> *errored, CLinkList<CBaseFile> *installedList = NULL);
        void            RemovePreparedInstall(CBaseFile *package);
        int                     GetNumPackagesInQueue() { return m_lInstallList.size(); }
        int                     CheckOpenPackage(CyString file, int *error);
        bool            findAllNeededDependacies(CBaseFile *p, const CLinkList<CBaseFile> &packages, CLinkList<CBaseFile> *foundPackages, bool onlyEnabled = false, bool includePrepared = false) const;
        int                     GetMissingDependacies(CBaseFile *p, Utils::CStringList *list, bool onlyEnabled = false, bool includePrepared = false);
        bool            CheckInstalledDependacy(CyString name, CyString author, CyString version, bool onlyEnabled = false, bool includePerpered = false);
        bool            checkInstalledDependacy(const Utils::String &name, const Utils::String &author, const Utils::String &version, bool onlyEnabled = false, bool includePerpered = false) const;
        bool            CheckEnabledDependacy(CBaseFile *p);
        int                     GetDependacyList(CBaseFile *package, CLinkList<CBaseFile> *list);
        int                     PrepareMultiPackage ( CyString file, CLinkList<CBaseFile> *errorPackageList, int *error, CProgressInfo *progress = 0);

        bool            IsOldPluginManager() { return m_bOldPlugin; }
        int                     findPackageFiles(CLinkList<CBaseFile> &packages, const Utils::String &dir);
        int                     findPackageDirectories(CLinkList<CBaseFile> &packages, const Utils::String &dir);
        int                     findAllPackages(CLinkList<CBaseFile> &packages, const Utils::String &dir);

        // enable/disable
        bool EnablePackage ( CBaseFile *package, CyStringList *errors, CProgressInfo *progress = NULL );
        bool DisablePackage ( CBaseFile *package, CyStringList *errors, CProgressInfo *progress = NULL );
        bool DisablePreparedPackages ( CyStringList *errors, CProgressInfo *progress, CLinkList<CBaseFile> *disabledPackages = NULL );
        bool PrepareEnablePackage(CBaseFile *package);
        bool PrepareDisablePackage(CBaseFile *package);
        bool EnablePreparedPackages ( CyStringList *errors, CProgressInfo *progress, CLinkList<CBaseFile> *enabledPackages = NULL );
        int  GetNumPackagesInEnabledQueue() { return m_lEnableList.size(); }
        int  GetNumPackagesInDisabledQueue() { return m_lDisableList.size(); }
        bool PrepareDisableForVanilla();
        bool PrepareEnableLibrarys();
        bool PrepareEnableFromVanilla();

        void WriteData();
        bool CloseDir ( CyStringList *errors = 0, CProgressInfo *progress = NULL, bool removedir = false );
        bool RestoreFakePatch();
        bool ReadyFakePatch();
        bool CheckValidPluginManagerFile(CyString filename);
        bool CheckIfPluginManagerFile(CyString filename);

        // package control
        void UpdateUsedFiles(CLinkList<CBaseFile> *ignoreList = NULL, bool = true);
        void UpdateSigned();
        bool UpdatePackages(int doStatus = -1, bool individual = false);
        CBaseFile *FindXspPackage(CyString id);
        CBaseFile *FindSpkPackage(CyString name, CyString author);
        CBaseFile *findSpkPackage(const Utils::String &name, const Utils::String &author) const;
        CArchiveFile *FindArchivePackage(CyString name);
        CBaseFile *FindPackage(CyString name, CyString author);
        CBaseFile *FindFirstPackageWithFile(C_File *f);
        CBaseFile *FindNextPackageWithFile(CBaseFile *p, C_File *f);
        CBaseFile *FindPackage(CBaseFile *package);
        C_File *FindFile(int filetype, CyString filename, CyString dir = NullString);
        CBaseFile *FirstPackage() { return m_lPackages.First(); }
        CBaseFile *NextPackage() { return m_lPackages.Next(); }
        CBaseFile *GetFirstPackage() { if ( m_lPackages.Front() ) return m_lPackages.Front()->Data(); return NULL; }
        CBaseFile *GetNextPackage(CBaseFile *from) 
        { 
                bool found = false;
                for ( CListNode<CBaseFile> *node = m_lPackages.Front(); node; node = node->next() )
                {
                        if ( !node->Data() ) continue;
                        if ( node->Data() == from )
                                found = true;
                        else if ( found )
                                return node->Data();
                }
                return NULL; 
        }
        void Reset();
        CBaseFile *GetPackageAt(int i) { return m_lPackages[i]; }
        CyString GetSelectedModName();
        CyString GetModKey();
        void SetupWares();
        void SetupShips();
        void PurgeGameObjects();
        void PurgeWares();
        void PurgeShips();
        void StartPackage() { m_pPackageNode = m_lPackages.Front(); }
        void UpdatePackage(CBaseFile *p);
        CBaseFile *GetCurrentPackage() { return (m_pPackageNode) ? m_pPackageNode->Data() : NULL; }
        bool RemoveCurrentDirectory();
        void RemoveCreatedFiles();
        bool AnyUnusedShared();

        // util functions
        void RemoveUnusedDirectories(CyStringList &dirs, CyStringList *errors = NULL);
        int  RemoveUninstallScripts(CyStringList *errors = 0, CProgressInfo *progress = NULL);
        bool RemoveUninstallFile(C_File *file, CyStringList *errors = 0);
        int  RemoveUnusedSharedFiles(CyStringList *errors = 0, CProgressInfo *progress = NULL);
        bool RemoveSharedFile(C_File *file, CyStringList *errors = NULL);
        void ShufflePatchTo(C_File *file, int to, CyStringList *errors);
        void ShuffleFakePatches(CyStringList *errors);
        void ShuffleTextFiles(CyStringList *errors);
        int  FindNextFakePatch(int start = 0, CyString dir = NullString);
        unsigned int  findNextTextFile(unsigned int start = 4) const;
        unsigned int  findNextTextFile(const Utils::String &dir, unsigned int start = 4) const;
        int  FindLastFakePatch(int start = 99, CyString dir = NullString);
        int  FindLastTextFile(int start = 9999, CyString dir = NullString);
        int  FindLowestFakePatchInstalled();
        void ReadGameLanguage(bool force = true);
        int      RemoveAllPackages(CyStringList *errors = NULL, CProgressInfo *progress = NULL);
        void AssignPackageNumbers();
        int  GetChildPackages(CBaseFile *package, CLinkList<CBaseFile> *children, bool recursive = false);
        int  GetAllPackageFiles(CBaseFile *package, CLinkList<C_File> *fileList, bool includeChild);
        int      GetAllPackageFiles(CLinkList<CBaseFile> *list, CLinkList<C_File> *fileList, bool includeChild);
        void AddLogEntry(int type, CyString args, CyStringList *errors);
        Utils::String findDataDir(const Utils::String &dir, const Utils::String &file);
        int  CountPackages(int type, bool onlyEnabled);
        int  CountBuiltInPackages(bool onlyEnabled);
        bool isCurrentDir(const Utils::String &dir) const;
        bool CheckOtherPackage(CBaseFile *package);
        int CheckPreparedInstallRequired(CLinkList<CBaseFile> *list);
        static int ConvertWareType(char w);
        static char ConvertWareTypeBack(int w);
        Utils::String logDirectory();
        Utils::String logDirectory(const Utils::String &gameExe);
        Utils::String saveDirectory();
        void backupSaves() { backupSaves(m_bVanilla); }
        void backupSaves(bool vanilla);
        void restoreSaves() { restoreSaves(m_bVanilla); }
        void restoreSaves(bool vanilla);
        bool UnPackFile(CyString filename, bool checkxml = true);
        bool PackFile(CyString filename);
        bool PackFile(CFileIO *File, CyString filename);
        Utils::String ConvertTextString(const Utils::String &text);
        void LoadVirtualFileSystem();
        bool CheckAccessRights(CyString dir);
        bool LoadShipData(CyString file, CyStringList *list);
        bool LoadShipData(CVirtualFileSystem *pVfs, CyStringList *list);
        bool ReadTextPage(CyString file, CyStringList *list, bool search, int page);
        CyStringList *LoadShipData(CyString file);
        CyStringList *ReadTextPage(CyString file, bool search, int page);
        int AdjustFileType(CyString name, int filetype);
        CXspFile *extractShip(const Utils::String &sCatFile, const Utils::String &sId, CProgressInfo *progress = NULL);
        CyString ReadShipData(CyString file, CyString entry);
        bool IsSamePackage(CBaseFile *p1, CBaseFile *p2);
        void ApplyFakePatchOrder(CyStringList *list);
        CBaseFile *CreateFromArchive(CyString filename, bool toInstall = false );
        void ReadArchiveData(const char *buf, size_t len, CBaseFile *archive);
        void ReadArchiveData(CyString filename, CBaseFile *archive);
        int VerifyInstalledFiles(CyStringList *missingFiles = NULL, bool getPackages = true);
        Utils::String empWaresForGame(int *maxsize = NULL);
        void addEMPPriceOverride(int empId, int price);
        void addEMPNotoOverride(int empId, int noto);
        void addBuiltInWarePriceOverride(int empId, int price);
        void addBuiltInWareNotoOverride(int empId, int noto);
        void addCustomWarePriceOverride(const Utils::String &id, int price);
        void addCustomWareNotoOverride(const Utils::String &id, int noto);

        int GetCurrentGameFlags() { return m_iGameFlags; }

        void SetCurrentDir(CyString dir);

        // merge mods
        void getMergedFiles(Utils::CStringList &list, CCatFile *cat1, CCatFile *cat2);
        bool CanWeMerge(const Utils::String &file) const;
        bool MergeMods(CCatFile *mod1, CCatFile *mod2, CyString outFile, CyStringList *cantMerge);
        bool NeedToMerge(CyString file);
        CyStringList MergeTextFiles(CyStringList *files, CCatFile *mod1, CCatFile *mod2);
        bool GetModCompatabilityList(C_File *file, CyStringList *list = NULL);
        bool CheckCompatabilityBetweenModFiles(C_File *from, C_File *to, CyStringList *list = NULL);
        bool CheckCompatabilityBetweenMods(CBaseFile *from, CBaseFile *to, CyStringList *list = NULL);
        int CheckCompatabilityAgainstPackages(CBaseFile *newFile, CyStringList *list = NULL, CLinkList<CBaseFile> *packages = NULL);

        CyString GetLanguageName() const;

        int     GetGameLanguage() const;
        int     GetGameLanguage(const Utils::String &dir) const;
        int      GetGameAddons(Utils::CStringList &exes);
        int      GetGameAddons(Utils::CStringList &exes, const Utils::String &dir);
        Utils::String getGameName() const;
        Utils::String getGameName(const Utils::String &dir) const;
        CyString GetGameName(CyString dir = NullString);
        CyString GetGameVersionFromType(int game, int version, CyString sVersion);
        CyString GetGameNameFromType(int game);
        CyString GetGameTypesString(CBaseFile *package, bool includeVersion);
        CyString GetGameVersionString(CBaseFile *package);
        Utils::String GetGameRunExe(const Utils::String &dir);
        CyString GetProperDir(CyString dir = NullString);
        CyString GetAddonDir(CyString dir = NullString);
        Utils::String GetGameRunExe();
        Utils::String getProperDir() const;
        Utils::String getProperDir(const Utils::String &dir) const;
        Utils::String getAddonDir() const;
        Utils::String getAddonDir(const Utils::String &dir) const;

        // text files
        void CreateLanguageTextFiles(CyStringList *errors = 0);
        bool RenameTextFile(CyString textid, int languageid, CyStringList *errors);
        void AddTextFileToScripts(C_File *file, CyString textid);
        void CreatePluginManagerText();
        void createPluginManagerOpenText();

        // game control
        void CreateEMPFile(CyString progDir = NullString);
        void CreateWareFiles();
        int ExtractGameFile(CyString aFilename, CyString aTo, CyString dir = NullString, CyString addon = NullString);
        void CreateDummies();
        void CreateComponants();
        void CreateCutData();
        void CreateBodies();
        void CreateGlobals();
        void CreateAnimations();
        void CreateTShips();
        CyStringList *CreateCockpits();
        void CreateCustomStarts();
        void AddCreatedFile(CyString file);
        
        bool ReadGlobals(CyStringList &globals);
        bool readWares(int iLang, CLinkList<SWareEntry> &list);
        bool readCommands(int iLang, CLinkList<SCommandSlot> &list);
        bool readWingCommands(int iLang, CLinkList<SCommandSlot> &list);
        int  empOveridePrice(int id);
        bool empOverideNoto(int id, int *noto);
        int  builtInWareOveridePrice(int id);
        bool builtInWareOverideNoto(int id, int *noto);
        int  customWareOveridePrice(const Utils::String &id);
        bool customWareOverideNoto(const Utils::String &id, int *noto);
        void removeEmpOverride(int pos);
        void removeBuiltinWareOverride(int pos);
        void removeCustomWareOverride(const Utils::String &id);

        // install text
        CyString GetInstallBeforeText(CBaseFile *package);
        CyString GetInstallAfterText(CBaseFile *package);
        CyString GetUninstallBeforeText(CBaseFile *package);
        CyString GetUninstallAfterText(CBaseFile *package);

        //setting functions
        void SetRenameText(bool b) { m_bRenameText = b; }
        void SetLanguage(int i) { m_iLanguage = i; }
        void SetAutoEnable(bool b) { m_bAutoEnableChild = b; }
        void SetForceModInstall(bool b) { m_bForceModInstall = b; }
        void setTempDirectory(const Utils::String &s) { m_sTempDir = s; }
        void setMyDocuments(const Utils::String &s) { m_sMyDoc = s; }
        void SetForceEMP(bool b) { m_bForceEMP = b; }
        void SetSurpressProtectedWarning(bool b) { m_bSurpressProtectedWarning = b; }
        void SurpressProtectedWarning() { m_bSurpressProtectedWarning = true; }
        bool IsSupressProtectedWarning() { return m_bSurpressProtectedWarning; }

        int GetLanguage() { return m_iLanguage; }
        int GetGame() { return m_iGame; }
        bool IsLoaded() { return m_bLoaded; }
        bool IsVanilla() { return m_bVanilla; }
        void SetVanilla(bool b);

        CyString GetSetMod() { return m_sSetMod; }
        void SetMod(CyString mod) { 
                if ( mod != "PluginManager" )
                        m_sSetMod = mod; 
        }
        void setSaveGameManager(bool managed);

        CBaseFile *GetEnabledMod() { return m_pEnabledMod; }

        //errors
        void ClearError() { m_iError = PKERR_NONE; }
        int  GetError() { return m_iError; }

        CLinkList<CBaseFile> *PackageList() { return &m_lPackages; }
        CLinkList<SAvailablePackage> *GetAvailablePackageList() { return &m_lAvailablePackages; }
        bool AnyAvailablePackages(int type = -1);
        bool AddAvailablePackage(SAvailablePackage *package);
        void ParseAvailablePackage(CyString str, CyString webaddress = NullString);
        SAvailablePackage *FindAvailablePackage(const Utils::String &filename);
        int FindAllServers(CyStringList *list);

        CBaseFile *FindScriptByAuthor(CyString author, CBaseFile *prev = NULL);
        void RemoveFailedFiles();

private:
        bool _checkForDisable(CBaseFile *package, bool disabled, CBaseFile *oldPackage);
        CBaseFile *_archive_fromRar(CyString filename, bool toInstall);
        CBaseFile *_archive_fromZip(CyString filename, bool toInstall);
        void _addToFakePatch(CBaseFile *pPackage);
        int _gameTextNumber() const;
        void _addWareOverride(enum WareTypes type, int pos, const Utils::String &id, int value, bool noto);
        int _warePriceOverride(enum WareTypes type, int pos, const Utils::String &id);
        bool _wareNotoOverride(enum WareTypes type, int pos, const Utils::String &id, int *noto);
        void _removeWareOverride(enum WareTypes type, int pos, const Utils::String &id);

private:
        CyString        m_sCurrentDir;
        static Utils::String    m_sTempDir;
        Utils::String                   m_sMyDoc;
        CyString        m_sSetMod;
        Utils::String _sSaveDir;
        GameDirectory *_pCurrentDir;

        // global files list
        CLinkList<C_File>               m_lFiles;
        CLinkList<CBaseFile>    m_lPackages;
        CLinkList<C_File>               m_lUninstallFiles;
        CLinkList<SGameWare>    m_lGameWares[WAREBUFFERS];
        CLinkList<SGameShip>    m_lGameShips;
        CLinkList<SWarePriceOverride>   m_lWarePrices;
        COriginalFiles             *_pOriginalFiles;

        // prepared lists
        CLinkList<CBaseFile>    m_lInstallList; // install/uninstalling packages
        CLinkList<CBaseFile>    m_lEnableList;  // enable packages
        CLinkList<CBaseFile>    m_lDisableList; // disable packages

        CyStringList                    m_lCreatedFiles; // list of files we've created
        CyStringList                    m_lNonRemovedFiles; // list of fiels that couldn't be removed for some reason
        CyStringList                    m_lGlobals; // global settigns that we want changed
        CyStringList                    m_lFakePatchOrder; // ordered fake patches
        CLinkList<SAvailablePackage> m_lAvailablePackages; // list of available packages online

        CVirtualFileSystem              m_pGameVFS; // Games Virtual File System

        CGameExe                                m_gameExe;
        SGameExe                                *m_pCurrentGameExe;
        CBaseFile                          *m_pEnabledMod;

        // settings
        bool            m_bRenameText;  // rename text files
        bool            m_bAutoEnableChild;     // auto enable all children
        bool            m_bForceModInstall; // allowsm ultiple mods to be installed
        bool            m_bOldPlugin;           // if its loading data from the old plugin manager
        bool            m_bLoadVFS;                     // if we should load the virtual filesystem
        int                     m_iLanguage;    // Language id to use
        int                     m_iSaveGameManager; // Save game manager
        bool            m_bSurpressProtectedWarning; // prevent checking for protected directory

        int                     m_iGame;                // the game the directory is
        int                     m_iGameVersion; // the version of the game (version position)
        CyString        m_sGameVersion; // the version of the game (full version)
        int                     m_iGameFlags;   // the flags for the game from SGameExe
        int                     m_iMaxPatch;    // the maximum patch for the game

        int                     m_iSaveGame;
        int                     m_iError;
        int                     m_iLastUpdated;
        int                     m_iFakePatch;           // The current fake patch

        bool            m_bVanilla;             // currently in vanilla mode, dont allow unsigned packages to be installed

        bool            m_bLoaded;
        bool            m_bRedo;
        bool            m_bUsedWare;    // if we have used the ware files in the directory, not in a patch
        bool            m_bRemoveDir;   // shall we remove direcotires;

        int                     m_iWareBuffer[WAREBUFFERS];     //Ware Buffers
        int                     m_iShipBuffer; //Ship Buffers

        bool            m_bDisableVanilla;
        bool            m_bForceEMP;

        CListNode<CBaseFile>    *m_pPackageNode;
};

#endif // __PACKAGES_H__