diff options
-rw-r--r-- | inc/common/error.h | 1 | ||||
-rw-r--r-- | src/client/client.h | 5 | ||||
-rw-r--r-- | src/client/download.c | 97 | ||||
-rw-r--r-- | src/client/http.c | 3 | ||||
-rw-r--r-- | src/client/main.c | 4 |
5 files changed, 109 insertions, 1 deletions
diff --git a/inc/common/error.h b/inc/common/error.h index 2a9702e..e1ed1ea 100644 --- a/inc/common/error.h +++ b/inc/common/error.h @@ -70,6 +70,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define Q_ERR_MFILE Q_ERR(EMFILE) #define Q_ERR_EXIST Q_ERR(EEXIST) #define Q_ERR_BADF Q_ERR(EBADF) +#define Q_ERR_PERM Q_ERR(EPERM) #define Q_PrintError(what, code) \ Com_Printf("Couldn't %s: %s\n", what, Q_ErrorString(code)) diff --git a/src/client/client.h b/src/client/client.h index 7d9fcb7..070274f 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -408,7 +408,8 @@ typedef struct client_static_s { dlqueue_t *current; // path being downloaded int percent; // how much downloaded qhandle_t file; // UDP file transfer from server - char temp[MAX_QPATH + 4]; // account 4 bytes for .tmp suffix + char temp[MAX_QPATH + 4];// account 4 bytes for .tmp suffix + string_entry_t *ignores; // list of ignored paths } download; // demo recording info must be here, so it isn't cleared on level change @@ -565,8 +566,10 @@ void CL_UpdateConfigstring(int index); // download.c // qerror_t CL_QueueDownload(const char *path, dltype_t type); +qboolean CL_IgnoreDownload(const char *path); void CL_FinishDownload(dlqueue_t *q); void CL_CleanupDownloads(void); +void CL_LoadDownloadIgnores(void); void CL_HandleDownload(const byte *data, int size, int percent); qboolean CL_CheckDownloadExtension(const char *ext); void CL_StartNextDownload(void); diff --git a/src/client/download.c b/src/client/download.c index f7e4dc5..fd9df7c 100644 --- a/src/client/download.c +++ b/src/client/download.c @@ -24,6 +24,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "format/md2.h" #include "format/sp2.h" +#define CL_DOWNLOAD_IGNORES "download-ignores.txt" + typedef enum { PRECACHE_MODELS, PRECACHE_OTHER, @@ -84,6 +86,27 @@ qerror_t CL_QueueDownload(const char *path, dltype_t type) /* =============== +CL_IgnoreDownload + +Returns true if specified path matches against an entry in download ignore +list. +=============== +*/ +qboolean CL_IgnoreDownload(const char *path) +{ + string_entry_t *entry; + + for (entry = cls.download.ignores; entry; entry = entry->next) { + if (Com_WildCmp(entry->string, path)) { + return qtrue; + } + } + + return qfalse; +} + +/* +=============== CL_FinishDownload Mark the queue entry as done, decrementing pending count. @@ -134,6 +157,77 @@ void CL_CleanupDownloads(void) cls.download.temp[0] = 0; } +/* +=============== +CL_LoadDownloadIgnores + +Allow mods to provide a list of paths that are known to be non-existent and +should never be downloaded (e.g. model specific sounds). +=============== +*/ +void CL_LoadDownloadIgnores(void) +{ + string_entry_t *entry, *next; + char *raw, *data, *p; + int count, line; + ssize_t len; + + // free previous entries + for (entry = cls.download.ignores; entry; entry = next) { + next = entry->next; + Z_Free(entry); + } + + cls.download.ignores = NULL; + + // load new list + len = FS_LoadFile(CL_DOWNLOAD_IGNORES, (void **)&raw); + if (!raw) { + if (len != Q_ERR_NOENT) + Com_EPrintf("Couldn't load %s: %s\n", + CL_DOWNLOAD_IGNORES, Q_ErrorString(len)); + return; + } + + count = 0; + line = 1; + data = raw; + + while (*data) { + p = strchr(data, '\n'); + if (p) { + if (p > data && *(p - 1) == '\r') + *(p - 1) = 0; + *p = 0; + } + + // ignore empty lines and comments + if (*data && *data != '#' && *data != '/') { + len = strlen(data); + if (len < MAX_QPATH) { + entry = Z_Malloc(sizeof(*entry) + len); + memcpy(entry->string, data, len + 1); + entry->next = cls.download.ignores; + cls.download.ignores = entry; + count++; + } else { + Com_WPrintf("Oversize filter on line %d in %s\n", + line, CL_DOWNLOAD_IGNORES); + } + } + + if (!p) + break; + + data = p + 1; + line++; + } + + Com_DPrintf("Loaded %d filters from %s\n", count, CL_DOWNLOAD_IGNORES); + + FS_FreeFile(raw); +} + // start legacy UDP download static qboolean start_download(dlqueue_t *q) { @@ -355,6 +449,9 @@ static qerror_t check_file_len(const char *path, size_t len, dltype_t type) // convert to lower case to make download server happy Q_strlwr(buffer); + if (CL_IgnoreDownload(buffer)) + return Q_ERR_PERM; + ret = HTTP_QueueDownload(buffer, type); if (ret != Q_ERR_NOSYS) return ret; diff --git a/src/client/http.c b/src/client/http.c index 82d5fbe..5b480e5 100644 --- a/src/client/http.c +++ b/src/client/http.c @@ -652,6 +652,9 @@ static void check_and_queue_download(char *path) if (valid == PATH_MIXED_CASE) Q_strlwr(path); + if (CL_IgnoreDownload(path)) + return; + CL_QueueDownload(path, type); } diff --git a/src/client/main.c b/src/client/main.c index 5c605c2..dbcf870 100644 --- a/src/client/main.c +++ b/src/client/main.c @@ -2347,6 +2347,8 @@ void CL_RestartFilesystem(qboolean total) CL_LoadState(LOAD_FINISH); } + CL_LoadDownloadIgnores(); + // switch back to original state cls.state = cls_state; @@ -3287,6 +3289,8 @@ void CL_Init(void) } #endif + CL_LoadDownloadIgnores(); + HTTP_Init(); UI_OpenMenu(UIMENU_DEFAULT); |