Subversion Repositories spk

Rev

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

// BaseFile.h: interface for the CBaseFile class.
//
//////////////////////////////////////////////////////////////////////

#ifndef __BASEFILE_H__
#define __BASEFILE_H__

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "lists.h"
#include "StringList.h"
#include "File.h"
#include "Utils/String.h"
#include "Utils/StringList.h"
#include "archive/zip.h"

#include "Package/CorePackage.h"

#define GAME_ALL                        0
#define GAME_X2                         1
#define GAME_X3                         2
#define GAME_X3TC                       3
#define GAME_X3AP                       4
#define GAME_X3FL                       5
#define GAME_MAX                        (GAME_X3FL)
#define GAME_ALLNEW                     (1 << 31)

#define FILEVERSION 4.30f

#define WRITECHUNK              50000

class CPackages;
class CGameExe;

namespace SPK {
        class CTextDB;
}

using namespace SPK;

enum {
        READFLAG_NONE = 0,
        READFLAG_NOUNCOMPRESS = 1
};

enum {SPKFILE_INVALID, SPKFILE_SINGLE, SPKFILE_MULTI, SPKFILE_SINGLESHIP, SPKFILE_OLD, SPKFILE_BASE};
enum {SPKREAD_ALL, SPKREAD_NODATA, SPKREAD_VALUES, SPKREAD_HEADER};
enum {DELETESTATE_NONE, DELETESTATE_WAITING, DELETESTATE_DONE};
enum {SPKINSTALL_CREATEDIRECTORY, SPKINSTALL_CREATEDIRECTORY_FAIL, SPKINSTALL_WRITEFILE, SPKINSTALL_WRITEFILE_FAIL, SPKINSTALL_DELETEFILE, SPKINSTALL_DELETEFILE_FAIL,
                SPKINSTALL_SKIPFILE, SPKINSTALL_REMOVEDIR, SPKINSTALL_ENABLEFILE, SPKINSTALL_DISABLEFILE, SPKINSTALL_ENABLEFILE_FAIL, SPKINSTALL_DISABLEFILE_FAIL,
                SPKINSTALL_UNINSTALL_MOVE, SPKINSTALL_UNINSTALL_COPY, SPKINSTALL_UNINSTALL_MOVE_FAIL, SPKINSTALL_UNINSTALL_COPY_FAIL, SPKINSTALL_UNINSTALL_REMOVE, SPKINSTALL_UNINSTALL_REMOVE_FAIL,
                SPKINSTALL_ORIGINAL_BACKUP, SPKINSTALL_ORIGINAL_RESTORE, SPKINSTALL_ORIGINAL_BACKUP_FAIL, SPKINSTALL_ORIGINAL_RESTORE_FAIL, SPKINSTALL_FAKEPATCH, SPKINSTALL_FAKEPATCH_FAIL, 
                SPKINSTALL_MISSINGFILE, SPKINSTALL_SHARED, SPKINSTALL_SHARED_FAIL, SPKINSTALL_ORPHANED, SPKINSTALL_ORPHANED_FAIL, SPKINSTALL_UNCOMPRESS_FAIL, SPKINSTALL_AUTOTEXT, SPKINSTALL_AUTOTEXT_FAIL
};

enum {PACKAGETYPE_NORMAL, PACKAGETYPE_LIBRARY, PACKAGETYPE_CUSTOMSTART, PACKAGETYPE_PATCH, PACKAGETYPE_UPDATE, PACKAGETYPE_MOD, PACKAGETYPE_SHIP, PACKAGETYPE_FAKEPATCH};

enum {TYPE_BASE, TYPE_SPK, TYPE_XSP, TYPE_ARCHIVE};

// spk header struct
tstruct SSPKHeader {
        SSPKHeader () { fVersion = 0; iValueCompression = lValueCompressSize = 0; }
        float fVersion;
        int iValueCompression;
        unsigned long lValueCompressSize;
} SSPKHeader;


tstruct SSPKHeader2 {
        SSPKHeader2 () { iNumFiles = 0; lSize = 0; lFullSize = 0; }
        int iNumFiles;
        long lSize;
        long lFullSize;
        int iFileCompression;
        int iDataCompression;
} SSPKHeader2;

class SPKEXPORT CBaseFile : public SPK::Package::CCorePackage
{
public:
        static Utils::String ConvertGameToString(int game);
        static int GetGameFromString(const Utils::String &game);
        static Utils::String ErrorString(int error, const Utils::String &errorStr = Utils::String::Null());

        CBaseFile();
        virtual ~CBaseFile();

        // Get basic Settings
        virtual CyString GetFullPackageName(int language, CyString byString) { return GetFullPackageName(language, true, byString); }
        virtual CyString GetFullPackageName(int language, bool includeVersion = true, CyString byString = "by") 
        { 
                CyString p;
                if ( language == -1 )
                        p = this->name();
                else
                        p = GetLanguageName(language);
                if ( includeVersion )
                {
                        p += " V";
                        p += this->version();
                }
                p += " ";
                p += byString + " " + this->author();
                return p;
        }
        CLinkList<C_File> *GetFileList() { return &m_lFiles; }
        C_File *GetIcon () { return m_pIconFile; }
        CyString GetIconExt () { return m_sIconExt; }
        Utils::String getNameValidFile() const;
        int GetDataCompression () { return m_SHeader2.iDataCompression; }
        float GetFileVersion () { return m_SHeader.fVersion; }
        long GetFullFileSize ();
        CyString GetLanguageName ( int lang ) const;
        virtual CyString GetFullPackageName(CyString format, int lang);
        Utils::String GetAutosaveName();
        void SetAutosaveName() { this->setFilename(GetAutosaveName()); }
        SGameCompat *GetGameCompatability(int game);
        bool RemoveGameCompatability(int game);
        void AddGameCompatability(int game, const Utils::String &version);
        bool CheckGameCompatability(int game);
        bool CheckGameVersionCompatability(int game, CyString sVersion, int iVersion);
        bool AnyGameCompatability() { return !m_lGames.empty(); }

        bool AnyWebMirrors() { return !m_lMirrors.Empty(); }
        CyStringList *GetWebMirrors() { return &m_lMirrors; }
        int GetMaxWebMirrors() { return m_lMirrors.Count(); }
        CyString GetWebMirror(int i) { if ( i >= 0 && i < m_lMirrors.Count() ) return m_lMirrors.StringAt(i); return NullString; }
        void ClearWebMirrors() { m_lMirrors.Clear(); }

        const CLinkList<C_File> *fileList() const;
        CLinkList<C_File> *fileList(int type) const;
        C_File *GetFirstFile(int type) const;
        C_File *GetNextFile(C_File *prev) const;
        C_File *GetPrevFile(C_File *next) const;

        virtual Utils::String CreateValuesLine () const;

        virtual bool LoadPackageData(const Utils::String &sFfirst, const Utils::String &sRest, const Utils::String &sMainGame, Utils::CStringList &otherGames, Utils::CStringList &gameAddons, CProgressInfo *progress);
        virtual bool GeneratePackagerScript(bool wildcard, Utils::CStringList *list, int game, const Utils::CStringList &gameAddons, bool datafile = false);
        virtual bool GeneratePackagerScriptFile(bool wildcard, Utils::CStringList *list, int game, const Utils::CStringList &gameAddons);

        void ConvertNormalMod(C_File *f, CyString to);
        void ConvertFakePatch(C_File *f);
        void ConvertAutoText(C_File *f);
        C_File *FindMatchingMod(C_File *f);
        void RenameFile(C_File *f, CyString baseName);

        // set basic settings
        void AddWebMirror               ( CyString str ) { m_lMirrors.PushBack(str, "", true); _changed(); }
        void RemoveWebMirror    ( CyString str ) { m_lMirrors.Remove(str, true); _changed(); }
        void SetDataCompression ( int c )       { m_SHeader2.iDataCompression = c; }
        void SetFileCompression ( int c )       { m_SHeader2.iFileCompression = c; }
        void SetValueCompression( int c )       { m_SHeader.iValueCompression = c; }
        void SetIcon ( C_File *file, CyString ext ) { if ( m_pIconFile ) delete m_pIconFile; m_sIconExt = ext; m_pIconFile = file; _changed(); }
        void SetFtpAddr                 ( CyString str ) { m_sFtpAddr = str; }

        void AddFileScript(FileType filetype, bool shared, CyString rest, const Utils::String &sMainGame, Utils::CStringList &otherGames, Utils::CStringList &gameAddons, CProgressInfo *progress = NULL);

        bool IsMod();
        bool IsFakePatch() const;

        // error handling
        void ClearError () { _sLastError = ""; _iLastError = SPKERR_NONE; }
        int lastError() const { return _iLastError; }
        const Utils::String lastErrorString() const { return _sLastError; }

        // file handling
        void AddFile ( C_File *file );
        C_File *AddFile(CyString, CyString, int type, int game = 0);
        C_File *addFile(const Utils::String &file, const Utils::String &dir, FileType type, int game = 0);
        C_File *AppendFile ( CyString file, int type, int game, CyString dir = NullString, CProgressInfo *progress = NULL );
        C_File *FindFile ( CyString, int, CyString = NullString, int game = 0 );
        bool AddFileNow ( CyString, CyString, int type, CProgressInfo *progress = NULL );
        int CountFiles ( int filetype );
        C_File *FindFileAt ( int filetype, int pos );
        virtual bool RemoveFile ( int pos );
        virtual bool RemoveFile ( C_File *files );
        virtual bool RemoveFile ( CyString file, int type, CyString dir = NullString, int game = 0 );
        void removeAllFiles(FileType type, int game);
        CyString CreateFilesLine ( bool updateheader, CProgressInfo * = NULL );

        virtual bool WriteHeader(CFileIO &file, int iHeader, int iLength);
        virtual bool WriteData(CFileIO &file, CProgressInfo * = NULL );
        virtual bool WriteFile ( CyString filename, CProgressInfo * = NULL );
        virtual bool ReadFile(CyString filename, int readType = SPKREAD_ALL, CProgressInfo *progress = NULL);
        virtual bool readFile(const Utils::String &filename, int readType = SPKREAD_ALL, CProgressInfo *progress = NULL);
        bool readFile(CFileIO &File, int readtype, CProgressInfo *progress);

        virtual bool ExtractFile(C_File *file, CyString dir, bool includedir = true, CProgressInfo *progress = NULL);
        virtual bool ExtractFile(int file, CyString dir, bool includedir = true, CProgressInfo *progress = NULL);
        virtual bool extractFile(int file, const Utils::String &dir, bool includedir = true, CProgressInfo *progress = NULL);
        virtual bool extractFile(C_File *file, const Utils::String &dir, bool includedir = true, CProgressInfo *progress = NULL);
        virtual bool extractFile(int filenum, const Utils::String &dir, unsigned int game, const Utils::CStringList &gameAddons, bool includedir = true, CProgressInfo *progress = NULL);
        virtual bool extractFile(C_File *file, const Utils::String &dir, unsigned int game, const Utils::CStringList &gameAddons, bool includedir = true, CProgressInfo *progress = NULL);
        virtual bool extractAll(const Utils::String &dir, int game, const Utils::CStringList &gameAddons, bool includedir = true, CProgressInfo *progress = NULL);

        virtual bool SaveToArchive(CyString filename, int game, const CGameExe *exes, CProgressInfo *progress = NULL);
        virtual bool saveToArchive(const Utils::String &filename, int game, const CGameExe *exes, CProgressInfo *progress = NULL);
        virtual void addGeneratedFiles(HZIP &hz) {};

        void ClearFileData();

        CLinkList<SNames> *GetNamesList() { return &m_lNames; }

        // reading files
        void ReadAllFilesToMemory ();
        void ReadIconFileToMemory ();
        bool ReadFileToMemory(C_File *f);

        // compression
        void RecompressAllFiles ( int compresstype, CProgressInfo *progress );
        void CompressAllFiles ( int compresstype, CProgressInfo *progress = NULL, CProgressInfo *overallProgress = NULL, int level = DEFAULT_COMPRESSION_LEVEL );
        bool UncompressAllFiles ( CProgressInfo * = NULL );

        // static functions
        static CyString GetEndOfLine ( FILE *id, int *line = NULL, bool upper = true );
        static int CheckFile ( CyString filename, float *version = NULL );

        bool IsFileAdded(C_File *f) { return m_lFiles.FindData(f); }

        // installing
        void SwitchFilePointer(C_File *oldFile, C_File *newFile);
        bool InstallFiles ( CyString destdir, CProgressInfo *progress, CLinkList<C_File> *spklist, CyStringList *errorStr, bool enabled = true, CPackages *packages = NULL );
        virtual bool IsPatch () { return false; }

        // installer functions
        bool IsProfileEnabled () { return m_bProfile; }
        bool IsEnabled () { return m_bEnable; }
        bool IsModifiedEnabled () { return m_bModifiedEnabled; }
        bool IsGlobalEnabled () { return m_bGlobal; }

        void SetProfileEnabled ( bool en ) { m_bProfile = en; }
        void SetEnabled ( bool en ) { m_bEnable = en; }
        void SetModifiedEnabled ( bool en ) { m_bModifiedEnabled = en; }
        void SetGlobalEnabled ( bool en ) { m_bGlobal = en; }

        int  GetLoadError() { return m_iLoadError; }
        void SetLoadError(int i) { m_iLoadError = i; }
        Utils::String createUpdateFile(const Utils::String &dir) const;

        // language functions
        void RemoveLanguageName ( int lang );
        void AddLanguageName ( int lang, const Utils::String &name );
        void ClearNames ();

        virtual bool ParseValueLine(const Utils::String &line);

        CLinkList<SGameCompat>  *GetGameCompatabilityList() { return &m_lGames; }

        CyString GetFullFileSizeString();

        CLinkList<SNeededLibrary> *GetNeededLibraries() { return &m_lNeededLibrarys; }
        void AddNeededLibrary(const Utils::String &scriptName, const Utils::String &author, const Utils::String &minVersion);
        bool IsPackageNeeded(const Utils::String &scriptName, const Utils::String &author);
        SNeededLibrary *FindPackageNeeded(const Utils::String &scriptName, const Utils::String &author);
        void RemovePackageNeeded(const Utils::String &scriptName, const Utils::String &author);
        void ClearNeededPackages();
        bool AnyDependacies() { return (m_lNeededLibrarys.size()) ? true: false; }
        bool AutoGenerateUpdateFile() { return m_bAutoGenerateUpdateFile; }
        void RemoveFakePatchOrder(bool after, CyString scriptName, CyString author);
        void RemoveFakePatchOrder(CyString scriptName, CyString author);
        void AddFakePatchOrder(bool after, CyString scriptName, CyString author);
        bool AnyFakePatchOrder() { if ( !m_lFakePatchBefore.Empty() || !m_lFakePatchAfter.Empty() ) return true; return false; }
        CyStringList &GetFakePatchBeforeOrder() { return m_lFakePatchBefore; }
        CyStringList &GetFakePatchAfterOrder() { return m_lFakePatchAfter; }
        void updateTextDB() { this->_resetTextDB(); }

        virtual bool readWares(int iLang, CLinkList<SWareEntry> &list, const Utils::String &empWares);
        virtual bool readCommands(int iLang, CLinkList<SCommandSlot> &list);
        virtual bool readWingCommands(int iLang, CLinkList<SCommandSlot> &list);

//      bool IsChanged() { return m_bChanged; }
//      void SetChanged(bool b) { m_bChanged = b; }

        int  FindFirstGameInPackage();
        bool IsAnyGameInPackage();
        bool IsMultipleGamesInPackage();
        bool IsGameInPackage(int game);

        virtual int GetType () { return TYPE_BASE; }
        bool AnyFileType ( int type );
        CBaseFile *GetParent () { return m_pParent; }
        void SetParent ( CBaseFile *file ) { m_pParent = file; }
        int ParseLanguage(const Utils::String &lang) const;

        virtual bool UpdateSigned (bool updateFiles);
        int GetNum() { return m_iNum; }
        void SetNum(int i) { m_iNum = i; }

        bool    IsFullyLoaded() { return m_bFullyLoaded; }
        virtual bool   IsSigned ()              { return m_bSigned;}
        void SetOverrideFiles(bool b) { m_bOverrideFiles = b; }
        bool IsUpdateChecked () { return m_bUpdate; }
        void SetUpdateChecked ( bool en ) { m_bUpdate = en; }

        unsigned char *CreateData(size_t *size, CProgressInfo *progress = NULL);

protected:
        virtual void Delete ();
        virtual void SetDefaults ();

        // reading of files
        virtual bool CheckHeader(const Utils::String header) const;
        virtual bool ParseHeader ( CyString header );
        virtual bool ParseFileHeader ( CyString header );
        virtual bool ParseFilesLine ( CyString line );
        virtual void ReadValues ( CyString values );
        virtual void ReadFiles ( CyString values );

        void _install_adjustFakePatches(CPackages *pPackages);
        void _install_renameText(CPackages *pPackages);
        bool _install_uncompress(C_File *fit, CProgressInfo *progress, CyStringList *errorStr, bool *uncomprToFile);
        bool _install_setEnabled(bool bEnable, C_File *fit);
        bool _install_checkVersion(C_File *pFile, const Utils::String &sDestination);
        Utils::String _install_adjustFilepointer(C_File *pFile, bool bEnabled, const Utils::String &sDestination);
        C_File *_install_checkFile(C_File *pFile, CyStringList *errorStr, bool *bDoFile, CLinkList<C_File> *pFileList);
        bool _install_checkFileEnable(C_File *pCheckFile, C_File *fit, const Utils::String &sDestination, bool bEnabled, CyStringList *errorStr);
        bool _install_createDirectory(CDirIO &Dir, const Utils::String &sTo, C_File *pFile, CyStringList *errorStr);
        void _install_writeFile(C_File *pFile, const Utils::String &sDestination, CyStringList *errorStr);

        int _read_FileHeader(CFileIO &File, int iReadType, int iMaxProgress, int iDoneLen, CProgressInfo *pProgress);
        int _read_Header(CFileIO &File, int iReadType, int iMaxProgress, CProgressInfo *pProgress);
        CFileIO *_startRead();

        void _addFile(C_File *file, bool dontChange = false);
        void _updateTextDB(C_File *file);
        void _resetTextDB();
        void _addWaresToList(int iLang, CLinkList<SWareEntry> &list, const Utils::String &wares, enum WareTypes eType);
        bool _readCommands(int iLang, int iStartID, CLinkList<SCommandSlot> &list);
        Utils::String _replaceFilename(const Utils::String &fname);

protected:
        SSPKHeader m_SHeader;
        SSPKHeader2 m_SHeader2;

        C_File *m_pIconFile;
        CyString m_sIconExt;
        Utils::String _sLastError;
        int _iLastError;

        CLinkList<C_File>  m_lFiles;
        CLinkList<SNames> m_lNames;                     //TODO: move to CorePackage
        CyStringList m_lMirrors;                        //TODO: move to CorePackage
        CyStringList m_lFakePatchBefore;
        CyStringList m_lFakePatchAfter;

        CTextDB *_pTextDB;

        CLinkList<SGameCompat> m_lGames;

        bool m_bSigned;
        bool m_bFullyLoaded;

        //installer varibles
        bool m_bEnable;
        bool m_bModifiedEnabled;
        bool m_bGlobal;
        bool m_bProfile;
        int m_iLoadError;

        CBaseFile *m_pParent;

        int m_iNum;

        CLinkList<SNeededLibrary> m_lNeededLibrarys;

        bool    _bCombineFiles;
        bool    m_bOverrideFiles;
        CyString        m_sFtpAddr;
        bool    m_bAutoGenerateUpdateFile;
        bool m_bUpdate;
};


class SPKEXPORT CArchiveFile : public CBaseFile
{
public:
        CArchiveFile();
        virtual ~CArchiveFile();
        virtual CyString GetFullPackageName(CyString format, int lang) { return CyString("Archive(") + this->name() + ")"; }
        virtual CyString GetFullPackageName(int language, CyString byString) { return CyString("Archive(") + this->name() + ")"; }
        virtual CyString GetFullPackageName(int language, bool includeVersion = true, CyString byString = "by") { return CyString("Archive(") + this->name() + ")"; }
        virtual int GetType () { return TYPE_ARCHIVE; }
};

#endif //__BASEFILE_H__