mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-09 23:02:02 +00:00
Port the HTTP / CURL download stuff from q2dos.
This is a very first cut: * It compiles * It doesn't crash What's missing: * cmake integration * CURL should be loaded dynamically * Integration between download code and filesystem * Likely UTF-8 stuff * cl_http.c needs cleanup * Windows support
This commit is contained in:
parent
380642468b
commit
0a94a8ee92
9 changed files with 1422 additions and 5 deletions
10
Makefile
10
Makefile
|
@ -25,6 +25,10 @@
|
|||
# User configurable options
|
||||
# -------------------------
|
||||
|
||||
# Enables HTTP support through cURL. Used for
|
||||
# HTTP download.
|
||||
WITH_CURL:=yes
|
||||
|
||||
# Enables the optional OpenAL sound system.
|
||||
# To use it your system needs libopenal.so.1
|
||||
# or openal32.dll (we recommend openal-soft)
|
||||
|
@ -373,6 +377,11 @@ endif
|
|||
|
||||
release/quake2 : CFLAGS += -Wno-unused-result
|
||||
|
||||
ifeq ($(WITH_CURL),yes)
|
||||
release/quake2 : CFLAGS += -DUSE_CURL
|
||||
release/quake2 : LDFLAGS += -lcurl
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_OPENAL),yes)
|
||||
ifeq ($(YQ2_OSTYPE), OpenBSD)
|
||||
release/quake2 : CFLAGS += -DUSE_OPENAL -DDEFAULT_OPENAL_DRIVER='"libopenal.so"'
|
||||
|
@ -668,6 +677,7 @@ CLIENT_OBJS_ := \
|
|||
src/client/cl_download.o \
|
||||
src/client/cl_effects.o \
|
||||
src/client/cl_entities.o \
|
||||
src/client/cl_http.o \
|
||||
src/client/cl_input.o \
|
||||
src/client/cl_inventory.o \
|
||||
src/client/cl_keyboard.o \
|
||||
|
|
|
@ -678,7 +678,11 @@ Con_DrawConsole(float frac)
|
|||
}
|
||||
|
||||
/* draw the download bar, figure out width */
|
||||
#ifdef USE_CURL
|
||||
if (cls.downloadname[0] && (cls.download || cls.downloadposition))
|
||||
#else
|
||||
if (cls.download)
|
||||
#endif
|
||||
{
|
||||
if ((text = strrchr(cls.downloadname, '/')) != NULL)
|
||||
{
|
||||
|
|
|
@ -103,6 +103,14 @@ CL_RequestNextDownload(void)
|
|||
precache_model_skin = 1;
|
||||
}
|
||||
|
||||
#ifdef USE_CURL
|
||||
/* Wait for the models to download before checking * skins. */
|
||||
if (CL_PendingHTTPDownloads())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* checking for skins in the model */
|
||||
if (!precache_model)
|
||||
{
|
||||
|
@ -338,6 +346,14 @@ CL_RequestNextDownload(void)
|
|||
precache_check = ENV_CNT;
|
||||
}
|
||||
|
||||
#ifdef USE_CURL
|
||||
/* Wait for pending downloads. */
|
||||
if (CL_PendingHTTPDownloads())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (precache_check == ENV_CNT)
|
||||
{
|
||||
precache_check = ENV_CNT + 1;
|
||||
|
@ -412,8 +428,15 @@ CL_RequestNextDownload(void)
|
|||
precache_check = TEXTURE_CNT + 999;
|
||||
}
|
||||
|
||||
CL_RegisterSounds();
|
||||
#ifdef USE_CURL
|
||||
/* Wait for pending downloads. */
|
||||
if (CL_PendingHTTPDownloads())
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
CL_RegisterSounds();
|
||||
CL_PrepRefresh();
|
||||
|
||||
MSG_WriteByte(&cls.netchan.message, clc_stringcmd);
|
||||
|
@ -464,6 +487,18 @@ CL_CheckOrDownloadFile(char *filename)
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef USE_CURL
|
||||
if (CL_QueueHTTPDownload(filename))
|
||||
{
|
||||
/* We return true so that the precache check
|
||||
keeps feeding us more files. Since we have
|
||||
multiple HTTP connections we want to
|
||||
minimize latency and be constantly sending
|
||||
requests, not one at a time. */
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
strcpy(cls.downloadname, filename);
|
||||
|
||||
/* download to a temp name, and only rename
|
||||
|
|
1182
src/client/cl_http.c
Normal file
1182
src/client/cl_http.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -461,6 +461,10 @@ CL_Precache_f(void)
|
|||
precache_model = 0;
|
||||
precache_model_skin = 0;
|
||||
|
||||
#ifdef USE_CURL
|
||||
CL_HTTP_ResetMapAbort();
|
||||
#endif
|
||||
|
||||
CL_RequestNextDownload();
|
||||
}
|
||||
|
||||
|
@ -541,6 +545,13 @@ CL_InitLocal(void)
|
|||
|
||||
cl_vwep = Cvar_Get("cl_vwep", "1", CVAR_ARCHIVE);
|
||||
|
||||
#ifdef USE_CURL
|
||||
cl_http_proxy = Cvar_Get("cl_http_proxy", "", 0);
|
||||
cl_http_filelists = Cvar_Get("cl_http_filelists", "1", 0);
|
||||
cl_http_downloads = Cvar_Get("cl_http_downloads", "1", CVAR_ARCHIVE);
|
||||
cl_http_max_connections = Cvar_Get("cl_http_max_connections", "4", 0);
|
||||
#endif
|
||||
|
||||
/* register our commands */
|
||||
Cmd_AddCommand("cmd", CL_ForwardToServer_f);
|
||||
Cmd_AddCommand("pause", CL_Pause_f);
|
||||
|
@ -757,7 +768,15 @@ CL_Frame(int packetdelta, int renderdelta, int timedelta, qboolean packetframe,
|
|||
}
|
||||
}
|
||||
|
||||
// Update input stuff
|
||||
// Run HTTP downloads more often while connecting.
|
||||
#ifdef USE_CURL
|
||||
if (cls.state == ca_connected)
|
||||
{
|
||||
CL_RunHTTPDownloads();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Update input stuff.
|
||||
if (packetframe || renderframe)
|
||||
{
|
||||
CL_ReadPackets();
|
||||
|
@ -786,6 +805,11 @@ CL_Frame(int packetdelta, int renderdelta, int timedelta, qboolean packetframe,
|
|||
{
|
||||
CL_SendCmd();
|
||||
CL_CheckForResend();
|
||||
|
||||
// Run HTTP downloads during game.
|
||||
#ifdef USE_CURL
|
||||
CL_RunHTTPDownloads();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (renderframe)
|
||||
|
@ -880,6 +904,10 @@ CL_Init(void)
|
|||
|
||||
M_Init();
|
||||
|
||||
#ifdef USE_CURL
|
||||
CL_InitHTTPDownloads();
|
||||
#endif
|
||||
|
||||
cls.disable_screen = true; /* don't draw yet */
|
||||
|
||||
CL_InitLocal();
|
||||
|
@ -902,6 +930,10 @@ CL_Shutdown(void)
|
|||
|
||||
isdown = true;
|
||||
|
||||
#ifdef USE_CURL
|
||||
CL_HTTP_Cleanup(true);
|
||||
#endif
|
||||
|
||||
CL_WriteConfiguration();
|
||||
|
||||
Key_WriteConsoleHistory();
|
||||
|
|
|
@ -346,6 +346,15 @@ CL_Disconnect(void)
|
|||
cls.download = NULL;
|
||||
}
|
||||
|
||||
#ifdef USE_CURL
|
||||
CL_CancelHTTPDownloads(true);
|
||||
cls.downloadReferer[0] = 0;
|
||||
cls.downloadname[0] = 0;
|
||||
cls.downloadposition = 0;
|
||||
// TODO CURL: Rausreißen?
|
||||
// CL_Download_Reset_KBps_counter();
|
||||
#endif
|
||||
|
||||
cls.state = ca_disconnected;
|
||||
|
||||
snd_is_underwater = false;
|
||||
|
@ -437,10 +446,15 @@ CL_Changing_f(void)
|
|||
}
|
||||
|
||||
SCR_BeginLoadingPlaque();
|
||||
|
||||
cls.state = ca_connected; /* not active anymore, but not disconnected */
|
||||
|
||||
Com_Printf("\nChanging map...\n");
|
||||
|
||||
#ifdef USE_CURL
|
||||
if (cls.downloadServerRetry[0] != 0)
|
||||
{
|
||||
CL_SetHTTPServer(cls.downloadServerRetry);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -583,6 +597,32 @@ CL_ConnectionlessPacket(void)
|
|||
|
||||
Netchan_Setup(NS_CLIENT, &cls.netchan, net_from, cls.quakePort);
|
||||
|
||||
// TODO CURL: Das erscheint mir sinnlos kompliziert und ist für
|
||||
// den Fall ohne CURL wahrscheinlich recht spammy.
|
||||
|
||||
char *buff = NET_AdrToString(cls.netchan.remote_address);
|
||||
|
||||
for (int i = 1; i < Cmd_Argc(); i++)
|
||||
{
|
||||
char *p = Cmd_Argv(i);
|
||||
|
||||
if (!strncmp (p, "dlserver=", 9))
|
||||
{
|
||||
#ifdef USE_CURL
|
||||
p += 9;
|
||||
Com_sprintf(cls.downloadReferer, sizeof(cls.downloadReferer), "quake2://%s", buff);
|
||||
CL_SetHTTPServer (p);
|
||||
|
||||
if (cls.downloadServer[0])
|
||||
{
|
||||
Com_Printf("HTTP downloading enabled, URL: %s\n", cls.downloadServer);
|
||||
}
|
||||
#else
|
||||
Com_Printf("HTTP downloading supported by server but not the client.\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
MSG_WriteChar(&cls.netchan.message, clc_stringcmd);
|
||||
MSG_WriteString(&cls.netchan.message, "new");
|
||||
cls.state = ca_connected;
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "../vid/header/ref.h"
|
||||
#include "../vid/header/vid.h"
|
||||
|
||||
#include "http.h"
|
||||
#include "screen.h"
|
||||
#include "keyboard.h"
|
||||
#include "console.h"
|
||||
|
@ -240,12 +241,22 @@ typedef struct
|
|||
char downloadname[MAX_OSPATH];
|
||||
int downloadnumber;
|
||||
dltype_t downloadtype;
|
||||
size_t downloadposition;
|
||||
int downloadpercent;
|
||||
|
||||
/* demo recording info must be here, so it isn't cleared on level change */
|
||||
qboolean demorecording;
|
||||
qboolean demowaiting; /* don't record until a non-delta message is received */
|
||||
FILE *demofile;
|
||||
|
||||
#ifdef USE_CURL
|
||||
/* http downloading */
|
||||
dlqueue_t downloadQueue; /* queues with files to download. */
|
||||
dlhandle_t HTTPHandles[MAX_HTTP_HANDLES]; /* download handles. */
|
||||
char downloadServer[512]; /* URL prefix to dowload from .*/
|
||||
char downloadServerRetry[512]; /* retry count. */
|
||||
char downloadReferer[32]; /* referer string. */
|
||||
#endif
|
||||
} client_static_t;
|
||||
|
||||
extern client_static_t cls;
|
||||
|
|
75
src/client/header/http.h
Normal file
75
src/client/header/http.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||
*
|
||||
* 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 the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*
|
||||
* =======================================================================
|
||||
*
|
||||
* Header for the HTTP / cURL download stuff.
|
||||
*
|
||||
* =======================================================================
|
||||
*/
|
||||
|
||||
#ifdef USE_CURL
|
||||
|
||||
// Number of max. parallel downloads.
|
||||
#define MAX_HTTP_HANDLES 16
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DLQ_STATE_NOT_STARTED,
|
||||
DLQ_STATE_RUNNING,
|
||||
DLQ_STATE_DONE
|
||||
} dlq_state;
|
||||
|
||||
typedef struct dlqueue_s
|
||||
{
|
||||
struct dlqueue_s *next;
|
||||
char quakePath[MAX_QPATH];
|
||||
dlq_state state;
|
||||
} dlqueue_t;
|
||||
|
||||
typedef struct dlhandle_s
|
||||
{
|
||||
CURL *curl;
|
||||
char filePath[MAX_OSPATH];
|
||||
FILE *file;
|
||||
dlqueue_t *queueEntry;
|
||||
size_t fileSize;
|
||||
size_t position;
|
||||
double speed;
|
||||
char URL[576];
|
||||
char *tempBuffer;
|
||||
} dlhandle_t;
|
||||
|
||||
extern cvar_t *cl_http_downloads;
|
||||
extern cvar_t *cl_http_filelists;
|
||||
extern cvar_t *cl_http_proxy;
|
||||
extern cvar_t *cl_http_max_connections;
|
||||
|
||||
void CL_CancelHTTPDownloads(qboolean permKill);
|
||||
void CL_InitHTTPDownloads(void);
|
||||
qboolean CL_QueueHTTPDownload(const char *quakePath);
|
||||
void CL_RunHTTPDownloads(void);
|
||||
qboolean CL_PendingHTTPDownloads(void);
|
||||
void CL_SetHTTPServer(const char *URL);
|
||||
void CL_HTTP_Cleanup(qboolean fullShutdown);
|
||||
void CL_HTTP_ResetMapAbort(void);
|
||||
|
||||
#endif
|
|
@ -3538,6 +3538,11 @@ static menuframework_s s_downloadoptions_menu;
|
|||
|
||||
static menuseparator_s s_download_title;
|
||||
static menulist_s s_allow_download_box;
|
||||
|
||||
#ifdef USE_CURL
|
||||
static menulist_s s_allow_download_http_box;
|
||||
#endif
|
||||
|
||||
static menulist_s s_allow_download_maps_box;
|
||||
static menulist_s s_allow_download_models_box;
|
||||
static menulist_s s_allow_download_players_box;
|
||||
|
@ -3552,6 +3557,12 @@ DownloadCallback(void *self)
|
|||
{
|
||||
Cvar_SetValue("allow_download", (float)f->curvalue);
|
||||
}
|
||||
#ifdef USE_CURL
|
||||
else if (f == &s_allow_download_http_box)
|
||||
{
|
||||
Cvar_SetValue("cl_http_downloads", f->curvalue);
|
||||
}
|
||||
#endif
|
||||
else if (f == &s_allow_download_maps_box)
|
||||
{
|
||||
Cvar_SetValue("allow_download_maps", (float)f->curvalue);
|
||||
|
@ -3596,9 +3607,21 @@ DownloadOptions_MenuInit(void)
|
|||
s_allow_download_box.itemnames = yes_no_names;
|
||||
s_allow_download_box.curvalue = (Cvar_VariableValue("allow_download") != 0);
|
||||
|
||||
#ifdef USE_CURL
|
||||
s_allow_download_http_box.generic.type = MTYPE_SPINCONTROL;
|
||||
s_allow_download_http_box.generic.x = 0;
|
||||
s_allow_download_http_box.generic.y = y += 20;
|
||||
s_allow_download_http_box.generic.name = "http downloading";
|
||||
s_allow_download_http_box.generic.callback = DownloadCallback;
|
||||
s_allow_download_http_box.itemnames = yes_no_names;
|
||||
s_allow_download_http_box.curvalue = (Cvar_VariableValue("cl_http_downloads") != 0);
|
||||
#else
|
||||
y += 10;
|
||||
#endif
|
||||
|
||||
s_allow_download_maps_box.generic.type = MTYPE_SPINCONTROL;
|
||||
s_allow_download_maps_box.generic.x = 0;
|
||||
s_allow_download_maps_box.generic.y = y += 20;
|
||||
s_allow_download_maps_box.generic.y = y += 10;
|
||||
s_allow_download_maps_box.generic.name = "maps";
|
||||
s_allow_download_maps_box.generic.callback = DownloadCallback;
|
||||
s_allow_download_maps_box.itemnames = yes_no_names;
|
||||
|
@ -3634,6 +3657,11 @@ DownloadOptions_MenuInit(void)
|
|||
|
||||
Menu_AddItem(&s_downloadoptions_menu, &s_download_title);
|
||||
Menu_AddItem(&s_downloadoptions_menu, &s_allow_download_box);
|
||||
|
||||
#ifdef USE_CURL
|
||||
Menu_AddItem(&s_downloadoptions_menu, &s_allow_download_http_box);
|
||||
#endif
|
||||
|
||||
Menu_AddItem(&s_downloadoptions_menu, &s_allow_download_maps_box);
|
||||
Menu_AddItem(&s_downloadoptions_menu, &s_allow_download_players_box);
|
||||
Menu_AddItem(&s_downloadoptions_menu, &s_allow_download_models_box);
|
||||
|
|
Loading…
Reference in a new issue