summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Nazarov <skuller@skuller.net>2012-12-09 02:41:25 +0400
committerAndrey Nazarov <skuller@skuller.net>2012-12-09 03:08:12 +0400
commitaa21464898b9239fafe148e703bd46a05d65cced (patch)
tree56a6069f493bd599927cb9a006b2e73a406f831d
parent84e0b001e6fe5f79518b17551f07365846d9b756 (diff)
Add download ignore list support.
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).
-rw-r--r--inc/common/error.h1
-rw-r--r--src/client/client.h5
-rw-r--r--src/client/download.c97
-rw-r--r--src/client/http.c3
-rw-r--r--src/client/main.c4
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);