Subversion Repositories spk

Rev

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

#pragma once

#include "CyString.h"
#include "VirtualFileSystem.h"
#include "lists.h"
#include "StringList.h"

using namespace SPK;

class CCatFile;

enum {DIFFTYPE_ADDITION, DIFFTYPE_REMOVAL, DIFFTYPE_CHANGE};

tstruct SDiffEntry {
        int                     iType;
        int                     iID;
} SDiffEntry;

tstruct SDiffEntryAddition : SDiffEntry {
        Utils::String   sEntry;
        SDiffEntryAddition() { iType = DIFFTYPE_ADDITION; }
} SDiffEntryAddition;

tstruct SDiffEntryRemoval : SDiffEntry {
        SDiffEntryRemoval() { iType = DIFFTYPE_REMOVAL; }
} SDiffEntryRemoval;

tstruct SDiffEntryChange : SDiffEntry {
        SDiffEntryChange() { iType = DIFFTYPE_CHANGE; }
        int                     iPos;
        Utils::String   sFrom;
        Utils::String   sEntry;
} SDiffEntryChange;

tstruct SDiffFile {
        Utils::String sFile;
        CLinkList<SDiffEntry> m_lEntries;
} SDiffFile;

enum {MDERR_NONE, MDERR_FILENOTFOUND, MDERR_CANTOPEN, MDERR_CANTOPENMOD};

tclass CModDiff
{
private:
        enum {
                MERGETYPE_NONE,
                MERGETYPE_TSHIPS,
        };

public:
        // static
        static bool CanBeDiffed(const Utils::String &file);

        // constructors
        CModDiff(const Utils::String &dir, const Utils::String &sAddon, int maxPatch = 0);
        ~CModDiff(void);

        // public functions
        void SetTempDirectory(const Utils::String &temp) { m_sTempDir = temp; }
        bool LoadDirectory(const Utils::String &dir);
        bool IsLoaded() { return m_bLoaded; }
        const Utils::String &GetDirectory() const { return m_sCurrentDir; }
        bool CreateDiff(const Utils::String &mod);
        bool startDiff(const Utils::String &sModFile);
        bool doDiff(const Utils::String &sModFile);
        SDiffFile *diffFile(const Utils::String &baseFile, const  Utils::String &modFile, const Utils::String &fileType);
        void Clean();
        bool WriteDiff(const Utils::String &file);
        bool ReadDiff(const Utils::String &file);
        bool ApplyDiff(const Utils::String &mod);
        bool ApplyMod(const Utils::String &mod);
        void SetMaxPatch(int patch) { m_iMaxPatch = patch; }

        CLinkList<SDiffFile> &GetDiffFiles() { return m_lFiles; }

        void ClearError() { m_iError = MDERR_NONE; }
        int Error() { return m_iError; }

private:
        // private functions
        int _amountPosition(const Utils::String &fileType);
        bool _isLineComplete(const Utils::String &line, const Utils::String &fileType, bool first);
        bool _readGameFile(const Utils::String &file, CyStringList *lines, int *id);
        void _compareLine(const Utils::String &line1, const Utils::String &line2, int type, int id, SDiffFile *diffFile);
        bool _validFile(const Utils::String &file);

        void _adjustFile(const Utils::String &sFile, SDiffFile *pDiff, bool bReverse);
        bool _adjustTShips(SDiffFile *pDiff, bool bReserve);
        int _specialType(const Utils::String &sFile);
        Utils::String _extractFile(const Utils::String &sFile, const Utils::String &sTo);

        // Variables
        Utils::String m_sAddon;
        Utils::String m_sCurrentDir;            // the current game directory (that the VFS is opened too)
        Utils::String m_sTempDir;                               // temporary dir (used to write temporary files to)

        CVirtualFileSystem m_fileSystem;        // the VFS of the game directory (for finding the files to use)
        CLinkList<SDiffFile> m_lFiles;          // list of files that have changed

        bool    m_bLoaded;                                      // if the directory is loaded and ready to be diffed
        int             m_iError;                                       // error id of process
        int             m_iMaxPatch;                            // The max fake patch to check to

        CCatFile                *m_pCatFile;
};