client side of http transfer support (untested)

This commit is contained in:
Bill Currie 2007-03-20 14:16:43 +00:00 committed by Jeff Teunissen
parent 03e5ae136e
commit fa011b55d1
11 changed files with 312 additions and 79 deletions

View file

@ -648,6 +648,8 @@ if test "x$enable_png" != "xno"; then
fi
AC_SUBST(PNG_LIBS)
LIBCURL_CHECK_CONFIG([], [], [CURL=yes], [])
AC_ARG_WITH(ipv6,
[ --with-ipv6=DIR enable IPv6 support. Optional argument specifies
location of inet6 libraries.],
@ -2429,6 +2431,7 @@ AC_MSG_RESULT([
CD Audio system :${CDTYPE- no}
IPv6 networking : $NETTYPE_IPV6
Compression support: gz=$HAVE_ZLIB ogg=$HAVE_VORBIS flac=$HAVE_FLAC png=$HAVE_PNG
HTTP support : ${CURL-no}
Compiler version : $CCVER
Compiler flags : $CFLAGS
qfcc cpp invocation: $CPP_NAME

View file

@ -51,7 +51,7 @@ typedef struct console_func_s {
} console_funcs_t;
typedef struct console_data_s {
const char *dl_name;
struct dstring_s *dl_name;
int *dl_percent;
double *realtime;
double *frametime;

View file

@ -594,10 +594,10 @@ draw_download (view_t *view)
const char *text;
size_t i, j, x, y, n;
if (!con_data.dl_name || !*con_data.dl_name)
if (!con_data.dl_name || !*con_data.dl_name->str)
return;
text = QFS_SkipPath(con_data.dl_name);
text = QFS_SkipPath(con_data.dl_name->str);
x = con_linewidth - ((con_linewidth * 7) / 40);
y = x - strlen (text) - 8;

View file

@ -2,7 +2,7 @@
AUTOMAKE_OPTIONS= foreign
EXTRA_DIST = \
cl_cam.h cl_chat.h cl_demo.h cl_ents.h cl_input.h \
cl_cam.h cl_chat.h cl_demo.h cl_ents.h cl_http.h cl_input.h \
cl_main.h cl_parse.h cl_pred.h cl_skin.h cl_slist.h cl_tent.h \
client.h crudefile.h game.h host.h map_cfg.h server.h sv_gib.h \
sv_demo.h sv_pr_cmds.h sv_pr_qwe.h sv_progs.h sv_qtv.h sv_recorder.h

41
qw/include/cl_http.h Normal file
View file

@ -0,0 +1,41 @@
/*
#FILENAME#
#DESCRIPTION#
Copyright (C) 2007 #AUTHOR#
Author: #AUTHOR#
Date: #DATE#
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id: template.h 11394 2007-03-17 03:23:39Z taniwha $
*/
#ifndef __cl_http_h
#define __cl_http_h
void CL_HTTP_Init (void);
void CL_HTTP_Shutdown (void);
void CL_HTTP_StartDownload (void);
void CL_HTTP_Update (void);
void CL_HTTP_Reset (void);
#endif//__cl_http_h

View file

@ -55,6 +55,7 @@ void CL_NewTranslation (int slot, struct skin_s *skin);
qboolean CL_CheckOrDownloadFile (const char *filename);
qboolean CL_IsUploading(void);
void CL_NextUpload(void);
void CL_FinishDownload (void);
void CL_StartUpload (byte *data, int size);
void CL_StopUpload(void);

View file

@ -152,8 +152,9 @@ typedef struct
// file transfer from server
QFile *download;
char downloadtempname[MAX_OSPATH];
char downloadname[MAX_OSPATH];
struct dstring_s *downloadtempname;
struct dstring_s *downloadname;
struct dstring_s *downloadurl;
int downloadnumber;
dltype_t downloadtype;
int downloadpercent;

View file

@ -117,7 +117,7 @@ client_libs= libqw_client.a libqw_common.a
libqw_client_a_SOURCES= \
cl_cam.c cl_chat.c cl_cmd.c cl_cvar.c cl_demo.c cl_ents.c \
cl_input.c cl_main.c cl_ngraph.c cl_parse.c cl_pred.c \
cl_http.c cl_input.c cl_main.c cl_ngraph.c cl_parse.c cl_pred.c \
cl_screen.c cl_skin.c cl_slist.c cl_tent.c cl_view.c \
locs.c sbar.c skin.c teamplay.c
@ -135,7 +135,7 @@ qw_client_fbdev_libs= \
$(top_builddir)/libs/video/targets/libQFfbdev.la \
$(client_LIBS)
qw_client_fbdev_SOURCES= cl_sys_unix.c
qw_client_fbdev_LDADD= $(qw_client_fbdev_libs) $(NET_LIBS)
qw_client_fbdev_LDADD= $(qw_client_fbdev_libs) $(NET_LIBS) $(LIBCURL)
qw_client_fbdev_LDFLAGS= $(common_ldflags)
qw_client_fbdev_DEPENDENCIES= $(qw_client_fbdev_libs)
@ -147,7 +147,7 @@ qw_client_mgl_libs= \
$(top_builddir)/libs/video/targets/libQFmgl.la \
$(client_LIBS)
qw_client_mgl_SOURCES= cl_sys_win.c
qw_client_mgl_LDADD= $(qw_client_mgl_libs) $(MGL_LIBS) $(NET_LIBS)
qw_client_mgl_LDADD= $(qw_client_mgl_libs) $(MGL_LIBS) $(NET_LIBS) $(LIBCURL)
qw_client_mgl_LDFLAGS= $(common_ldflags)
qw_client_mgl_DEPENDENCIES= $(qw_client_mgl_libs)
@ -160,7 +160,7 @@ qw_client_sdl_libs= \
$(top_builddir)/libs/video/targets/libQFsdl.la \
$(client_LIBS)
qw_client_sdl_SOURCES=sdl_link.c
qw_client_sdl_LDADD= libqw_sdl.a $(qw_client_sdl_libs) $(SDL_LIBS) $(NET_LIBS)
qw_client_sdl_LDADD= libqw_sdl.a $(qw_client_sdl_libs) $(SDL_LIBS) $(NET_LIBS) $(LIBCURL)
qw_client_sdl_LDFLAGS= $(common_ldflags)
qw_client_sdl_DEPENDENCIES= libqw_sdl.a $(qw_client_sdl_libs)
@ -174,7 +174,7 @@ qw_client_sdl32_libs= \
$(top_builddir)/libs/video/targets/libQFsdl32.la \
$(client_LIBS)
qw_client_sdl32_SOURCES=sdl_link.c
qw_client_sdl32_LDADD= libqw_sdl.a $(qw_client_sdl32_libs) $(SDL_LIBS) $(NET_LIBS)
qw_client_sdl32_LDADD= libqw_sdl.a $(qw_client_sdl32_libs) $(SDL_LIBS) $(NET_LIBS) $(LIBCURL)
qw_client_sdl32_LDFLAGS=$(common_ldflags)
qw_client_sdl32_DEPENDENCIES= libqw_sdl.a $(qw_client_sdl32_libs)
@ -186,7 +186,7 @@ qw_client_svga_libs= \
$(top_builddir)/libs/video/targets/libQFsvga.la \
$(client_LIBS)
qw_client_svga_SOURCES= cl_sys_unix.c
qw_client_svga_LDADD= $(qw_client_svga_libs) $(SVGA_LIBS) $(NET_LIBS)
qw_client_svga_LDADD= $(qw_client_svga_libs) $(SVGA_LIBS) $(NET_LIBS) $(LIBCURL)
qw_client_svga_LDFLAGS= $(common_ldflags)
qw_client_svga_DEPENDENCIES= $(qw_client_svga_libs)
@ -200,7 +200,7 @@ qw_client_x11_libs= \
qw_client_x11_SOURCES= cl_sys_unix.c
qw_client_x11_LDADD= $(qw_client_x11_libs) \
$(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 \
$(X_EXTRA_LIBS) $(X_SHM_LIB) $(NET_LIBS)
$(X_EXTRA_LIBS) $(X_SHM_LIB) $(NET_LIBS) $(LIBCURL)
qw_client_x11_LDFLAGS= $(common_ldflags)
qw_client_x11_DEPENDENCIES= $(qw_client_x11_libs)
@ -219,7 +219,7 @@ qw_client_glx_libs= \
qw_client_glx_SOURCES= cl_sys_unix.c
qw_client_glx_LDADD= $(qw_client_glx_libs) \
$(X_PRE_LIBS) $(VIDMODE_LIBS) $(DGA_LIBS) $(X_LIBS) -lX11 \
-lXext $(X_EXTRA_LIBS) $(DL_LIBS) $(NET_LIBS)
-lXext $(X_EXTRA_LIBS) $(DL_LIBS) $(NET_LIBS) $(LIBCURL)
qw_client_glx_LDFLAGS= $(common_ldflags)
qw_client_glx_DEPENDENCIES= $(qw_client_glx_libs)
@ -232,7 +232,7 @@ qw_client_3dfx_libs= \
$(client_LIBS)
qw_client_3dfx_SOURCES= cl_sys_unix.c
qw_client_3dfx_LDADD= $(qw_client_3dfx_libs) \
$(SVGA_LIBS) $(NET_LIBS)
$(SVGA_LIBS) $(NET_LIBS) $(LIBCURL)
qw_client_3dfx_LDFLAGS= $(common_ldflags)
qw_client_3dfx_DEPENDENCIES= $(qw_client_3dfx_libs)
@ -245,7 +245,7 @@ qw_client_sgl_libs= \
$(top_builddir)/libs/video/targets/libQFsgl.la \
$(client_LIBS)
qw_client_sgl_SOURCES=sdl_link.c
qw_client_sgl_LDADD= $(qw_client_sgl_libs) $(SDL_LIBS) $(DL_LIBS) $(NET_LIBS)
qw_client_sgl_LDADD= $(qw_client_sgl_libs) $(SDL_LIBS) $(DL_LIBS) $(NET_LIBS) $(LIBCURL)
qw_client_sgl_LDFLAGS= $(common_ldflags)
qw_client_sgl_DEPENDENCIES= $(qw_client_sgl_libs)
@ -257,7 +257,7 @@ qw_client_wgl_libs= \
$(top_builddir)/libs/video/targets/libQFwgl.la \
$(client_LIBS)
qw_client_wgl_SOURCES= cl_sys_win.c
qw_client_wgl_LDADD= $(qw_client_wgl_libs) -lgdi32 -lwinmm $(NET_LIBS)
qw_client_wgl_LDADD= $(qw_client_wgl_libs) -lgdi32 -lwinmm $(NET_LIBS) $(LIBCURL)
qw_client_wgl_LDFLAGS= $(common_ldflags)
qw_client_wgl_DEPENDENCIES= $(qw_client_wgl_libs)

129
qw/source/cl_http.c Normal file
View file

@ -0,0 +1,129 @@
/*
#FILENAME#
#DESCRIPTION#
Copyright (C) 2007 #AUTHOR#
Author: #AUTHOR#
Date: #DATE#
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
static __attribute__ ((used)) const char rcsid[] =
"$Id: template.c 11394 2007-03-17 03:23:39Z taniwha $";
#ifdef HAVE_LIBCURL
#include <curl/curl.h>
#include "QF/console.h"
#include "QF/dstring.h"
#include "cl_http.h"
#include "cl_parse.h"
#include "client.h"
static int curl_borked;
static CURL *easy_handle;
static CURLM *multi_handle;
static int
http_progress (void *clientp, double dltotal, double dlnow,
double ultotal, double uplow)
{
return 0; //non-zero = abort
}
static size_t
http_write (void *ptr, size_t size, size_t nmemb, void *stream)
{
if (!cls.download) {
Con_Printf ("http_write: unexpected call\n");
return -1;
}
return Qwrite (cls.download, ptr, size * nmemb);
}
void
CL_HTTP_Init (void)
{
if ((curl_borked = curl_global_init (CURL_GLOBAL_NOTHING)))
return;
multi_handle = curl_multi_init ();
}
void
CL_HTTP_Shutdown (void)
{
if (curl_borked)
return;
curl_multi_cleanup (multi_handle);
curl_global_cleanup ();
}
void
CL_HTTP_StartDownload (void)
{
easy_handle = curl_easy_init ();
curl_easy_setopt (easy_handle, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt (easy_handle, CURLOPT_NOSIGNAL, 1L);
curl_easy_setopt (easy_handle, CURLOPT_PROGRESSFUNCTION, http_progress);
curl_easy_setopt (easy_handle, CURLOPT_WRITEFUNCTION, http_write);
curl_easy_setopt (easy_handle, CURLOPT_URL, cls.downloadurl->str);
curl_multi_add_handle (multi_handle, easy_handle);
}
void
CL_HTTP_Update (void)
{
int running_handles;
curl_multi_perform (multi_handle, &running_handles);
if (!running_handles) {
curl_multi_remove_handle (multi_handle, easy_handle);
CL_FinishDownload ();
}
}
void
CL_HTTP_Reset (void)
{
curl_multi_remove_handle (multi_handle, easy_handle);
curl_easy_cleanup (easy_handle);
easy_handle = 0;
}
#else
#include "cl_http.h"
void CL_HTTP_Init (void) {}
void CL_HTTP_Shutdown (void) {}
void CL_HTTP_StartDownload (void) {}
void CL_HTTP_Update (void) {}
void CL_HTTP_Reset (void) {}
#endif

View file

@ -91,6 +91,7 @@ static __attribute__ ((used)) const char rcsid[] =
#include "cl_chat.h"
#include "cl_demo.h"
#include "cl_ents.h"
#include "cl_http.h"
#include "cl_input.h"
#include "cl_main.h"
#include "cl_parse.h"
@ -500,6 +501,10 @@ CL_Disconnect (void)
Cam_Reset ();
if (cls.download) {
CL_HTTP_Reset ();
dstring_clearstr (cls.downloadname);
dstring_clearstr (cls.downloadurl);
dstring_clearstr (cls.downloadtempname);
Qclose (cls.download);
cls.download = NULL;
}
@ -659,6 +664,9 @@ CL_AddQFInfoKeys (void)
static const char *cap = "pt"
#ifdef HAVE_ZLIB
"z"
#endif
#ifdef HAVE_LIBCURL
"h"
#endif
;
@ -1067,12 +1075,10 @@ CL_Download_f (void)
return;
}
snprintf (cls.downloadname, sizeof (cls.downloadname), "%s/%s",
qfs_gamedir->dir.def, Cmd_Argv (1));
dsprintf (cls.downloadname, "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1));
strncpy (cls.downloadtempname, cls.downloadname,
sizeof (cls.downloadtempname));
cls.download = QFS_WOpen (cls.downloadname, 0);
dstring_copystr (cls.downloadtempname, cls.downloadname->str);
cls.download = QFS_WOpen (cls.downloadname->str, 0);
if (cls.download) {
cls.downloadtype = dl_single;
@ -1549,6 +1555,8 @@ Host_Frame (float time)
// fetch results from server
CL_ReadPackets ();
if (cls.downloadurl->str)
CL_HTTP_Update ();
if (cls.demoplayback2) {
player_state_t *self, *oldself;
@ -1741,6 +1749,9 @@ Host_Init (void)
pr_gametype = "quakeworld";
cls.userinfo = Info_ParseString ("", MAX_INFO_STRING, 0);
cls.downloadtempname = dstring_newstr ();
cls.downloadname = dstring_newstr ();
cls.downloadurl = dstring_newstr ();
cl.serverinfo = Info_ParseString ("", MAX_INFO_STRING, 0);
QFS_Init ("qw");
@ -1799,6 +1810,7 @@ Host_Init (void)
sound_precache[i] = cl.sound_name[i];
Net_Log_Init (sound_precache);
}
CL_HTTP_Init ();
W_LoadWadFile ("gfx.wad");
Key_Init (cl_cbuf);
@ -1882,6 +1894,7 @@ Host_Shutdown (void)
Host_WriteConfiguration ();
CDAudio_Shutdown ();
CL_HTTP_Shutdown ();
NET_Shutdown ();
S_Shutdown ();
IN_Shutdown ();

View file

@ -65,6 +65,7 @@ static __attribute__ ((used)) const char rcsid[] =
#include "cl_cam.h"
#include "cl_chat.h"
#include "cl_ents.h"
#include "cl_http.h"
#include "cl_input.h"
#include "cl_main.h"
#include "cl_parse.h"
@ -232,25 +233,24 @@ CL_CheckOrDownloadFile (const char *filename)
// ZOID - can't download when recording
if (cls.demorecording) {
Con_Printf ("Unable to download %s in record mode.\n",
cls.downloadname);
cls.downloadname->str);
return true;
}
// ZOID - can't download when playback
if (cls.demoplayback)
return true;
strcpy (cls.downloadname, filename);
Con_Printf ("Downloading %s...\n", cls.downloadname);
dstring_copystr (cls.downloadname, filename);
Con_Printf ("Downloading %s...\n", cls.downloadname->str);
// download to a temp name, and only rename to the real name when done,
// so if interrupted a runt file wont be left
QFS_StripExtension (cls.downloadname, cls.downloadtempname);
strncat (cls.downloadtempname, ".tmp",
sizeof (cls.downloadtempname) - strlen (cls.downloadtempname));
QFS_StripExtension (cls.downloadname->str, cls.downloadtempname->str);
dstring_appendstr (cls.downloadtempname, ".tmp");
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message,
va ("download \"%s\"", cls.downloadname));
va ("download \"%s\"", cls.downloadname->str));
cls.downloadnumber++;
@ -416,6 +416,43 @@ CL_RequestNextDownload (void)
}
}
void
CL_FinishDownload (void)
{
Qclose (cls.download);
VID_SetCaption (va ("Connecting to %s", cls.servername));
// rename the temp file to it's final name
if (strcmp (cls.downloadtempname->str, cls.downloadname->str)) {
dstring_t *oldn = dstring_new ();
dstring_t *newn = dstring_new ();
if (strncmp (cls.downloadtempname->str, "skins/", 6)) {
dsprintf (oldn, "%s/%s", qfs_gamedir->dir.def,
cls.downloadtempname->str);
dsprintf (newn, "%s/%s", qfs_gamedir->dir.def,
cls.downloadname->str);
} else {
dsprintf (oldn, "%s/%s", qfs_gamedir->dir.skins,
cls.downloadtempname->str + 6);
dsprintf (newn, "%s/%s", qfs_gamedir->dir.skins,
cls.downloadname->str + 6);
}
if (QFS_Rename (oldn->str, newn->str))
Con_Printf ("failed to rename, %s.\n", strerror (errno));
dstring_delete (oldn);
dstring_delete (newn);
}
cls.download = NULL;
dstring_clearstr (cls.downloadname);
dstring_clearstr (cls.downloadurl);
cls.downloadpercent = 0;
// get another file if needed
CL_RequestNextDownload ();
}
/*
CL_ParseDownload
@ -424,7 +461,7 @@ CL_RequestNextDownload (void)
static void
CL_ParseDownload (void)
{
int size, percent, r;
int size, percent;
// read the data
size = MSG_ReadShort (net_message);
@ -433,7 +470,8 @@ CL_ParseDownload (void)
if (cls.demoplayback) {
if (size > 0)
net_message->readcount += size;
cls.downloadname[0] = 0;
dstring_clearstr (cls.downloadname);
dstring_clearstr (cls.downloadurl);
return; // not in demo playback
}
@ -444,16 +482,18 @@ CL_ParseDownload (void)
Qclose (cls.download);
cls.download = NULL;
}
cls.downloadname[0] = 0;
dstring_clearstr (cls.downloadname);
dstring_clearstr (cls.downloadurl);
CL_RequestNextDownload ();
return;
}
if (size == -2) {
const char *newname = MSG_ReadString (net_message);
const char *newname = MSG_ReadString (net_message);
if (strncmp (newname, cls.downloadname, strlen (cls.downloadname))
|| strstr (newname + strlen (cls.downloadname), "/")) {
if (strncmp (newname, cls.downloadname->str,
strlen (cls.downloadname->str))
|| strstr (newname + strlen (cls.downloadname->str), "/")) {
Con_Printf
("WARNING: server tried to give a strange new name: %s\n",
newname);
@ -462,10 +502,43 @@ CL_ParseDownload (void)
}
if (cls.download) {
Qclose (cls.download);
unlink (cls.downloadname);
unlink (cls.downloadname->str);
}
strncpy (cls.downloadname, newname, sizeof (cls.downloadname));
Con_Printf ("downloading to %s\n", cls.downloadname);
dstring_copystr (cls.downloadname, newname);
Con_Printf ("downloading to %s\n", cls.downloadname->str);
return;
}
if (size == -3) {
#ifdef HAVE_LIBCURL
const char *url = MSG_ReadString (net_message);
const char *newname = MSG_ReadString (net_message);
if (newname) {
if (strncmp (newname, cls.downloadname->str,
strlen (cls.downloadname->str))
|| strstr (newname + strlen (cls.downloadname->str), "/")) {
Con_Printf
("WARNING: server tried to give a strange new name: %s\n",
newname);
CL_RequestNextDownload ();
return;
}
if (cls.download) {
Qclose (cls.download);
unlink (cls.downloadname->str);
}
dstring_copystr (cls.downloadname, newname);
}
dstring_copystr (cls.downloadurl, url);
Con_Printf ("downloading %s to %s\n", cls.downloadurl->str,
cls.downloadname->str);
CL_HTTP_StartDownload ();
#else
MSG_ReadString (net_message);
MSG_ReadString (net_message);
Con_Printf ("server sent http redirect but we don't know how to handle"
"it :(\n");
#endif
return;
}
// open the file if not opened yet
@ -473,27 +546,28 @@ CL_ParseDownload (void)
dstring_t *name = dstring_newstr ();
const char *fname, *path;
if (strncmp (cls.downloadtempname, "skins/", 6) == 0) {
if (strncmp (cls.downloadtempname->str, "skins/", 6) == 0) {
path = qfs_gamedir->dir.skins;
fname = cls.downloadtempname + 6;
} else if (strncmp (cls.downloadtempname, "progs/", 6) == 0) {
fname = cls.downloadtempname->str + 6;
} else if (strncmp (cls.downloadtempname->str, "progs/", 6) == 0) {
path = qfs_gamedir->dir.progs;
fname = cls.downloadtempname + 6;
} else if (strncmp (cls.downloadtempname, "sound/", 6) == 0) {
fname = cls.downloadtempname->str + 6;
} else if (strncmp (cls.downloadtempname->str, "sound/", 6) == 0) {
path = qfs_gamedir->dir.sound;
fname = cls.downloadtempname + 6;
} else if (strncmp (cls.downloadtempname, "maps/", 5) == 0) {
fname = cls.downloadtempname->str + 6;
} else if (strncmp (cls.downloadtempname->str, "maps/", 5) == 0) {
path = qfs_gamedir->dir.maps;
fname = cls.downloadtempname + 5;
fname = cls.downloadtempname->str + 5;
} else {
path = qfs_gamedir->dir.def;
fname = cls.downloadtempname;
fname = cls.downloadtempname->str;
}
dsprintf (name, "%s/%s", path, fname);
cls.download = QFS_WOpen (name->str, 0);
if (!cls.download) {
cls.downloadname[0] = 0;
dstring_clearstr (cls.downloadname);
dstring_clearstr (cls.downloadurl);
net_message->readcount += size;
Con_Printf ("Failed to open %s\n", name->str);
CL_RequestNextDownload ();
@ -509,43 +583,14 @@ CL_ParseDownload (void)
if (percent != 100) {
// request next block
if (percent != cls.downloadpercent)
VID_SetCaption (va ("Downloading %s %d%%", cls.downloadname,
VID_SetCaption (va ("Downloading %s %d%%", cls.downloadname->str,
percent));
cls.downloadpercent = percent;
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
SZ_Print (&cls.netchan.message, "nextdl");
} else {
char oldn[MAX_OSPATH];
char newn[MAX_OSPATH];
Qclose (cls.download);
VID_SetCaption (va ("Connecting to %s", cls.servername));
// rename the temp file to it's final name
if (strcmp (cls.downloadtempname, cls.downloadname)) {
if (strncmp (cls.downloadtempname, "skins/", 6)) {
snprintf (oldn, sizeof (oldn), "%s/%s", qfs_gamedir->dir.def,
cls.downloadtempname);
snprintf (newn, sizeof (newn), "%s/%s", qfs_gamedir->dir.def,
cls.downloadname);
} else {
snprintf (oldn, sizeof (oldn), "%s/%s", qfs_gamedir->dir.skins,
cls.downloadtempname + 6);
snprintf (newn, sizeof (newn), "%s/%s", qfs_gamedir->dir.skins,
cls.downloadname + 6);
}
r = QFS_Rename (oldn, newn);
if (r)
Con_Printf ("failed to rename, %s.\n", strerror (errno));
}
cls.download = NULL;
cls.downloadname[0] = 0;
cls.downloadpercent = 0;
// get another file if needed
CL_RequestNextDownload ();
CL_FinishDownload ();
}
}