diff options
| author | oy <Tom_Adams@web.de> | 2010-10-06 23:07:35 +0200 |
|---|---|---|
| committer | oy <Tom_Adams@web.de> | 2010-10-06 23:07:35 +0200 |
| commit | 3a98f7a048c044ce0d870320fc0b1def0db4f7fb (patch) | |
| tree | 7dfa1826e537355b37d00e77558ca623a915bac2 /src/engine/shared/storage.cpp | |
| parent | a62a7413d1ff25c8e07657b96a485f001004619a (diff) | |
| download | zcatch-3a98f7a048c044ce0d870320fc0b1def0db4f7fb.tar.gz zcatch-3a98f7a048c044ce0d870320fc0b1def0db4f7fb.zip | |
added mod system. Closes #34
Diffstat (limited to 'src/engine/shared/storage.cpp')
| -rw-r--r-- | src/engine/shared/storage.cpp | 290 |
1 files changed, 187 insertions, 103 deletions
diff --git a/src/engine/shared/storage.cpp b/src/engine/shared/storage.cpp index 8785a5bf..cfe64e4b 100644 --- a/src/engine/shared/storage.cpp +++ b/src/engine/shared/storage.cpp @@ -3,6 +3,7 @@ #include <base/system.h> #include <engine/storage.h> #include "engine.h" +#include "linereader.h" // compiled-in data-dir path #define DATA_DIR "data" @@ -10,36 +11,29 @@ class CStorage : public IStorage { public: - char m_aApplicationSavePath[512]; - char m_aDatadir[512]; + enum + { + MAX_PATHS = 16, + MAX_PATH_LENGTH = 512 + }; + + char m_aaStoragePaths[MAX_PATHS][MAX_PATH_LENGTH]; + int m_NumPaths; + char m_aDatadir[MAX_PATH_LENGTH]; + char m_aUserdir[MAX_PATH_LENGTH]; CStorage() { - m_aApplicationSavePath[0] = 0; + mem_zero(m_aaStoragePaths, sizeof(m_aaStoragePaths)); + m_NumPaths = 0; m_aDatadir[0] = 0; + m_aUserdir[0] = 0; } int Init(const char *pApplicationName, int NumArgs, const char **ppArguments) { - char aPath[1024] = {0}; - fs_storage_path(pApplicationName, m_aApplicationSavePath, sizeof(m_aApplicationSavePath)); - if(fs_makedir(m_aApplicationSavePath) == 0) - { - str_format(aPath, sizeof(aPath), "%s/screenshots", m_aApplicationSavePath); - fs_makedir(aPath); - - str_format(aPath, sizeof(aPath), "%s/maps", m_aApplicationSavePath); - fs_makedir(aPath); - - str_format(aPath, sizeof(aPath), "%s/dumps", m_aApplicationSavePath); - fs_makedir(aPath); - - str_format(aPath, sizeof(aPath), "%s/downloadedmaps", m_aApplicationSavePath); - fs_makedir(aPath); - - str_format(aPath, sizeof(aPath), "%s/demos", m_aApplicationSavePath); - fs_makedir(aPath); - } + // get userdir + fs_storage_path(pApplicationName, m_aUserdir, sizeof(m_aUserdir)); // check for datadir override for(int i = 1; i < NumArgs; i++) @@ -50,54 +44,160 @@ public: break; } } - - return FindDatadir(ppArguments[0]); + // get datadir + FindDatadir(ppArguments[0]); + + // load paths from storage.cfg + LoadPaths(ppArguments[0]); + + if(!m_NumPaths) + { + dbg_msg("storage", "using standard paths"); + AddDefaultPaths(); + } + + // add save directories + if(m_NumPaths && (!m_aaStoragePaths[TYPE_SAVE][0] || !fs_makedir(m_aaStoragePaths[TYPE_SAVE]))) + { + char aPath[MAX_PATH_LENGTH]; + fs_makedir(GetPath(TYPE_SAVE, "screenshots", aPath, sizeof(aPath))); + fs_makedir(GetPath(TYPE_SAVE, "maps", aPath, sizeof(aPath))); + fs_makedir(GetPath(TYPE_SAVE, "dumps", aPath, sizeof(aPath))); + fs_makedir(GetPath(TYPE_SAVE, "downloadedmaps", aPath, sizeof(aPath))); + fs_makedir(GetPath(TYPE_SAVE, "demos", aPath, sizeof(aPath))); + } + + return m_NumPaths ? 0 : 1; + } + + void LoadPaths(const char *pArgv0) + { + // check current directory + IOHANDLE File = io_open("storage.cfg", IOFLAG_READ); + if(!File) + { + // check usable path in argv[0] + unsigned int Pos = ~0U; + for(unsigned i = 0; pArgv0[i]; i++) + if(pArgv0[i] == '/' || pArgv0[i] == '\\') + Pos = i; + if(Pos < MAX_PATH_LENGTH) + { + char aBuffer[MAX_PATH_LENGTH]; + str_copy(aBuffer, pArgv0, Pos+1); + str_append(aBuffer, "/storage.cfg", sizeof(aBuffer)); + File = io_open(aBuffer, IOFLAG_READ); + } + + if(Pos >= MAX_PATH_LENGTH || !File) + { + dbg_msg("storage", "couldn't open storage.cfg"); + return; + } + } + + char *pLine; + CLineReader LineReader; + LineReader.Init(File); + + while((pLine = LineReader.Get())) + { + if(str_length(pLine) > 9 && !str_comp_num(pLine, "add_path ", 9)) + AddPath(pLine+9); + } + + io_close(File); + + if(!m_NumPaths) + dbg_msg("storage", "no paths found in storage.cfg"); + } + + void AddDefaultPaths() + { + AddPath("$USERDIR"); + AddPath("$DATADIR"); + AddPath("$CURRENTDIR"); + } + + void AddPath(const char *pPath) + { + if(m_NumPaths >= MAX_PATHS || !pPath[0]) + return; + + int OldNum = m_NumPaths; + + if(!str_comp(pPath, "$USERDIR")) + { + if(m_aUserdir[0]) + str_copy(m_aaStoragePaths[m_NumPaths++], m_aUserdir, MAX_PATH_LENGTH); + } + else if(!str_comp(pPath, "$DATADIR")) + { + if(m_aDatadir[0]) + str_copy(m_aaStoragePaths[m_NumPaths++], m_aDatadir, MAX_PATH_LENGTH); + } + else if(!str_comp(pPath, "$CURRENTDIR")) + { + m_aaStoragePaths[m_NumPaths++][0] = 0; + } + else + { + if(fs_is_dir(pPath)) + str_copy(m_aaStoragePaths[m_NumPaths++], pPath, MAX_PATH_LENGTH); + } + + if(OldNum != m_NumPaths) + dbg_msg("storage", "added path '%s'", pPath); } - int FindDatadir(const char *pArgv0) + void FindDatadir(const char *pArgv0) { // 1) use provided data-dir override if(m_aDatadir[0]) { - if(fs_is_dir(m_aDatadir)) - return 0; - else + char aBuffer[MAX_PATH_LENGTH]; + str_format(aBuffer, sizeof(aBuffer), "%s/mapres", m_aDatadir); + if(!fs_is_dir(aBuffer)) { - dbg_msg("engine/datadir", "specified data-dir '%s' does not exist", m_aDatadir); - return -1; + dbg_msg("storage", "specified data directory '%s' does not exist", m_aDatadir); + m_aDatadir[0] = 0; } + else + return; } // 2) use data-dir in PWD if present if(fs_is_dir("data/mapres")) { str_copy(m_aDatadir, "data", sizeof(m_aDatadir)); - return 0; + return; } // 3) use compiled-in data-dir if present - if (fs_is_dir(DATA_DIR "/mapres")) + if(fs_is_dir(DATA_DIR "/mapres")) { str_copy(m_aDatadir, DATA_DIR, sizeof(m_aDatadir)); - return 0; + return; } // 4) check for usable path in argv[0] { unsigned int Pos = ~0U; for(unsigned i = 0; pArgv0[i]; i++) - if(pArgv0[i] == '/') + if(pArgv0[i] == '/' || pArgv0[i] == '\\') Pos = i; - if (Pos < sizeof(m_aDatadir)) + if(Pos < MAX_PATH_LENGTH) { - char aBaseDir[sizeof(m_aDatadir)]; - str_copy(aBaseDir, pArgv0, Pos); - aBaseDir[Pos] = '\0'; + char aBaseDir[MAX_PATH_LENGTH]; + str_copy(aBaseDir, pArgv0, Pos+1); str_format(m_aDatadir, sizeof(m_aDatadir), "%s/data", aBaseDir); + str_append(aBaseDir, "/data/mapres", sizeof(aBaseDir)); - if (fs_is_dir(m_aDatadir)) - return 0; + if(fs_is_dir(aBaseDir)) + return; + else + m_aDatadir[0] = 0; } } @@ -105,11 +205,11 @@ public: // 5) check for all default locations { const char *aDirs[] = { - "/usr/share/teeworlds/data", - "/usr/share/games/teeworlds/data", - "/usr/local/share/teeworlds/data", - "/usr/local/share/games/teeworlds/data", - "/opt/teeworlds/data" + "/usr/share/teeworlds/data/mapres", + "/usr/share/games/teeworlds/data/mapres", + "/usr/local/share/teeworlds/data/mapres", + "/usr/local/share/games/teeworlds/data/mapres", + "/opt/teeworlds/data/mapres" }; const int DirsCount = sizeof(aDirs) / sizeof(aDirs[0]); @@ -119,55 +219,41 @@ public: if (fs_is_dir(aDirs[i])) { str_copy(m_aDatadir, aDirs[i], sizeof(m_aDatadir)); - return 0; + return; } } } #endif // no data-dir found - dbg_msg("engine/datadir", "warning no data directory found"); - return -1; + dbg_msg("storage", "warning no data directory found"); } - virtual void ListDirectory(int Types, const char *pPath, FS_LISTDIR_CALLBACK pfnCallback, void *pUser) + virtual void ListDirectory(int Type, const char *pPath, FS_LISTDIR_CALLBACK pfnCallback, void *pUser) { - char aBuffer[1024]; - - // list current directory - if(Types&TYPE_CURRENT) + char aBuffer[MAX_PATH_LENGTH]; + if(Type == TYPE_ALL) { - fs_listdir(pPath, pfnCallback, TYPE_CURRENT, pUser); + // list all available directories + for(int i = 0; i < m_NumPaths; ++i) + fs_listdir(GetPath(i, pPath, aBuffer, sizeof(aBuffer)), pfnCallback, i, pUser); } - - // list users directory - if(Types&TYPE_SAVE) + else if(Type >= 0 && Type < m_NumPaths) { - str_format(aBuffer, sizeof(aBuffer), "%s/%s", m_aApplicationSavePath, pPath); - fs_listdir(aBuffer, pfnCallback, TYPE_SAVE, pUser); + // list wanted directory + fs_listdir(GetPath(Type, pPath, aBuffer, sizeof(aBuffer)), pfnCallback, Type, pUser); } - - // list datadir directory - if(Types&TYPE_DATA) - { - str_format(aBuffer, sizeof(aBuffer), "%s/%s", m_aDatadir, pPath); - fs_listdir(aBuffer, pfnCallback, TYPE_DATA, pUser); - } } - virtual const char *GetDirectory(int Type) const + const char *GetPath(int Type, const char *pDir, char *pBuffer, unsigned BufferSize) { - switch(Type) - { - case TYPE_SAVE: return m_aApplicationSavePath; - case TYPE_DATA: return m_aDatadir; - default: return ""; - } + str_format(pBuffer, BufferSize, "%s%s%s", m_aaStoragePaths[Type], !m_aaStoragePaths[Type][0] ? "" : "/", pDir); + return pBuffer; } - virtual IOHANDLE OpenFile(const char *pFilename, int Flags, char *pBuffer = 0, int BufferSize = 0) + virtual IOHANDLE OpenFile(const char *pFilename, int Flags, int Type, char *pBuffer = 0, int BufferSize = 0) { - char aBuffer[1024]; + char aBuffer[MAX_PATH_LENGTH]; if(!pBuffer) { pBuffer = aBuffer; @@ -176,45 +262,42 @@ public: if(Flags&IOFLAG_WRITE) { - str_format(pBuffer, BufferSize, "%s/%s", m_aApplicationSavePath, pFilename); - return io_open(pBuffer, Flags); + return io_open(GetPath(TYPE_SAVE, pFilename, pBuffer, BufferSize), Flags); } else { IOHANDLE Handle = 0; - - // check current directory - Handle = io_open(pFilename, Flags); - if(Handle) - return Handle; - - // check user directory - str_format(pBuffer, BufferSize, "%s/%s", m_aApplicationSavePath, pFilename); - Handle = io_open(pBuffer, Flags); - if(Handle) - return Handle; - - // check normal data directory - str_format(pBuffer, BufferSize, "%s/%s", m_aDatadir, pFilename); - Handle = io_open(pBuffer, Flags); - if(Handle) - return Handle; + + if(Type == TYPE_ALL) + { + // check all available directories + for(int i = 0; i < m_NumPaths; ++i) + { + Handle = io_open(GetPath(i, pFilename, pBuffer, BufferSize), Flags); + if(Handle) + return Handle; + } + } + else if(Type >= 0 && Type < m_NumPaths) + { + // check wanted directory + Handle = io_open(GetPath(Type, pFilename, pBuffer, BufferSize), Flags); + if(Handle) + return Handle; + } } pBuffer[0] = 0; return 0; } - virtual bool RemoveFile(const char *pFilename) + virtual bool RemoveFile(const char *pFilename, int Type) { - char aBuffer[1024]; - str_format(aBuffer, sizeof(aBuffer), "%s/%s", m_aApplicationSavePath, pFilename); - bool Fail = remove(aBuffer); - - if(Fail) - Fail = remove(pFilename); - - return !Fail; + if(Type < 0 || Type >= m_NumPaths) + return false; + + char aBuffer[MAX_PATH_LENGTH]; + return remove(GetPath(Type, pFilename, aBuffer, sizeof(aBuffer))); } static IStorage *Create(const char *pApplicationName, int NumArgs, const char **ppArguments) @@ -222,6 +305,7 @@ public: CStorage *p = new CStorage(); if(p && p->Init(pApplicationName, NumArgs, ppArguments)) { + dbg_msg("storage", "initialisation failed"); delete p; p = 0; } |