From 00885ffd27df3dd9eefe3b6fb21641d3fe85c218 Mon Sep 17 00:00:00 2001 From: Spoike Date: Wed, 5 Jun 2019 20:48:06 +0000 Subject: [PATCH] Fix q2 cinematics (was giving black screens). Add support for DP_SV_CLIENTCAMERA (primarily to work around an rmq bug). Now pointing the engine at the shadowy updates.triptohell.info domain (with a self-signed cert), so that we can give fte.triptohell.info a proper cert that browsers will trust. Still need to make a stable release some time before that can happen. Make sure q2 gamecode updates can work, so win64/linux64 can actually run q2 now (using yamagi's). git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5467 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_pred.c | 2 +- engine/client/clq2_cin.c | 13 ++- engine/client/clq2_ents.c | 2 - engine/client/image.c | 1 - engine/client/m_download.c | 14 +-- engine/client/m_mp3.c | 2 + engine/client/m_options.c | 11 +-- engine/client/p_script.c | 5 +- engine/client/r_2d.c | 1 - engine/client/render.h | 2 +- engine/client/view.c | 170 +++++++++++++++++--------------- engine/client/view.h | 12 +++ engine/common/common.c | 4 +- engine/common/config_fteqw.h | 2 +- engine/common/fs.c | 34 ++++--- engine/common/net.h | 1 + engine/common/net_ssl_gnutls.c | 63 +++++++----- engine/common/net_ssl_winsspi.c | 12 +-- engine/common/net_wins.c | 11 +++ engine/common/pr_bgcmd.c | 1 + engine/gl/gl_alias.c | 1 - engine/gl/gl_backend.c | 8 +- engine/gl/gl_draw.c | 9 -- engine/qclib/progslib.h | 1 + engine/qclib/qccguiqt.cpp | 61 +++++++++++- engine/server/net_preparse.c | 1 - engine/server/pr_cmds.c | 105 +++++++------------- engine/server/progdefs.h | 1 + engine/server/progs.h | 8 +- engine/server/savegame.c | 16 --- engine/server/server.h | 5 +- engine/server/sv_init.c | 3 +- engine/server/sv_main.c | 22 +++-- engine/server/sv_mvd.c | 5 +- engine/server/sv_nchan.c | 2 +- engine/server/sv_send.c | 73 +++++++------- engine/server/sv_user.c | 1 - engine/server/svq2_game.c | 20 +++- 38 files changed, 389 insertions(+), 316 deletions(-) diff --git a/engine/client/cl_pred.c b/engine/client/cl_pred.c index 792b8dc7..b5144b95 100644 --- a/engine/client/cl_pred.c +++ b/engine/client/cl_pred.c @@ -1155,7 +1155,7 @@ void CL_PredictMovePNum (int seat) //if our network protocol doesn't have a concept of separate players, make sure our player states are updated from those entities //fixme: use entity states instead of player states to avoid the extra work here - if (pv->nolocalplayer || nopred) + if (pv->nolocalplayer) { packet_entities_t *pe; pe = &cl.inframes[fromframe & UPDATE_MASK].packet_entities; diff --git a/engine/client/clq2_cin.c b/engine/client/clq2_cin.c index 4c5deece..934e0afb 100644 --- a/engine/client/clq2_cin.c +++ b/engine/client/clq2_cin.c @@ -4,7 +4,7 @@ typedef struct { qbyte *data; - int count; + size_t count; } cblock_t; typedef struct cinematics_s @@ -123,7 +123,8 @@ static void Huff1TableInit (cinematics_t *cin) memset (cin->h_used,0,sizeof(cin->h_used)); // read a row of counts - VFS_READ (cin->cinematic_file, counts, sizeof(counts)); + if (VFS_READ (cin->cinematic_file, counts, sizeof(counts)) != sizeof(counts)) + Con_Printf("Huff1TableInit: read error\n"); for (j=0 ; j<256 ; j++) cin->h_count[j] = counts[j]; @@ -274,7 +275,7 @@ static cblock_t Huff1Decompress (cinematics_t *cin, cblock_t in) if (input - in.data != in.count && input - in.data != in.count+1) { - Con_Printf ("Decompression overread by %i\n", (int)(input - in.data) - in.count); + Con_Printf ("Decompression overread by %i\n", (int)((input - in.data) - in.count)); } out.count = out_p - out.data; @@ -318,7 +319,8 @@ static qbyte *CIN_ReadNextFrame (cinematics_t *cin) size = LittleLong(size); if (size > sizeof(compressed) || size < 1) Host_Error ("Bad compressed frame size"); - VFS_READ (cin->cinematic_file, compressed, size); + if (VFS_READ (cin->cinematic_file, compressed, size) != size) + Con_Printf("CIN_ReadNextFrame: Failed reading video data\n"); // read sound. the number of samples per frame is not actually constant, despite a constant rate and fps... // life is shit like that. @@ -326,7 +328,8 @@ static qbyte *CIN_ReadNextFrame (cinematics_t *cin) end = ((cin->cinematicframe+1)*cin->s_rate)/14; count = end - start; - VFS_READ (cin->cinematic_file, samples, count*cin->s_width*cin->s_channels); + if (VFS_READ (cin->cinematic_file, samples, count*cin->s_width*cin->s_channels) != count*cin->s_width*cin->s_channels) + Con_Printf("CIN_ReadNextFrame: Failed reading audio data\n"); if (cin->s_width == 1) COM_CharBias(samples, count*cin->s_channels); diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index b50d6c0d..718f547f 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -2420,12 +2420,10 @@ Sets r_refdef view values */ void CLQ2_CalcViewValues (int seat) { - extern cvar_t v_gunkick_q2; int i; float lerp, backlerp; q2frame_t *oldframe; q2player_state_t *ps, *ops; - extern cvar_t gl_cshiftenabled; playerview_t *pv = &cl.playerview[seat]; r_refdef.areabitsknown = true; diff --git a/engine/client/image.c b/engine/client/image.c index 4c774682..9e4fc376 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -3242,7 +3242,6 @@ void BoostGamma(qbyte *rgba, int width, int height, uploadfmt_t fmt) { //note: should not be used where hardware gamma is supported. int i; - extern qbyte gammatable[256]; switch(fmt) { diff --git a/engine/client/m_download.c b/engine/client/m_download.c index 2f7a6940..1e8cfb18 100644 --- a/engine/client/m_download.c +++ b/engine/client/m_download.c @@ -165,6 +165,7 @@ typedef struct package_s { DEP_FILECONFLICT, //don't install if this file already exists. DEP_REQUIRE, DEP_RECOMMEND, //like depend, but uninstalling will not bubble. + DEP_SUGGEST, //like recommend, but will not force install (ie: only prevents auto-uninstall) // DEP_MIRROR, // DEP_FAILEDMIRROR, @@ -900,6 +901,8 @@ static void PM_ParsePackageList(vfsfile_t *f, int parseflags, const char *url, c PM_AddDep(p, DEP_FILECONFLICT, val); else if (!strcmp(key, "recommend")) PM_AddDep(p, DEP_RECOMMEND, val); + else if (!strcmp(key, "suggest")) + PM_AddDep(p, DEP_SUGGEST, val); else if (!strcmp(key, "test")) flags |= DPF_TESTING; else if (!strcmp(key, "stale") && version==2) @@ -1314,7 +1317,7 @@ static qboolean PM_HasDependant(package_t *package, unsigned int markflag) { if (o->flags & markflag) for (dep = o->deps; dep; dep = dep->next) - if (dep->dtype == DEP_REQUIRE || dep->dtype == DEP_RECOMMEND) + if (dep->dtype == DEP_REQUIRE || dep->dtype == DEP_RECOMMEND || dep->dtype == DEP_SUGGEST) if (!strcmp(package->name, dep->name)) return true; } @@ -3435,15 +3438,6 @@ static int MD_AddItemsToDownloadMenu(menu_t *m, int y, const char *pathprefix) break; if (!mo) { - package_t *s; - for (s = availablepackages; s; s = s->next) - { - if (!strncmp(s->category, pathprefix, slash-path) || s->category[slash-path] != '/') - continue; - if (!(s->flags & DPF_ENABLED) != !(s->flags & DPF_MARKED)) - break; - } - y += 8; MC_AddBufferedText(m, 48, 320, y, path+prefixlen, false, true); y += 8; diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index 235e48e9..60ec251f 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -2590,6 +2590,8 @@ qboolean Media_ShowFilm(void) if (videoshader) { cin_t *cin = R_ShaderGetCinematic(videoshader); + if (cin && cin->playstate == CINSTATE_INVALID) + Media_SetState(cin, CINSTATE_PLAY); //err... wot? must have vid_reloaded or something if (cin && cin->playstate == CINSTATE_ENDED) { Media_StopFilm(false); diff --git a/engine/client/m_options.c b/engine/client/m_options.c index 4a3e6004..28bdd743 100644 --- a/engine/client/m_options.c +++ b/engine/client/m_options.c @@ -879,7 +879,7 @@ const char *presetexec[] = "seta r_graphics 1;" "seta r_renderscale 1;" - , // fast options + , // fast options (for deathmatch) "gl_texturemode ln;" "gl_texturemode2d n;" #ifdef MINIMAL @@ -898,7 +898,7 @@ const char *presetexec[] = "r_nolightdir 0;" "seta gl_simpleitems 0;" - , //quakespasm-esque options. + , //quakespasm-esque options (for singleplayer faithful). "r_part_density 1;" "gl_polyblend 1;" "r_dynamic 2;" @@ -910,10 +910,7 @@ const char *presetexec[] = "v_gunkick 1;" "cl_rollangle 2.0;" "cl_bob 0.02;" - //these things are perhaps a little extreme - "r_loadlit 0;" "vid_hardwaregamma 1;" //auto hardware gamma, for fast fullscreen and usable windowed. - "d_mipcap 0 2;" //gl without anisotropic filtering favours too-distant mips too often, so lets just pretend it doesn't exist. should probably mess with lod instead or something "r_part_classic_expgrav 1;" //vanillaery "r_part_classic_opaque 1;" // "r_particlesystem script;" //q2 or hexen2 particle effects need to be loadable @@ -925,13 +922,15 @@ const char *presetexec[] = "seta cl_deadbodyfilter 0;" "cl_fullpitch 1;maxpitch 90;seta minpitch -90;" //QS has cheaty viewpitch range. some maps require it. - , //vanilla-esque options. + , //vanilla-esque options (for purists). "cl_fullpitch 0;maxpitch \"\";seta minpitch \"\";" //quakespasm is not vanilla "gl_texturemode nll;" //yup, we went there. "gl_texturemode2d n.l;" //yeah, 2d too. "r_nolerp 1;" "cl_sbar 1;" + "d_mipcap 0 2;" //gl without anisotropic filtering favours too-distant mips too often, so lets just pretend it doesn't exist. should probably mess with lod instead or something "v_viewmodel_quake 1;" + "r_loadlit 0;" "gl_affinemodels 1;" "r_softwarebanding 1;" //ugly software banding. "r_part_classic_square 1;" //blocky baby! diff --git a/engine/client/p_script.c b/engine/client/p_script.c index 4ef9df7c..3ffcd481 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -7316,6 +7316,7 @@ static void PScript_DrawParticleTypes (void) float m; vec3_t vec={0.5, 0.5, 0.431}; model_t *model; + float rotangle; ctx.entity = e; if (!ctx.entity) @@ -7338,7 +7339,9 @@ static void PScript_DrawParticleTypes (void) VectorNormalize(vec); CrossProduct(ctx.normal, vec, ctx.tangent1); - Matrix4x4_CM_Transform3(Matrix4x4_CM_NewRotation(frandom()*360, ctx.normal[0], ctx.normal[1], ctx.normal[2]), ctx.tangent1, ctx.tangent2); + rotangle = type->rotationstartmin+frandom()*type->rotationstartrand; + rotangle *= 180/M_PI; //gah! Matrix4x4_CM_NewRotation takes degrees but we already converted to radians. + Matrix4x4_CM_Transform3(Matrix4x4_CM_NewRotation(rotangle, ctx.normal[0], ctx.normal[1], ctx.normal[2]), ctx.tangent1, ctx.tangent2); CrossProduct(ctx.normal, ctx.tangent2, ctx.tangent1); VectorNormalize(ctx.tangent1); diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index a2924571..caaae779 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -1291,7 +1291,6 @@ R_PolyBlend //bright flashes and stuff, game only, doesn't touch sbar void R2D_PolyBlend (void) { - extern cvar_t gl_cshiftborder; float bordersize = gl_cshiftborder.value; if (r_refdef.flags & RDF_NOWORLDMODEL) diff --git a/engine/client/render.h b/engine/client/render.h index 2577d745..9f03fa30 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -298,7 +298,7 @@ typedef struct qboolean externalview; /*draw external models and not viewmodels*/ int recurse; /*in a mirror/portal/half way through drawing something else*/ qboolean forcevis; /*if true, vis comes from the forcedvis field instead of recalculated*/ - unsigned int flipcull; /*reflected/flipped view, requires inverted culling (should be set to SHADER_CULL_FLIPPED or 0)*/ + unsigned int flipcull; /*reflected/flipped view, requires inverted culling (should be set to SHADER_CULL_FLIPPED or 0 - its implemented as a xor)*/ qboolean useperspective; /*not orthographic*/ stereomethod_t stereomethod; diff --git a/engine/client/view.c b/engine/client/view.c index 0f84c550..c7e1d47f 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -32,7 +32,7 @@ cvar_t ffov = CVARFD("ffov", "", 0, "Allows you to set a specific field of view #if defined(_WIN32) && !defined(MINIMAL) //amusing gimmick / easteregg. #include "winquake.h" -cvar_t itburnsitburnsmakeitstop = CVARFD("itburnsitburnsmakeitstop", "0", CVAR_NOTFROMSERVER, "Ouch"); +static cvar_t itburnsitburnsmakeitstop = CVARFD("itburnsitburnsmakeitstop", "0", CVAR_NOTFROMSERVER, "Ouch"); #endif /* @@ -45,39 +45,53 @@ when crossing a water boudnary. */ #ifdef SIDEVIEWS -cvar_t vsec_enabled[SIDEVIEWS] = {CVAR("v2_enabled", "2"), CVAR("v3_enabled", "0"), CVAR("v4_enabled", "0"), CVAR("v5_enabled", "0")}; -cvar_t vsec_x[SIDEVIEWS] = {CVAR("v2_x", "0"), CVAR("v3_x", "0.25"), CVAR("v4_x", "0.5"), CVAR("v5_x", "0.75")}; -cvar_t vsec_y[SIDEVIEWS] = {CVAR("v2_y", "0"), CVAR("v3_y", "0"), CVAR("v4_y", "0"), CVAR("v5_y", "0")}; -cvar_t vsec_scalex[SIDEVIEWS] = {CVAR("v2_scalex", "0.25"), CVAR("v3_scalex", "0.25"), CVAR("v4_scalex", "0.25"), CVAR("v5_scalex", "0.25")}; -cvar_t vsec_scaley[SIDEVIEWS] = {CVAR("v2_scaley", "0.25"), CVAR("v3_scaley", "0.25"), CVAR("v4_scaley", "0.25"), CVAR("v5_scaley", "0.25")}; -cvar_t vsec_yaw[SIDEVIEWS] = {CVAR("v2_yaw", "180"), CVAR("v3_yaw", "90"), CVAR("v4_yaw", "270"), CVAR("v5_yaw", "0")}; +static struct +{ + cvar_t enabled; + cvar_t x; + cvar_t y; + cvar_t scalex; + cvar_t scaley; + cvar_t yaw; +} sideview[SIDEVIEWS] = { + {CVAR("v2_enabled", "2"), CVAR("v2_x", "0"), CVAR("v2_y", "0"), CVAR("v2_scalex", "0.25"), CVAR("v2_scaley", "0.25"), CVAR("v2_yaw", "180")}, +#if SIDEVIEWS > 1 + {CVAR("v3_enabled", "2"), CVAR("v3_x", "0.25"), CVAR("v3_y", "0"), CVAR("v3_scalex", "0.25"), CVAR("v3_scaley", "0.25"), CVAR("v3_yaw", "90")}, +#endif +#if SIDEVIEWS > 2 + {CVAR("v4_enabled", "2"), CVAR("v4_x", "0.5"), CVAR("v4_y", "0"), CVAR("v4_scalex", "0.25"), CVAR("v4_scaley", "0.25"), CVAR("v4_yaw", "270")}, +#endif +#if SIDEVIEWS > 3 + {CVAR("v5_enabled", "2"), CVAR("v5_x", "0.75"), CVAR("v5_y", "0"), CVAR("v5_scalex", "0.25"), CVAR("v5_scaley", "0.25"), CVAR("v5_yaw", "0")}, +#endif +}; #endif cvar_t cl_rollspeed = CVARD("cl_rollspeed", "200", "Controls the speed required to reach cl_rollangle's tilt."); -cvar_t cl_rollangle = CVARD("cl_rollangle", "2.0", "Controls the maximum view should tilt while strafing."); -cvar_t cl_rollalpha = CVARD("cl_rollalpha", "20", "Controls the speed at which the view rolls according to sideways movement."); -cvar_t v_deathtilt = CVARD("v_deathtilt", "1", "Specifies whether to tilt the view when dead."); +static cvar_t cl_rollangle = CVARD("cl_rollangle", "2.0", "Controls the maximum view should tilt while strafing."); +static cvar_t cl_rollalpha = CVARD("cl_rollalpha", "20", "Controls the speed at which the view rolls according to sideways movement."); +static cvar_t v_deathtilt = CVARD("v_deathtilt", "1", "Specifies whether to tilt the view when dead."); -cvar_t cl_bob = CVARD("cl_bob","0.02", "Controls how much the camera position should bob up down as the player runs around."); -cvar_t cl_bobcycle = CVAR("cl_bobcycle","0.6"); -cvar_t cl_bobup = CVAR("cl_bobup","0.5"); +static cvar_t cl_bob = CVARD("cl_bob","0.02", "Controls how much the camera position should bob up down as the player runs around."); +static cvar_t cl_bobcycle = CVAR("cl_bobcycle","0.6"); +static cvar_t cl_bobup = CVAR("cl_bobup","0.5"); -cvar_t cl_bobmodel = CVARD("cl_bobmodel", "0", "Controls whether the viewmodel should bob up and down as the player runs around."); -cvar_t cl_bobmodel_side = CVAR("cl_bobmodel_side", "0.15"); -cvar_t cl_bobmodel_up = CVAR("cl_bobmodel_up", "0.06"); -cvar_t cl_bobmodel_speed = CVAR("cl_bobmodel_speed", "7"); +static cvar_t cl_bobmodel = CVARD("cl_bobmodel", "0", "Controls whether the viewmodel should bob up and down as the player runs around."); +static cvar_t cl_bobmodel_side = CVAR("cl_bobmodel_side", "0.15"); +static cvar_t cl_bobmodel_up = CVAR("cl_bobmodel_up", "0.06"); +static cvar_t cl_bobmodel_speed = CVAR("cl_bobmodel_speed", "7"); -cvar_t v_kicktime = CVARD("v_kicktime", "0.5", "This controls how long viewangle changes from taking damage will last."); -cvar_t v_kickroll = CVARD("v_kickroll", "0.6", "This controls part of the strength of viewangle changes from taking damage."); -cvar_t v_kickpitch = CVARD("v_kickpitch", "0.6", "This controls part of the strength of viewangle changes from taking damage."); +static cvar_t v_kicktime = CVARD("v_kicktime", "0.5", "This controls how long viewangle changes from taking damage will last."); +static cvar_t v_kickroll = CVARD("v_kickroll", "0.6", "This controls part of the strength of viewangle changes from taking damage."); +static cvar_t v_kickpitch = CVARD("v_kickpitch", "0.6", "This controls part of the strength of viewangle changes from taking damage."); -cvar_t v_iyaw_cycle = CVAR("v_iyaw_cycle", "2"); -cvar_t v_iroll_cycle = CVAR("v_iroll_cycle", "0.5"); -cvar_t v_ipitch_cycle = CVAR("v_ipitch_cycle", "1"); -cvar_t v_iyaw_level = CVAR("v_iyaw_level", "0.3"); -cvar_t v_iroll_level = CVAR("v_iroll_level", "0.1"); -cvar_t v_ipitch_level = CVAR("v_ipitch_level", "0.3"); -cvar_t v_idlescale = CVARD("v_idlescale", "0", "Enable swishing of the view (whether idle or otherwise). Often used for concussion effects."); +static cvar_t v_iyaw_cycle = CVAR("v_iyaw_cycle", "2"); +static cvar_t v_iroll_cycle = CVAR("v_iroll_cycle", "0.5"); +static cvar_t v_ipitch_cycle = CVAR("v_ipitch_cycle", "1"); +static cvar_t v_iyaw_level = CVAR("v_iyaw_level", "0.3"); +static cvar_t v_iroll_level = CVAR("v_iroll_level", "0.1"); +static cvar_t v_ipitch_level = CVAR("v_ipitch_level", "0.3"); +static cvar_t v_idlescale = CVARD("v_idlescale", "0", "Enable swishing of the view (whether idle or otherwise). Often used for concussion effects."); cvar_t crosshair = CVARF("crosshair", "1", CVAR_ARCHIVE); cvar_t crosshaircolor = CVARF("crosshaircolor", "255 255 255", CVAR_ARCHIVE); @@ -89,43 +103,43 @@ cvar_t crosshaircorrect = CVARFD("crosshaircorrect", "0", CVAR_SEMICHEAT, "Move cvar_t crosshairimage = CVARD("crosshairimage", "", "Enables the use of an external/custom crosshair image"); cvar_t crosshairalpha = CVAR("crosshairalpha", "1"); -cvar_t gl_cshiftpercent = CVAR("gl_cshiftpercent", "100"); +static cvar_t gl_cshiftpercent = CVAR("gl_cshiftpercent", "100"); cvar_t gl_cshiftenabled = CVARFD("gl_polyblend", "1", CVAR_ARCHIVE, "Controls whether temporary whole-screen colour changes should be honoured or not. Change gl_cshiftpercent if you want to adjust the intensity.\nThis does not affect v_cshift commands sent from the server."); cvar_t gl_cshiftborder = CVARD("gl_polyblend_edgesize", "128", "This constrains colour shifts to the edge of the screen, with the value specifying the size of those borders."); -cvar_t v_bonusflash = CVARD("v_bonusflash", "1", "Controls the strength of temporary screen flashes when picking up items (gl_polyblend must be enabled)."); +static cvar_t v_bonusflash = CVARD("v_bonusflash", "1", "Controls the strength of temporary screen flashes when picking up items (gl_polyblend must be enabled)."); cvar_t v_contentblend = CVARFD("v_contentblend", "1", CVAR_ARCHIVE, "Controls the strength of underwater colour tints (gl_polyblend must be enabled)."); -cvar_t v_damagecshift = CVARD("v_damagecshift", "1", "Controls the strength of damage-taken colour tints (gl_polyblend must be enabled)."); -cvar_t v_quadcshift = CVARD("v_quadcshift", "1", "Controls the strength of quad-damage colour tints (gl_polyblend must be enabled)."); -cvar_t v_suitcshift = CVARD("v_suitcshift", "1", "Controls the strength of envirosuit colour tints (gl_polyblend must be enabled)."); -cvar_t v_ringcshift = CVARD("v_ringcshift", "1", "Controls the strength of ring-of-invisibility colour tints (gl_polyblend must be enabled)."); -cvar_t v_pentcshift = CVARD("v_pentcshift", "1", "Controls the strength of pentagram-of-protection colour tints (gl_polyblend must be enabled)."); -cvar_t v_gunkick = CVARD("v_gunkick", "0", "Controls the strength of view angle changes when firing weapons."); +static cvar_t v_damagecshift = CVARD("v_damagecshift", "1", "Controls the strength of damage-taken colour tints (gl_polyblend must be enabled)."); +static cvar_t v_quadcshift = CVARD("v_quadcshift", "1", "Controls the strength of quad-damage colour tints (gl_polyblend must be enabled)."); +static cvar_t v_suitcshift = CVARD("v_suitcshift", "1", "Controls the strength of envirosuit colour tints (gl_polyblend must be enabled)."); +static cvar_t v_ringcshift = CVARD("v_ringcshift", "1", "Controls the strength of ring-of-invisibility colour tints (gl_polyblend must be enabled)."); +static cvar_t v_pentcshift = CVARD("v_pentcshift", "1", "Controls the strength of pentagram-of-protection colour tints (gl_polyblend must be enabled)."); +static cvar_t v_gunkick = CVARD("v_gunkick", "0", "Controls the strength of view angle changes when firing weapons."); cvar_t v_gunkick_q2 = CVARD("v_gunkick_q2", "1", "Controls the strength of view angle changes when firing weapons (in Quake2)."); -cvar_t v_viewmodel_quake = CVARD("r_viewmodel_quake", "0", "Controls whether to use weird viewmodel movements from vanilla quake."); //name comes from MarkV. +static cvar_t v_viewmodel_quake = CVARD("r_viewmodel_quake", "0", "Controls whether to use weird viewmodel movements from vanilla quake."); //name comes from MarkV. cvar_t v_viewheight = CVARF("v_viewheight", "0", CVAR_ARCHIVE); -cvar_t v_projectionmode = CVARF("v_projectionmode", "0", CVAR_ARCHIVE); +static cvar_t v_projectionmode = CVARF("v_projectionmode", "0", CVAR_ARCHIVE); -cvar_t v_depthsortentities = CVARAD("v_depthsortentities", "0", "v_reorderentitiesrandomly", "Reorder entities for transparency such that the furthest entities are drawn first, allowing nearer transparent entities to draw over the top of them."); +static cvar_t v_depthsortentities = CVARAD("v_depthsortentities", "0", "v_reorderentitiesrandomly", "Reorder entities for transparency such that the furthest entities are drawn first, allowing nearer transparent entities to draw over the top of them."); -cvar_t scr_autoid = CVARD("scr_autoid", "1", "Display nametags above all players while spectating."); -cvar_t scr_autoid_team = CVARD("scr_autoid_team", "1", "Display nametags above team members. 0: off. 1: display with half-alpha if occluded. 2: hide when occluded."); -cvar_t scr_autoid_health = CVARD("scr_autoid_health", "1", "Display health as part of nametags (when known)."); -cvar_t scr_autoid_armour = CVARD("scr_autoid_armor", "1", "Display armour as part of nametags (when known)."); -cvar_t scr_autoid_weapon = CVARD("scr_autoid_weapon", "1", "Display the player's best weapon as part of their nametag (when known)."); -cvar_t scr_autoid_teamcolour = CVARD("scr_autoid_teamcolour", STRINGIFY(COLOR_BLUE), "The colour for the text on the nametags of team members."); -cvar_t scr_autoid_enemycolour = CVARD("scr_autoid_enemycolour", STRINGIFY(COLOR_WHITE), "The colour for the text on the nametags of non-team members."); +static cvar_t scr_autoid = CVARD("scr_autoid", "1", "Display nametags above all players while spectating."); +static cvar_t scr_autoid_team = CVARD("scr_autoid_team", "1", "Display nametags above team members. 0: off. 1: display with half-alpha if occluded. 2: hide when occluded."); +static cvar_t scr_autoid_health = CVARD("scr_autoid_health", "1", "Display health as part of nametags (when known)."); +static cvar_t scr_autoid_armour = CVARD("scr_autoid_armor", "1", "Display armour as part of nametags (when known)."); +static cvar_t scr_autoid_weapon = CVARD("scr_autoid_weapon", "1", "Display the player's best weapon as part of their nametag (when known)."); +static cvar_t scr_autoid_teamcolour = CVARD("scr_autoid_teamcolour", STRINGIFY(COLOR_BLUE), "The colour for the text on the nametags of team members."); +static cvar_t scr_autoid_enemycolour = CVARD("scr_autoid_enemycolour", STRINGIFY(COLOR_WHITE), "The colour for the text on the nametags of non-team members."); cvar_t chase_active = CVAR("chase_active", "0"); -cvar_t chase_back = CVAR("chase_back", "48"); -cvar_t chase_up = CVAR("chase_up", "24"); +static cvar_t chase_back = CVAR("chase_back", "48"); +static cvar_t chase_up = CVAR("chase_up", "24"); extern cvar_t cl_chasecam; -player_state_t *view_message; +static player_state_t *view_message; /* =============== @@ -206,8 +220,8 @@ float V_CalcBob (playerview_t *pv, qboolean queryold) //============================================================================= -cvar_t v_centermove = CVAR("v_centermove", "0.15"); -cvar_t v_centerspeed = CVAR("v_centerspeed","500"); +static cvar_t v_centermove = CVAR("v_centermove", "0.15"); +static cvar_t v_centerspeed = CVAR("v_centerspeed","500"); void V_StartPitchDrift (playerview_t *pv) @@ -325,12 +339,12 @@ void V_DriftPitch (playerview_t *pv) static void QDECL V_Gamma_Callback(struct cvar_s *var, char *oldvalue); -cshift_t cshift_empty = { {130,80,50}, 0 }; -cshift_t cshift_water = { {130,80,50}, 128 }; -cshift_t cshift_slime = { {0,25,5}, 150 }; -cshift_t cshift_lava = { {255,80,0}, 150 }; +static cshift_t cshift_empty = { {130,80,50}, 0 }; +static cshift_t cshift_water = { {130,80,50}, 128 }; +static cshift_t cshift_slime = { {0,25,5}, 150 }; +static cshift_t cshift_lava = { {255,80,0}, 150 }; -cshift_t cshift_server = { {130,80,50}, 0 }; +static cshift_t cshift_server = { {130,80,50}, 0 }; cvar_t v_gamma = CVARFCD("gamma", "1.0", CVAR_ARCHIVE|CVAR_RENDERERCALLBACK, V_Gamma_Callback, "Controls how bright the screen is. Setting this to anything but 1 without hardware gamma requires glsl support and can noticably harm your framerate."); cvar_t v_gammainverted = CVARFCD("v_gammainverted", "0", CVAR_ARCHIVE, V_Gamma_Callback, "Boolean that controls whether the gamma should be inverted (like quake) or not."); @@ -2248,9 +2262,9 @@ void V_RenderPlayerViews(playerview_t *pv) } */ for (viewnum = 0; viewnum < SIDEVIEWS; viewnum++) - if (vsec_scalex[viewnum].value>0&&vsec_scaley[viewnum].value>0 - && ((vsec_enabled[viewnum].value && vsec_enabled[viewnum].value != 2) //rearview if v2_enabled = 1 and not 2 - || (vsec_enabled[viewnum].value && pv->stats[STAT_VIEW2]&&viewnum==0))) //v2 enabled if v2_enabled is non-zero + if (sideview[viewnum].scalex.value>0&&sideview[viewnum].scaley.value>0 + && ((sideview[viewnum].enabled.value && sideview[viewnum].enabled.value != 2) //rearview if v2_enabled = 1 and not 2 + || (sideview[viewnum].enabled.value && pv->stats[STAT_VIEW2]&&viewnum==0))) //v2 enabled if v2_enabled is non-zero { vrect_t oldrect; vec3_t oldangles; @@ -2260,14 +2274,14 @@ void V_RenderPlayerViews(playerview_t *pv) float ofx; float ofy; - if (vsec_x[viewnum].value < 0) - vsec_x[viewnum].value = 0; - if (vsec_y[viewnum].value < 0) - vsec_y[viewnum].value = 0; + if (sideview[viewnum].x.value < 0) + sideview[viewnum].x.value = 0; + if (sideview[viewnum].y.value < 0) + sideview[viewnum].y.value = 0; - if (vsec_scalex[viewnum].value+vsec_x[viewnum].value > 1) + if (sideview[viewnum].scalex.value+sideview[viewnum].x.value > 1) continue; - if (vsec_scaley[viewnum].value+vsec_y[viewnum].value > 1) + if (sideview[viewnum].scaley.value+sideview[viewnum].y.value > 1) continue; oldrect = r_refdef.vrect; @@ -2276,10 +2290,10 @@ void V_RenderPlayerViews(playerview_t *pv) ofx = r_refdef.fov_x; ofy = r_refdef.fov_y; - r_refdef.vrect.x += r_refdef.vrect.width*vsec_x[viewnum].value; - r_refdef.vrect.y += r_refdef.vrect.height*vsec_y[viewnum].value; - r_refdef.vrect.width *= vsec_scalex[viewnum].value; - r_refdef.vrect.height *= vsec_scaley[viewnum].value; + r_refdef.vrect.x += r_refdef.vrect.width*sideview[viewnum].x.value; + r_refdef.vrect.y += r_refdef.vrect.height*sideview[viewnum].y.value; + r_refdef.vrect.width *= sideview[viewnum].scalex.value; + r_refdef.vrect.height *= sideview[viewnum].scaley.value; r_refdef.fov_x = 0; r_refdef.fov_y = 0; @@ -2321,10 +2335,10 @@ void V_RenderPlayerViews(playerview_t *pv) #endif { //rotate the view, keeping pitch and roll. - r_refdef.viewangles[YAW] += vsec_yaw[viewnum].value; - r_refdef.viewangles[ROLL] += sin(vsec_yaw[viewnum].value / 180 * 3.14) * r_refdef.viewangles[PITCH]; - r_refdef.viewangles[PITCH] *= -cos((vsec_yaw[viewnum].value / 180 * 3.14)+3.14); - if (vsec_enabled[viewnum].value!=2) + r_refdef.viewangles[YAW] += sideview[viewnum].yaw.value; + r_refdef.viewangles[ROLL] += sin(sideview[viewnum].yaw.value / 180 * 3.14) * r_refdef.viewangles[PITCH]; + r_refdef.viewangles[PITCH] *= -cos((sideview[viewnum].yaw.value / 180 * 3.14)+3.14); + if (sideview[viewnum].enabled.value!=2) { V_EditExternalModels(pv->viewentity, NULL, 0); R_RenderView (); @@ -2571,12 +2585,12 @@ void V_Init (void) #define SECONDARYVIEWVARS "Secondary view vars" for (i = 0; i < SIDEVIEWS; i++) { - Cvar_Register (&vsec_enabled[i], SECONDARYVIEWVARS); - Cvar_Register (&vsec_x[i], SECONDARYVIEWVARS); - Cvar_Register (&vsec_y[i], SECONDARYVIEWVARS); - Cvar_Register (&vsec_scalex[i], SECONDARYVIEWVARS); - Cvar_Register (&vsec_scaley[i], SECONDARYVIEWVARS); - Cvar_Register (&vsec_yaw[i], SECONDARYVIEWVARS); + Cvar_Register (&sideview[i].enabled, SECONDARYVIEWVARS); + Cvar_Register (&sideview[i].x, SECONDARYVIEWVARS); + Cvar_Register (&sideview[i].y, SECONDARYVIEWVARS); + Cvar_Register (&sideview[i].scalex, SECONDARYVIEWVARS); + Cvar_Register (&sideview[i].scaley, SECONDARYVIEWVARS); + Cvar_Register (&sideview[i].yaw, SECONDARYVIEWVARS); } #endif diff --git a/engine/client/view.h b/engine/client/view.h index cbb7c675..5b6391e6 100644 --- a/engine/client/view.h +++ b/engine/client/view.h @@ -40,3 +40,15 @@ void VQ2_AddLerpEntity(entity_t *in); void V_AddAxisEntity(entity_t *in); void CLQ1_AddShadow(entity_t *ent); int V_AddLight (int entsource, vec3_t org, float quant, float r, float g, float b); + +extern qbyte gammatable[256]; //for texture gamma. +extern qboolean gammaworks; + +extern cvar_t r_projection, ffov; +extern cvar_t crosshair, crosshairalpha, crosshairsize, crosshaircolor, crosshairimage, cl_crossx, cl_crossy, crosshaircorrect; +extern cvar_t v_viewheight; + +extern cvar_t v_gunkick_q2, gl_cshiftenabled, gl_cshiftborder; //q2 logic needs some of these cvars. + +extern cvar_t v_contentblend; //for menus +extern cvar_t chase_active; //I fucking hate this cvar. die die die. diff --git a/engine/common/common.c b/engine/common/common.c index 3cdc6800..eb3e3b1d 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -4643,7 +4643,7 @@ void COM_ParsePlusSets (qboolean docbuf) { #if defined(Q2CLIENT) || defined(Q2SERVER) if (!strcmp("basedir", com_argv[i+1])) - host_parms.basedir = com_argv[i]; + host_parms.basedir = com_argv[i+2]; else #endif Cvar_Get(com_argv[i+1], com_argv[i+2], (!strcmp(com_argv[i], "+seta"))?CVAR_ARCHIVE:0, "Cvars set on commandline"); @@ -4768,6 +4768,8 @@ void COM_InitArgv (int argc, const char **argv) //not allowed to tprint largv[com_argc] = argv[com_argc]; if (!Q_strcmp ("-safe", argv[com_argc])) safe = true; + + printf("Arg %i: %s\n", com_argc, argv[com_argc]); } if (safe) diff --git a/engine/common/config_fteqw.h b/engine/common/config_fteqw.h index 9248f9bb..fe8b9012 100644 --- a/engine/common/config_fteqw.h +++ b/engine/common/config_fteqw.h @@ -59,7 +59,7 @@ #define AVAIL_GZDEC //.gz decompression #define AVAIL_ZLIB //whether pk3s can be compressed or not. //#define AVAIL_BZLIB //whether pk3s can use bz2 compression -#define PACKAGE_DZIP //.dzip support for smaller demos (which are actually more like pak files and can store ANY type of file) +#define PACKAGE_DZIP //.dzip support for smaller demos (which are actually more like pak files and can store ANY type of file) //Map formats #define Q1BSPS //Quake1 diff --git a/engine/common/fs.c b/engine/common/fs.c index f264f780..37ecff53 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -3145,6 +3145,12 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths) #define Q3CFG "set v_gammainverted 0\nset com_parseutf8 0\ngl_overbright 2\nseta model sarge\nseta headmodel sarge\nseta handicap 100\ncom_nogamedirnativecode 0\n" //#define RMQCFG "sv_bigcoords 1\n" +#ifdef HAVE_SSL +#define UPDATEURL(g) "https://updates.triptohell.info/downloadables.php?game=" #g +#else +#define UPDATEURL(g) NULL +#endif + typedef struct { const char *argname; //used if this was used as a parameter. const char *exename; //used if the exe name contains this @@ -3190,31 +3196,31 @@ const gamemode_info_t gamemode_info[] = { #ifdef HAVE_LEGACY //cmdline switch exename protocol name(dpmaster) identifying file exec dir1 dir2 dir3 dir(fte) full name //standard quake - {"-quake", "q1", "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},QCFG,{"id1", "qw", "*fte"}, "Quake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, + {"-quake", "q1", "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},QCFG,{"id1", "qw", "*fte"}, "Quake", UPDATEURL(Q1) /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, //alternative name, because fmf file install names are messy when a single name is used for registry install path. - {"-afterquake", NULL, "FTE-Quake",{"id1/pak0.pak", "id1/quake.rc"}, QCFG,{"id1", "qw", "*fte"}, "Quake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, + {"-afterquake", NULL, "FTE-Quake",{"id1/pak0.pak", "id1/quake.rc"}, QCFG,{"id1", "qw", "*fte"}, "Quake", UPDATEURL(Q1) /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, //netquake-specific quake that avoids qw/ with its nquake fuckups, and disables nqisms - {"-netquake", "nq", "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},NQCFG,{"id1"}, "NetQuake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, + {"-netquake", "nq", "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},NQCFG,{"id1"}, "NetQuake", UPDATEURL(Q1) /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, //because we can. quakespasm is hopefully close enough... - {"-fitz", NULL, "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},NQCFG"fps_preset spasm\n",{"id1"}, "NetQuake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, + {"-fitz", NULL, "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},NQCFG"fps_preset spasm\n",{"id1"}, "NetQuake", UPDATEURL(Q1) /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, //because we can - {"-tenebrae", NULL, "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},NQCFG"fps_preset tenebrae\n",{"id1","qw","*fte"},"Tenebrae", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, + {"-tenebrae", NULL, "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},NQCFG"fps_preset tenebrae\n",{"id1","qw","*fte"},"Tenebrae", UPDATEURL(Q1) /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/}, //quake's mission packs should not be favoured over the base game nor autodetected //third part mods also tend to depend upon the mission packs for their huds, even if they don't use any other content. //and q2 also has a rogue/pak0.pak file that we don't want to find and cause quake2 to look like dissolution of eternity //so just make these require the same files as good ol' quake. - {"-hipnotic", "hipnotic", "FTE-Hipnotic", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "hipnotic", "*fte"}, "Quake: Scourge of Armagon"}, - {"-rogue", "rogue", "FTE-Rogue", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "rogue", "*fte"}, "Quake: Dissolution of Eternity"}, + {"-hipnotic", "hipnotic", "FTE-Hipnotic", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "hipnotic", "*fte"}, "Quake: Scourge of Armagon", UPDATEURL(Q1)}, + {"-rogue", "rogue", "FTE-Rogue", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "rogue", "*fte"}, "Quake: Dissolution of Eternity", UPDATEURL(Q1)}, //various quake-dependant non-standalone mods that require hacks //quoth needed an extra arg just to enable hipnotic hud drawing, it doesn't actually do anything weird, but most engines have a -quoth arg, so lets have one too. - {"-quoth", "quoth", "FTE-Quake", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "quoth", "*fte"}, "Quake: Quoth"}, - {"-nehahra", "nehahra", "FTE-Quake", {"id1/pak0.pak","id1/quake.rc"},NEHCFG, {"id1", "qw", "nehahra", "*fte"}, "Quake: Seal Of Nehahra"}, + {"-quoth", "quoth", "FTE-Quake", {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "quoth", "*fte"}, "Quake: Quoth", UPDATEURL(Q1)}, + {"-nehahra", "nehahra", "FTE-Quake", {"id1/pak0.pak","id1/quake.rc"},NEHCFG, {"id1", "qw", "nehahra", "*fte"}, "Quake: Seal Of Nehahra", UPDATEURL(Q1)}, //various quake-based standalone mods. {"-nexuiz", "nexuiz", "Nexuiz", {"nexuiz.exe"}, NEXCFG, {"data", "*ftedata"},"Nexuiz"}, {"-xonotic", "xonotic", "Xonotic", {"data/xonotic-data.pk3dir", - "data/xonotic-*data*.pk3"}, XONCFG, {"data", "*ftedata"},"Xonotic"}, + "data/xonotic-*data*.pk3"}, XONCFG, {"data", "*ftedata"},"Xonotic", UPDATEURL(Xonotic)}, // {"-spark", "spark", "Spark", {"base/src/progs.src", // "base/qwprogs.dat", // "base/pak0.pak"}, DMFCFG, {"base", }, "Spark"}, @@ -3226,17 +3232,17 @@ const gamemode_info_t gamemode_info[] = { #ifdef HEXEN2 //hexen2's mission pack generally takes precedence if both are installed. {"-portals", "h2mp", "FTE-H2MP", {"portals/hexen.rc", - "portals/pak3.pak"}, HEX2CFG,{"data1", "portals", "*fteh2"}, "Hexen II MP"}, - {"-hexen2", "hexen2", "FTE-Hexen2", {"data1/pak0.pak"}, HEX2CFG,{"data1", "*fteh2"}, "Hexen II"}, + "portals/pak3.pak"}, HEX2CFG,{"data1", "portals", "*fteh2"}, "Hexen II MP", UPDATEURL(H2)}, + {"-hexen2", "hexen2", "FTE-Hexen2", {"data1/pak0.pak"}, HEX2CFG,{"data1", "*fteh2"}, "Hexen II", UPDATEURL(H2)}, #endif #if defined(Q2CLIENT) || defined(Q2SERVER) - {"-quake2", "q2", "FTE-Quake2", {"baseq2/pak0.pak"}, Q2CFG, {"baseq2", "*fteq2"}, "Quake II"}, + {"-quake2", "q2", "FTE-Quake2", {"baseq2/pak0.pak"}, Q2CFG, {"baseq2", "*fteq2"}, "Quake II", UPDATEURL(Q2)}, //mods of the above that should generally work. {"-dday", "dday", "FTE-Quake2", {"dday/pak0.pak"}, Q2CFG, {"baseq2", "dday", "*fteq2"}, "D-Day: Normandy"}, #endif #if defined(Q3CLIENT) || defined(Q3SERVER) - {"-quake3", "q3", "FTE-Quake3", {"baseq3/pak0.pk3"}, Q3CFG, {"baseq3", "*fteq3"}, "Quake III Arena"}, + {"-quake3", "q3", "FTE-Quake3", {"baseq3/pak0.pk3"}, Q3CFG, {"baseq3", "*fteq3"}, "Quake III Arena", UPDATEURL(Q3)}, //the rest are not supported in any real way. maps-only mostly, if that // {"-quake4", "q4", "FTE-Quake4", {"q4base/pak00.pk4"}, NULL, {"q4base", "*fteq4"}, "Quake 4"}, // {"-et", NULL, "FTE-EnemyTerritory", {"etmain/pak0.pk3"}, NULL, {"etmain", "*fteet"}, "Wolfenstein - Enemy Territory"}, diff --git a/engine/common/net.h b/engine/common/net.h index 0ed4269d..7c53ba55 100644 --- a/engine/common/net.h +++ b/engine/common/net.h @@ -191,6 +191,7 @@ qboolean NET_DTLS_Disconnect(struct ftenet_connections_s *col, netadr_t *to); void NET_DTLS_Timeouts(struct ftenet_connections_s *col); #endif extern cvar_t timeout; +extern cvar_t tls_ignorecertificateerrors; //evil evil evil. //============================================================================ diff --git a/engine/common/net_ssl_gnutls.c b/engine/common/net_ssl_gnutls.c index 6cb58eaa..f6d1f3d0 100644 --- a/engine/common/net_ssl_gnutls.c +++ b/engine/common/net_ssl_gnutls.c @@ -430,25 +430,32 @@ typedef struct #define CAFILE "/etc/ssl/certs/ca-certificates.crt" -static qboolean QDECL SSL_Close(vfsfile_t *vfs) +static void SSL_Close(vfsfile_t *vfs) { gnutlsfile_t *file = (void*)vfs; - file->handshaking = true; + file->handshaking = true; //so further attempts to use it will fail. if (file->session) { qgnutls_bye (file->session, file->datagram?GNUTLS_SHUT_WR:GNUTLS_SHUT_RDWR); qgnutls_deinit(file->session); + file->session = NULL; } - file->session = NULL; if (file->stream) + { VFS_CLOSE(file->stream); - file->stream = NULL; - Z_Free(file); + file->stream = NULL; + } +} +static qboolean QDECL SSL_CloseFile(vfsfile_t *vfs) +{ + SSL_Close(vfs); + Z_Free(vfs); return true; } +static const qbyte updates_triptohell_certdata[962] = "\x30\x82\x03\xbe\x30\x82\x02\xa6\xa0\x03\x02\x01\x02\x02\x09\x00\xf4\x4e\x13\x08\x32\x85\xb5\x19\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x74\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x4b\x31\x10\x30\x0e\x06\x03\x55\x04\x08\x0c\x07\x45\x6e\x67\x6c\x61\x6e\x64\x31\x0f\x30\x0d\x06\x03\x55\x04\x07\x0c\x06\x4c\x6f\x6e\x64\x6f\x6e\x31\x0e\x30\x0c\x06\x03\x55\x04\x0a\x0c\x05\x46\x54\x45\x51\x57\x31\x10\x30\x0e\x06\x03\x55\x04\x0b\x0c\x07\x55\x70\x64\x61\x74\x65\x73\x31\x20\x30\x1e\x06\x03\x55\x04\x03\x0c\x17\x75\x70\x64\x61\x74\x65\x73\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x39\x30\x35\x33\x31\x31\x30\x30\x39\x31\x39\x5a\x17\x0d\x32\x39\x30\x35\x32\x38\x31\x30\x30\x39\x31\x39\x5a\x30\x74\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x4b\x31\x10\x30\x0e\x06\x03\x55\x04\x08\x0c\x07\x45\x6e\x67\x6c\x61\x6e\x64\x31\x0f\x30\x0d\x06\x03\x55\x04\x07\x0c\x06\x4c\x6f\x6e\x64\x6f\x6e\x31\x0e\x30\x0c\x06\x03\x55\x04\x0a\x0c\x05\x46\x54\x45\x51\x57\x31\x10\x30\x0e\x06\x03\x55\x04\x0b\x0c\x07\x55\x70\x64\x61\x74\x65\x73\x31\x20\x30\x1e\x06\x03\x55\x04\x03\x0c\x17\x75\x70\x64\x61\x74\x65\x73\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xaa\xb5\x9c\xcc\xe8\xbd\xad\x1c\x7f\x6b\x1c\xc9\x04\xe6\x2c\x10\xac\x99\xeb\x67\x0b\x9c\x24\xb8\x90\x77\xde\xaa\x44\xa2\x15\x31\x61\x52\x4d\xeb\x8f\x56\xb8\xaf\xc1\x2f\x66\xdd\x55\x8d\xd6\xec\xc3\xa4\x93\x8c\x86\xeb\xaf\x89\x17\x19\x2e\x6c\xc2\xd4\xf9\x92\xac\x2e\x73\x99\x56\xf2\xc3\xc4\x14\x56\x4a\x0d\xbe\x51\xc9\x8f\x4e\x92\x20\x2b\xae\x05\x0c\x7e\x87\xa5\x02\xe1\xc0\x7d\x71\xa7\x38\x72\x47\x3f\x31\x07\x90\xb0\x6d\xcf\xae\xb6\xdb\xeb\x39\xaa\x5f\xb4\x6f\x0c\x63\x2a\x21\x65\x36\xaa\x6b\xac\x97\xb6\xbe\x20\xa4\x87\x36\xbf\x35\xc5\xa6\x31\xe4\x9d\x85\xf3\xae\x8f\x6b\xf8\x59\x75\x0f\xb5\x5d\x31\x40\x39\x2e\xea\x48\x65\xdf\x91\xe3\x06\xfb\xb2\xec\xdc\xd0\x90\x94\xd6\x68\x4d\x62\x25\x9a\x3d\xc3\x74\x17\x7d\x0e\xe2\x1e\x34\xbf\x02\x85\xc4\x40\x88\x91\xeb\xe0\xf5\x92\x56\x42\x4f\xa6\x4c\x17\x88\xb2\x89\xd2\xec\x60\x54\x97\x20\x0a\xca\xf0\xd1\x33\x3f\x5b\x66\xb7\x8a\x42\x72\x67\xc9\x47\x83\xb3\xd4\x1e\xa8\x44\xbf\x5a\x1a\x85\x79\xee\xf8\x80\xde\x19\x1d\xc5\xdd\x50\x42\x10\x17\xb7\xc3\xd4\xf1\xcb\x8a\xb8\x71\x55\x31\x02\x03\x01\x00\x01\xa3\x53\x30\x51\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x2c\x68\x81\x8f\x40\x8c\x40\x42\x9f\xbd\xc5\x0b\x36\xfb\xe2\x76\xeb\x8d\xb4\xf3\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x2c\x68\x81\x8f\x40\x8c\x40\x42\x9f\xbd\xc5\x0b\x36\xfb\xe2\x76\xeb\x8d\xb4\xf3\x30\x0f\x06\x03\x55\x1d\x13\x01\x01\xff\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x0c\x01\x35\x32\xb8\xe7\x96\xba\x3e\x53\x8c\x78\x41\xab\x9b\x7f\xe2\x7a\x80\x5a\xc9\x88\x06\x29\x28\xf9\x50\x7f\xcc\xb6\xcc\x34\x03\x45\x32\x79\x63\xe7\xde\x9c\x46\x29\xf4\xaf\x32\x72\x26\x11\xa0\x7b\x52\x23\x0a\xd5\x51\x91\x79\xf2\x50\x61\x80\x72\x40\xe7\x85\xb0\x13\x1d\x98\xdb\x14\x23\x59\xa4\xbc\xe9\xe0\x1b\xc0\x38\x33\x96\xbc\xbb\x56\x47\xcc\xbd\xe8\x40\x49\xdf\xaa\x64\x7e\x29\xe5\x9d\x40\xa5\x1a\x5c\x45\x1f\x5a\x77\x59\xfe\x7a\xb8\xf8\x4d\xc4\x9b\x31\xe6\x08\xc4\x95\xfa\x91\x8f\x91\x9f\x3c\xc4\x82\xb9\xf1\x6d\xa8\xa6\xc4\x09\xb1\xe9\xa8\x60\x9b\xaa\x4c\x79\xf0\x99\xb8\xad\x63\xb1\xe4\xc0\xaf\xf0\xdf\xc9\x33\x53\x4d\x09\xe4\x3f\x8d\x9e\x38\xc6\x93\xff\xcc\x91\x46\x7e\x67\x28\x61\xaa\xc7\x0b\xe2\xd8\x8c\xe4\xec\x8d\x44\xe7\x6a\x14\x78\x91\x7d\xec\xc7\x07\xed\xc9\x58\xdb\x35\xd4\x70\x06\x06\x39\x8d\x4b\x80\x2c\xb6\xa8\x79\x5c\x94\x15\x6c\x34\x06\x5c\xd7\xc5\x42\xc0\x72\x01\x71\x07\xf5\x25\x6a\xd0\x24\x86\xcd\x1b\x21\x07\xae\x40\xf8\xc1\xe4\x23\x0d\xa0\xc0\x23\xf0\x07\xba\xdc\x34\x5d\x47\xcf\x4b\x7b\xd5\x5d"; static const qbyte fte_triptohell_certdata[917] = "\x30\x82\x03\x91\x30\x82\x02\x79\xa0\x03\x02\x01\x02\x02\x09\x00\xb5\x71\x47\x8d\x5e\x66\xf1\xd9\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x5f\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x46\x54\x45\x31\x1c\x30\x1a\x06\x03\x55\x04\x03\x0c\x13\x66\x74\x65\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x35\x30\x30\x35\x38\x31\x34\x5a\x17\x0d\x31\x37\x30\x33\x30\x34\x30\x30\x35\x38\x31\x34\x5a\x30\x5f\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x46\x54\x45\x31\x1c\x30\x1a\x06\x03\x55\x04\x03\x0c\x13\x66\x74\x65\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xdd\xb8\x7c\x69\x3d\x63\x95\xe3\x88\x15\xfd\xad\x93\x5e\x6b\x97\xfb\x74\xba\x1f\x83\x33\xe5\x8a\x8d\x8f\xb0\xbf\xf9\xd3\xa1\x2c\x65\x53\xa7\xef\xd3\x0f\xdc\x03\x60\x0a\x40\xef\xa8\xef\x3f\xb3\xd9\x8d\x31\x39\x12\x8a\xd8\x0e\x24\x8f\xe5\x58\x26\x86\x4c\x76\x6c\x59\x9a\xab\xea\x1c\x3d\xfb\x62\x62\xad\xaf\xd6\x00\x33\x76\x2d\xbb\xeb\xe8\xec\xb4\x76\x4f\xb0\xbe\xcf\xf0\x46\x94\x40\x02\x99\xd4\xb2\x71\x71\xd6\xf5\x1f\xc3\x4f\x1e\x1e\xb4\x0d\x82\x49\xc4\xa2\xdc\xae\x6f\x4e\x3a\xf9\x0e\xdd\xf4\xd2\x53\xe3\xe7\x7d\x58\x79\xf4\xce\x1f\x6c\xac\x81\x8c\x8c\xe1\x03\x5b\x22\x56\x92\x19\x4f\x74\xc0\x36\x41\xac\x1b\xfa\x9e\xf7\x2a\x0f\xd6\x4b\xcc\x9a\xca\x67\x87\xb7\x95\xdf\xb7\xd4\x7d\x8c\xcc\xa9\x25\xde\xdd\x8c\x1b\xd7\x32\xf2\x84\x25\x46\x7b\x10\x55\xf9\x80\xfd\x5d\xad\xab\xf9\x4c\x1f\xc0\xa5\xd1\x3f\x01\x86\x4d\xfa\x57\xab\x7a\x6d\xec\xf1\xdb\xf4\xad\xf2\x33\xcd\xa0\xed\xfe\x1b\x27\x55\x56\xba\x8c\x47\x70\x16\xd5\x75\x17\x8e\x80\xaa\x49\x5e\x93\x83\x1d\x6f\x1f\x2c\xf7\xa7\x64\xe6\x2e\x88\x8e\xff\x70\x5a\x41\x52\xae\x93\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x4e\x76\x4a\xce\x7b\x45\x14\x39\xeb\x9c\x28\x56\xb5\x7b\x8a\x18\x6f\x22\x17\x82\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x4e\x76\x4a\xce\x7b\x45\x14\x39\xeb\x9c\x28\x56\xb5\x7b\x8a\x18\x6f\x22\x17\x82\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x48\x22\x65\xed\x2e\xc5\xed\xbb\xe9\x40\x6c\x80\xc4\x63\x19\xd1\x00\xb4\x30\x34\x17\x7c\x7c\xbd\x1b\xc5\xa9\x43\x0c\x92\x6e\xd6\x2d\x11\x6c\x0d\xa6\xda\x30\xe9\xf7\x46\x7b\x01\xe4\x53\x23\xae\x88\xd1\xf2\xed\xca\x84\x06\x19\x97\xb9\x06\xfb\xda\xec\x72\x2d\x15\x20\xd2\x8f\x66\xad\xb5\xdd\x4b\x4f\xdf\x7e\xaf\xa3\x6c\x7f\x53\x32\x8f\xe2\x19\x5c\x44\x98\x86\x31\xee\xb4\x03\xe7\x27\xa1\x83\xab\xc3\xce\xb4\x9a\x01\xbe\x8c\x64\x2e\x2b\xe3\x4e\x55\xdf\x95\xeb\x16\x87\xbd\xfa\x11\xa2\x3e\x38\x92\x97\x36\xe9\x65\x60\xf3\xac\x68\x44\xb3\x51\x54\x3a\x42\xa8\x98\x9b\xee\x1b\x9e\x79\x6a\xaf\xc0\xbe\x41\xc4\xb1\x96\x42\xd9\x94\xef\x49\x5b\xbe\x2d\x04\xb9\xfb\x92\xbb\xdc\x0e\x29\xfd\xee\xa9\x68\x09\xf9\x9f\x69\x8b\x3d\xe1\x4b\xee\x24\xf9\xfe\x02\x3a\x0a\xb8\xcd\x6c\x07\x43\xa9\x4a\xe7\x03\x34\x2e\x72\xa7\x81\xaa\x40\xa9\x98\x5d\x97\xee\x2a\x99\xc6\x8f\xe8\x6f\x98\xa2\x85\xc9\x0d\x04\x19\x43\x6a\xd3\xc7\x15\x4c\x4b\xbc\xa5\xb8\x9f\x38\xf3\x43\x83\x0c\xef\x97\x6e\xa6\x20\xde\xc5\xd3\x1e\x3e\x5d\xcd\x58\x3d\x5c\x55\x7a\x90\x94"; static const qbyte triptohell_certdata[933] = "\x30\x82\x03\xa1\x30\x82\x02\x89\xa0\x03\x02\x01\x02\x02\x09\x00\xea\xb7\x13\xcf\x55\xe5\xe8\x8c\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x31\x18\x30\x16\x06\x03\x55\x04\x03\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x35\x30\x30\x35\x38\x33\x37\x5a\x17\x0d\x31\x37\x30\x33\x30\x34\x30\x30\x35\x38\x33\x37\x5a\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x31\x18\x30\x16\x06\x03\x55\x04\x03\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xd8\x77\x62\xf6\x74\xa7\x75\xde\xda\x09\xae\x9e\x76\x7a\xc6\x2a\xcf\x9a\xbe\xc6\xb9\x6d\xe2\xca\x0f\x2d\x95\xb8\x89\x93\xf7\x50\x64\x92\x7d\x95\x34\xe4\x6e\xef\x52\x56\xef\x13\x9a\x3a\xae\x84\x5b\x57\x82\x04\x86\x74\xbd\x4e\x38\x32\x56\x00\xd6\x34\x9c\x23\xd6\x81\x8e\x29\x77\x45\x61\x20\xdf\x28\xf8\xe5\x61\x83\xec\xe6\xa0\x1a\x75\xa8\x3b\x53\x6f\xc4\x09\x61\x66\x3a\xf0\x81\xbf\x2c\xf5\x8e\xf1\xe2\x35\xe4\x24\x7f\x16\xcc\xce\x60\xa2\x42\x6e\xc2\x3a\x29\x75\x6c\x79\xb0\x99\x9c\xe2\xfe\x27\x32\xb6\xf7\x0d\x71\xfd\x62\x9d\x54\x7c\x40\xb2\xf5\xa0\xa4\x25\x31\x8d\x65\xfd\x3f\x3b\x9b\x7e\x84\x74\x17\x3c\x1f\xec\x50\xcf\x75\xb8\x5c\xca\xfc\x0f\xe8\x47\xd8\x64\xec\x5f\x6c\x45\x9a\x55\x49\x97\x3f\xcb\x49\x34\x71\x0a\x12\x13\xbc\x3d\x53\x81\x17\x9a\x92\x44\x91\x07\xc2\xef\x6d\x64\x86\x5d\xfd\x67\xd5\x99\x38\x95\x46\x74\x6d\xb6\xbf\x29\xc9\x5b\xac\xb1\x46\xd6\x9e\x57\x5c\x7b\x24\x91\xf4\x7c\xe4\x01\x31\x8c\xec\x79\x94\xb7\x3f\xd2\x93\x6d\xe2\x69\xbe\x61\x44\x2e\x8f\x1a\xdc\xa8\x97\xf5\x81\x8e\x0c\xe1\x00\xf2\x71\x51\xf3\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x18\xb2\x6b\x63\xcc\x17\x54\xf6\xf0\xb6\x9e\x62\xa4\x35\xcf\x47\x74\x13\x29\xbf\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x18\xb2\x6b\x63\xcc\x17\x54\xf6\xf0\xb6\x9e\x62\xa4\x35\xcf\x47\x74\x13\x29\xbf\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x7f\x24\x18\x8a\x79\xee\xf9\xeb\xed\x29\x1e\x21\x15\x8a\x53\xc9\xb7\xec\x30\xc4\x85\x9f\x45\x85\x26\x36\xb7\x07\xf3\xf1\xff\x3b\x89\x05\x0a\xd4\x30\x68\x31\x68\x33\xdd\xf6\x58\xa3\x85\x9f\x49\x50\x76\x9a\xc5\x79\x13\xe1\x4d\x67\x0c\xf3\x92\xf0\x1d\x02\x1f\xc4\x5c\xd4\xa1\x0c\x57\xdf\x46\x84\x43\x9f\xb0\xe2\x91\x62\xa8\xe0\x86\x0d\x47\xe1\xd9\x60\x01\xc4\xe0\xda\x6f\x06\x0a\xad\x38\xf3\x66\x68\xc5\xe2\x66\x3e\x47\x83\x65\x64\xcd\xff\xf3\xbb\xa7\xfa\x23\xf1\x82\x5e\x06\x6a\x91\x37\x51\xcd\xb9\x95\x20\x89\xff\xa1\x54\xb2\x76\xcf\x8e\xe1\xcd\x13\x93\x13\xd1\xda\x0d\x0d\xbc\x0f\xd5\x11\x26\xd6\xaf\x60\x0f\x4d\x8a\x4f\x28\xee\x6c\xf1\x99\xdc\xed\x16\xdc\x87\x26\xfd\x23\x8a\xb8\xb0\x20\x0e\xe2\x32\xf5\x8e\xb0\x65\x98\x13\xb8\x4b\x39\x7c\x8c\x98\xa2\x29\x75\x48\x3a\x89\xf9\x61\x77\x6c\x2d\x84\x41\x40\x17\xa6\x50\xc5\x09\x63\x10\xe7\x09\xd4\x5c\xdd\x0e\x71\x16\xaf\xb1\x32\xe4\xc0\xe6\xea\xfd\x26\x55\x07\x40\x95\x84\x48\x62\x04\x10\x92\xb2\xd9\x27\xfb\x8a\xf3\x7c\xe6\xfe\xd4\xfc\xa6\x33\x79\x01\x5c\xc3\x1f\x80\xa8\xf3"; static struct @@ -459,9 +466,10 @@ static struct } knowncerts[] = { {"triptohell.info", sizeof(triptohell_certdata), triptohell_certdata}, {"fte.triptohell.info", sizeof(fte_triptohell_certdata), fte_triptohell_certdata}, + {"updates.triptohell.info", sizeof(updates_triptohell_certdata), updates_triptohell_certdata}, }; -static int SSL_CheckUserTrust(gnutls_session_t session, gnutlsfile_t *file, int ret) +static qboolean SSL_CheckUserTrust(gnutls_session_t session, gnutlsfile_t *file, int *errorcode) { #ifdef HAVE_CLIENT //when using dtls, we expect self-signed certs and persistent trust. @@ -480,22 +488,23 @@ static int SSL_CheckUserTrust(gnutls_session_t session, gnutlsfile_t *file, int certsize += certlist[j].size; } if (CertLog_ConnectOkay(file->certname, certdata, certsize)) - ret = 0; //user has previously authorised it. + *errorcode = 0; //user has previously authorised it. else - ret = GNUTLS_E_CERTIFICATE_ERROR; //user didn't trust it yet + *errorcode = GNUTLS_E_CERTIFICATE_ERROR; //user didn't trust it yet free(certdata); + return true; } #endif - return ret; + return false; } static int QDECL SSL_CheckCert(gnutls_session_t session) { gnutlsfile_t *file = qgnutls_session_get_ptr (session); unsigned int certstatus; - cvar_t *tls_ignorecertificateerrors; qboolean preverified = false; + int errcode = GNUTLS_E_CERTIFICATE_ERROR; size_t i; for (i = 0; i < countof(knowncerts); i++) @@ -554,13 +563,16 @@ static int QDECL SSL_CheckCert(gnutls_session_t session) return 0; if (certstatus == 0) return SSL_CheckUserTrust(session, file, 0); - if (certstatus == (GNUTLS_CERT_INVALID|GNUTLS_CERT_SIGNER_NOT_FOUND) && SSL_CheckUserTrust(session, file, GNUTLS_E_CERTIFICATE_ERROR)) - return 0; + if (certstatus == (GNUTLS_CERT_INVALID|GNUTLS_CERT_SIGNER_NOT_FOUND)) + { + if (SSL_CheckUserTrust(session, file, &errcode)) + return errcode; + } type = qgnutls_certificate_type_get (session); if (qgnutls_certificate_verification_status_print(certstatus, type, &out, 0) >= 0) { - Con_Printf("%s: %s (%x)\n", file->certname, out.data, certstatus); + Con_Printf(CON_ERROR "%s: %s (%x)\n", file->certname, out.data, certstatus); //looks like its static anyway. qgnutls_free(out.data); #else @@ -585,30 +597,29 @@ static int QDECL SSL_CheckCert(gnutls_session_t session) return 0; if (certstatus & GNUTLS_CERT_SIGNER_NOT_FOUND) - Con_Printf("%s: Certificate authority is not recognised\n", file->certname); + Con_Printf(CON_ERROR "%s: Certificate authority is not recognised\n", file->certname); else if (certstatus & GNUTLS_CERT_INSECURE_ALGORITHM) - Con_Printf("%s: Certificate uses insecure algorithm\n", file->certname); + Con_Printf(CON_ERROR "%s: Certificate uses insecure algorithm\n", file->certname); else if (certstatus & (GNUTLS_CERT_REVOCATION_DATA_ISSUED_IN_FUTURE|GNUTLS_CERT_REVOCATION_DATA_SUPERSEDED|GNUTLS_CERT_EXPIRED|GNUTLS_CERT_REVOKED|GNUTLS_CERT_NOT_ACTIVATED)) - Con_Printf("%s: Certificate has expired or was revoked or not yet valid\n", file->certname); + Con_Printf(CON_ERROR "%s: Certificate has expired or was revoked or not yet valid\n", file->certname); else if (certstatus & GNUTLS_CERT_SIGNATURE_FAILURE) - Con_Printf("%s: Certificate signature failure\n", file->certname); + Con_Printf(CON_ERROR "%s: Certificate signature failure\n", file->certname); else - Con_Printf("%s: Certificate error\n", file->certname); + Con_Printf(CON_ERROR "%s: Certificate error\n", file->certname); #endif - tls_ignorecertificateerrors = Cvar_Get("tls_ignorecertificateerrors", "0", CVAR_NOTFROMSERVER, "TLS"); - if (tls_ignorecertificateerrors && tls_ignorecertificateerrors->ival) + if (tls_ignorecertificateerrors.ival) { - Con_Printf("%s: Ignoring certificate errors (tls_ignorecertificateerrors is %i)\n", file->certname, tls_ignorecertificateerrors->ival); + Con_Printf(CON_ERROR "%s: Ignoring certificate errors (tls_ignorecertificateerrors is %i)\n", file->certname, tls_ignorecertificateerrors.ival); return 0; } } else - Con_DPrintf("%s: certificate is for a different domain\n", file->certname); + Con_DPrintf(CON_ERROR "%s: certificate is for a different domain\n", file->certname); } } - Con_DPrintf("%s: rejecting certificate\n", file->certname); - return GNUTLS_E_CERTIFICATE_ERROR; + Con_DPrintf(CON_ERROR "%s: rejecting certificate\n", file->certname); + return errcode; } //return 1 to read data. @@ -1104,7 +1115,7 @@ vfsfile_t *GNUTLS_OpenVFS(const char *hostname, vfsfile_t *source, qboolean isse return NULL; } newf->stream = source; - newf->funcs.Close = SSL_Close; + newf->funcs.Close = SSL_CloseFile; newf->funcs.Flush = NULL; newf->funcs.GetLen = SSL_GetLen; newf->funcs.ReadBytes = SSL_Read; @@ -1131,7 +1142,7 @@ int GNUTLS_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize) { gnutls_datum_t cb; gnutlsfile_t *f = (gnutlsfile_t*)vf; - if (vf->Close != SSL_Close) + if (vf->Close != SSL_CloseFile) return -1; //err, not a tls connection. if (qgnutls_session_channel_binding(f->session, GNUTLS_CB_TLS_UNIQUE, &cb)) diff --git a/engine/common/net_ssl_winsspi.c b/engine/common/net_ssl_winsspi.c index b6877afe..c601e65c 100644 --- a/engine/common/net_ssl_winsspi.c +++ b/engine/common/net_ssl_winsspi.c @@ -7,8 +7,6 @@ Its also meant to be supported from some RDP server patch on win7, but I can't g I've given up for now. */ -cvar_t *tls_ignorecertificateerrors; - #include "winquake.h" #define SECURITY_WIN32 #include @@ -101,8 +99,6 @@ void SSL_Init(void) {NULL, NULL} }; - tls_ignorecertificateerrors = Cvar_Get("tls_ignorecertificateerrors", "0", CVAR_NOTFROMSERVER, "TLS"); - if (!secur.lib) secur.lib = Sys_LoadLibrary("secur32.dll", secur_functable); if (!crypt.lib) @@ -390,6 +386,7 @@ static void SSPI_Encode(sslfile_t *f) //these are known sites that use self-signed certificates, or are special enough that we don't trust corporate networks to hack in their own certificate authority for a proxy/mitm //old static const qbyte triptohell_certdata[933] = "\x30\x82\x03\xa1\x30\x82\x02\x89\xa0\x03\x02\x01\x02\x02\x09\x00\x8b\xd0\x05\x63\x62\xd1\x6a\xe3\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x42\x44\x31\x0c\x30\x0a\x06\x03\x55\x04\x08\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x07\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0b\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x03\x0c\x03\x42\x61\x64\x31\x12\x30\x10\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x03\x42\x61\x64\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x34\x32\x32\x34\x32\x34\x37\x5a\x17\x0d\x32\x34\x31\x32\x32\x31\x32\x32\x34\x32\x34\x37\x5a\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x42\x44\x31\x0c\x30\x0a\x06\x03\x55\x04\x08\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x07\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x0b\x0c\x03\x42\x61\x64\x31\x0c\x30\x0a\x06\x03\x55\x04\x03\x0c\x03\x42\x61\x64\x31\x12\x30\x10\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16\x03\x42\x61\x64\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xaf\x10\x33\xfa\x39\xf5\xae\x2c\x91\x0e\x20\xe6\x3c\x5c\x7c\x1e\xeb\x16\x50\x2f\x05\x30\xfe\x67\xee\xa9\x00\x54\xd9\x4a\x86\xe6\xba\x80\xfb\x1a\x80\x08\x7e\x7b\x13\xe5\x1a\x18\xc9\xd4\x70\xbd\x5d\xc4\x38\xef\x64\xf1\x90\x2c\x53\x49\x93\x24\x36\x3e\x11\x59\x69\xa6\xdf\x37\xb2\x54\x82\x28\x3e\xdd\x30\x75\xa0\x18\xd8\xe1\xf5\x52\x73\x12\x5b\x37\x68\x1c\x59\xbd\x8c\x73\x66\x47\xbc\xcb\x9c\xfe\x38\x92\x8f\x74\xe9\xd1\x2f\x96\xd2\x5d\x6d\x11\x59\xb2\xdc\xbd\x8c\x37\x5b\x22\x76\x98\xe7\xbe\x08\xef\x1e\x99\xc4\xa9\x77\x2c\x9c\x0e\x08\x3c\x8e\xab\x97\x0c\x6a\xd7\x03\xab\xfd\x4a\x1e\x95\xb2\xc2\x9c\x3a\x16\x65\xd7\xaf\x45\x5f\x6e\xe7\xce\x51\xba\xa0\x60\x43\x0e\x07\xc5\x0b\x0a\x82\x05\x26\xc4\x92\x0a\x27\x5b\xfc\x57\x6c\xdf\xe2\x54\x8a\xef\x38\xf1\xf8\xc4\xf8\x51\x16\x27\x1f\x78\x89\x7c\x5b\xd7\x53\xcd\x9b\x54\x2a\xe6\x71\xee\xe4\x56\x2e\xa4\x09\x1a\x61\xf7\x0f\x97\x22\x94\xd7\xef\x21\x6c\xe6\x81\xfb\x54\x5f\x09\x92\xac\xd2\x7c\xab\xd5\xa9\x81\xf4\xc9\xb7\xd6\xbf\x68\xf8\x4f\xdc\xf3\x60\xa3\x3b\x29\x92\x9e\xdd\xa2\xa3\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x19\xed\xd0\x7b\x16\xaf\xb5\x0c\x9a\xe8\xd3\x46\x2e\x3c\x64\x29\xb6\xc1\x73\x5a\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x19\xed\xd0\x7b\x16\xaf\xb5\x0c\x9a\xe8\xd3\x46\x2e\x3c\x64\x29\xb6\xc1\x73\x5a\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x05\x05\x00\x03\x82\x01\x01\x00\x62\xa7\x26\xeb\xd4\x03\x29\x9c\x09\x33\x69\x7a\x9c\x65\x68\xec\x4c\xb9\x06\xeb\x1e\x51\x6f\x78\x20\xdc\xf6\x44\x5e\x06\x6e\x53\x87\x73\xe6\x14\x15\xb9\x17\x74\x67\xe0\x4e\x48\x38\xbc\x1c\xbd\xd0\xad\xd6\xbd\x8c\xf0\x3a\xe0\x13\x73\x19\xad\x8b\x79\x68\x67\x65\x9b\x7a\x4c\x81\xfb\xd9\x92\x77\x89\xb5\xb0\x53\xb0\xa5\xf7\x2d\x8e\x29\x60\x31\xd1\x9b\x2f\x63\x8a\x5f\x64\xc1\x61\xd5\xb7\xdf\x70\x3b\x2b\xf6\x1a\x96\xb9\xa7\x08\xca\x87\xa6\x8c\x60\xca\x6e\xd7\xee\xba\xef\x89\x0b\x93\xd5\xfd\xfc\x14\xba\xef\x27\xba\x90\x11\x90\xf7\x25\x70\xe7\x4e\xf4\x9c\x13\x27\xc1\xa7\x8e\xd9\x66\x43\x72\x20\x5b\xe1\x5c\x73\x74\xf5\x33\xf2\xa5\xf6\xe1\xd5\xac\xf3\x67\x5c\xe7\xd4\x0a\x8d\x91\x73\x03\x3e\x9d\xbc\x96\xc3\x0c\xdb\xd5\x77\x6e\x76\x44\x69\xaf\x24\x0f\x4f\x8b\x47\x36\x8b\xc3\xd6\x36\xdd\x26\x5a\x9c\xdd\x9c\x43\xee\x29\x43\xdd\x75\x2f\x19\x52\xfc\x1d\x24\x9c\x13\x29\x99\xa0\x6d\x7a\x95\xcc\xa0\x58\x86\xd8\xc5\xb9\xa3\xc2\x3d\x64\x1d\x85\x8a\xca\x53\x55\x8e\x9a\x6d\xc9\x91\x73\xf4\xe1\xe1\xa4\x9b\x76\xfc\x7f\x63\xc2\xb9\x23"; +static const qbyte updates_triptohell_certdata[962] = "\x30\x82\x03\xbe\x30\x82\x02\xa6\xa0\x03\x02\x01\x02\x02\x09\x00\xf4\x4e\x13\x08\x32\x85\xb5\x19\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x74\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x4b\x31\x10\x30\x0e\x06\x03\x55\x04\x08\x0c\x07\x45\x6e\x67\x6c\x61\x6e\x64\x31\x0f\x30\x0d\x06\x03\x55\x04\x07\x0c\x06\x4c\x6f\x6e\x64\x6f\x6e\x31\x0e\x30\x0c\x06\x03\x55\x04\x0a\x0c\x05\x46\x54\x45\x51\x57\x31\x10\x30\x0e\x06\x03\x55\x04\x0b\x0c\x07\x55\x70\x64\x61\x74\x65\x73\x31\x20\x30\x1e\x06\x03\x55\x04\x03\x0c\x17\x75\x70\x64\x61\x74\x65\x73\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x39\x30\x35\x33\x31\x31\x30\x30\x39\x31\x39\x5a\x17\x0d\x32\x39\x30\x35\x32\x38\x31\x30\x30\x39\x31\x39\x5a\x30\x74\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x4b\x31\x10\x30\x0e\x06\x03\x55\x04\x08\x0c\x07\x45\x6e\x67\x6c\x61\x6e\x64\x31\x0f\x30\x0d\x06\x03\x55\x04\x07\x0c\x06\x4c\x6f\x6e\x64\x6f\x6e\x31\x0e\x30\x0c\x06\x03\x55\x04\x0a\x0c\x05\x46\x54\x45\x51\x57\x31\x10\x30\x0e\x06\x03\x55\x04\x0b\x0c\x07\x55\x70\x64\x61\x74\x65\x73\x31\x20\x30\x1e\x06\x03\x55\x04\x03\x0c\x17\x75\x70\x64\x61\x74\x65\x73\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xaa\xb5\x9c\xcc\xe8\xbd\xad\x1c\x7f\x6b\x1c\xc9\x04\xe6\x2c\x10\xac\x99\xeb\x67\x0b\x9c\x24\xb8\x90\x77\xde\xaa\x44\xa2\x15\x31\x61\x52\x4d\xeb\x8f\x56\xb8\xaf\xc1\x2f\x66\xdd\x55\x8d\xd6\xec\xc3\xa4\x93\x8c\x86\xeb\xaf\x89\x17\x19\x2e\x6c\xc2\xd4\xf9\x92\xac\x2e\x73\x99\x56\xf2\xc3\xc4\x14\x56\x4a\x0d\xbe\x51\xc9\x8f\x4e\x92\x20\x2b\xae\x05\x0c\x7e\x87\xa5\x02\xe1\xc0\x7d\x71\xa7\x38\x72\x47\x3f\x31\x07\x90\xb0\x6d\xcf\xae\xb6\xdb\xeb\x39\xaa\x5f\xb4\x6f\x0c\x63\x2a\x21\x65\x36\xaa\x6b\xac\x97\xb6\xbe\x20\xa4\x87\x36\xbf\x35\xc5\xa6\x31\xe4\x9d\x85\xf3\xae\x8f\x6b\xf8\x59\x75\x0f\xb5\x5d\x31\x40\x39\x2e\xea\x48\x65\xdf\x91\xe3\x06\xfb\xb2\xec\xdc\xd0\x90\x94\xd6\x68\x4d\x62\x25\x9a\x3d\xc3\x74\x17\x7d\x0e\xe2\x1e\x34\xbf\x02\x85\xc4\x40\x88\x91\xeb\xe0\xf5\x92\x56\x42\x4f\xa6\x4c\x17\x88\xb2\x89\xd2\xec\x60\x54\x97\x20\x0a\xca\xf0\xd1\x33\x3f\x5b\x66\xb7\x8a\x42\x72\x67\xc9\x47\x83\xb3\xd4\x1e\xa8\x44\xbf\x5a\x1a\x85\x79\xee\xf8\x80\xde\x19\x1d\xc5\xdd\x50\x42\x10\x17\xb7\xc3\xd4\xf1\xcb\x8a\xb8\x71\x55\x31\x02\x03\x01\x00\x01\xa3\x53\x30\x51\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x2c\x68\x81\x8f\x40\x8c\x40\x42\x9f\xbd\xc5\x0b\x36\xfb\xe2\x76\xeb\x8d\xb4\xf3\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x2c\x68\x81\x8f\x40\x8c\x40\x42\x9f\xbd\xc5\x0b\x36\xfb\xe2\x76\xeb\x8d\xb4\xf3\x30\x0f\x06\x03\x55\x1d\x13\x01\x01\xff\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x0c\x01\x35\x32\xb8\xe7\x96\xba\x3e\x53\x8c\x78\x41\xab\x9b\x7f\xe2\x7a\x80\x5a\xc9\x88\x06\x29\x28\xf9\x50\x7f\xcc\xb6\xcc\x34\x03\x45\x32\x79\x63\xe7\xde\x9c\x46\x29\xf4\xaf\x32\x72\x26\x11\xa0\x7b\x52\x23\x0a\xd5\x51\x91\x79\xf2\x50\x61\x80\x72\x40\xe7\x85\xb0\x13\x1d\x98\xdb\x14\x23\x59\xa4\xbc\xe9\xe0\x1b\xc0\x38\x33\x96\xbc\xbb\x56\x47\xcc\xbd\xe8\x40\x49\xdf\xaa\x64\x7e\x29\xe5\x9d\x40\xa5\x1a\x5c\x45\x1f\x5a\x77\x59\xfe\x7a\xb8\xf8\x4d\xc4\x9b\x31\xe6\x08\xc4\x95\xfa\x91\x8f\x91\x9f\x3c\xc4\x82\xb9\xf1\x6d\xa8\xa6\xc4\x09\xb1\xe9\xa8\x60\x9b\xaa\x4c\x79\xf0\x99\xb8\xad\x63\xb1\xe4\xc0\xaf\xf0\xdf\xc9\x33\x53\x4d\x09\xe4\x3f\x8d\x9e\x38\xc6\x93\xff\xcc\x91\x46\x7e\x67\x28\x61\xaa\xc7\x0b\xe2\xd8\x8c\xe4\xec\x8d\x44\xe7\x6a\x14\x78\x91\x7d\xec\xc7\x07\xed\xc9\x58\xdb\x35\xd4\x70\x06\x06\x39\x8d\x4b\x80\x2c\xb6\xa8\x79\x5c\x94\x15\x6c\x34\x06\x5c\xd7\xc5\x42\xc0\x72\x01\x71\x07\xf5\x25\x6a\xd0\x24\x86\xcd\x1b\x21\x07\xae\x40\xf8\xc1\xe4\x23\x0d\xa0\xc0\x23\xf0\x07\xba\xdc\x34\x5d\x47\xcf\x4b\x7b\xd5\x5d"; static const qbyte fte_triptohell_certdata[917] = "\x30\x82\x03\x91\x30\x82\x02\x79\xa0\x03\x02\x01\x02\x02\x09\x00\xb5\x71\x47\x8d\x5e\x66\xf1\xd9\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x5f\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x46\x54\x45\x31\x1c\x30\x1a\x06\x03\x55\x04\x03\x0c\x13\x66\x74\x65\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x35\x30\x30\x35\x38\x31\x34\x5a\x17\x0d\x31\x37\x30\x33\x30\x34\x30\x30\x35\x38\x31\x34\x5a\x30\x5f\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x0c\x30\x0a\x06\x03\x55\x04\x0a\x0c\x03\x46\x54\x45\x31\x1c\x30\x1a\x06\x03\x55\x04\x03\x0c\x13\x66\x74\x65\x2e\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xdd\xb8\x7c\x69\x3d\x63\x95\xe3\x88\x15\xfd\xad\x93\x5e\x6b\x97\xfb\x74\xba\x1f\x83\x33\xe5\x8a\x8d\x8f\xb0\xbf\xf9\xd3\xa1\x2c\x65\x53\xa7\xef\xd3\x0f\xdc\x03\x60\x0a\x40\xef\xa8\xef\x3f\xb3\xd9\x8d\x31\x39\x12\x8a\xd8\x0e\x24\x8f\xe5\x58\x26\x86\x4c\x76\x6c\x59\x9a\xab\xea\x1c\x3d\xfb\x62\x62\xad\xaf\xd6\x00\x33\x76\x2d\xbb\xeb\xe8\xec\xb4\x76\x4f\xb0\xbe\xcf\xf0\x46\x94\x40\x02\x99\xd4\xb2\x71\x71\xd6\xf5\x1f\xc3\x4f\x1e\x1e\xb4\x0d\x82\x49\xc4\xa2\xdc\xae\x6f\x4e\x3a\xf9\x0e\xdd\xf4\xd2\x53\xe3\xe7\x7d\x58\x79\xf4\xce\x1f\x6c\xac\x81\x8c\x8c\xe1\x03\x5b\x22\x56\x92\x19\x4f\x74\xc0\x36\x41\xac\x1b\xfa\x9e\xf7\x2a\x0f\xd6\x4b\xcc\x9a\xca\x67\x87\xb7\x95\xdf\xb7\xd4\x7d\x8c\xcc\xa9\x25\xde\xdd\x8c\x1b\xd7\x32\xf2\x84\x25\x46\x7b\x10\x55\xf9\x80\xfd\x5d\xad\xab\xf9\x4c\x1f\xc0\xa5\xd1\x3f\x01\x86\x4d\xfa\x57\xab\x7a\x6d\xec\xf1\xdb\xf4\xad\xf2\x33\xcd\xa0\xed\xfe\x1b\x27\x55\x56\xba\x8c\x47\x70\x16\xd5\x75\x17\x8e\x80\xaa\x49\x5e\x93\x83\x1d\x6f\x1f\x2c\xf7\xa7\x64\xe6\x2e\x88\x8e\xff\x70\x5a\x41\x52\xae\x93\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x4e\x76\x4a\xce\x7b\x45\x14\x39\xeb\x9c\x28\x56\xb5\x7b\x8a\x18\x6f\x22\x17\x82\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x4e\x76\x4a\xce\x7b\x45\x14\x39\xeb\x9c\x28\x56\xb5\x7b\x8a\x18\x6f\x22\x17\x82\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x48\x22\x65\xed\x2e\xc5\xed\xbb\xe9\x40\x6c\x80\xc4\x63\x19\xd1\x00\xb4\x30\x34\x17\x7c\x7c\xbd\x1b\xc5\xa9\x43\x0c\x92\x6e\xd6\x2d\x11\x6c\x0d\xa6\xda\x30\xe9\xf7\x46\x7b\x01\xe4\x53\x23\xae\x88\xd1\xf2\xed\xca\x84\x06\x19\x97\xb9\x06\xfb\xda\xec\x72\x2d\x15\x20\xd2\x8f\x66\xad\xb5\xdd\x4b\x4f\xdf\x7e\xaf\xa3\x6c\x7f\x53\x32\x8f\xe2\x19\x5c\x44\x98\x86\x31\xee\xb4\x03\xe7\x27\xa1\x83\xab\xc3\xce\xb4\x9a\x01\xbe\x8c\x64\x2e\x2b\xe3\x4e\x55\xdf\x95\xeb\x16\x87\xbd\xfa\x11\xa2\x3e\x38\x92\x97\x36\xe9\x65\x60\xf3\xac\x68\x44\xb3\x51\x54\x3a\x42\xa8\x98\x9b\xee\x1b\x9e\x79\x6a\xaf\xc0\xbe\x41\xc4\xb1\x96\x42\xd9\x94\xef\x49\x5b\xbe\x2d\x04\xb9\xfb\x92\xbb\xdc\x0e\x29\xfd\xee\xa9\x68\x09\xf9\x9f\x69\x8b\x3d\xe1\x4b\xee\x24\xf9\xfe\x02\x3a\x0a\xb8\xcd\x6c\x07\x43\xa9\x4a\xe7\x03\x34\x2e\x72\xa7\x81\xaa\x40\xa9\x98\x5d\x97\xee\x2a\x99\xc6\x8f\xe8\x6f\x98\xa2\x85\xc9\x0d\x04\x19\x43\x6a\xd3\xc7\x15\x4c\x4b\xbc\xa5\xb8\x9f\x38\xf3\x43\x83\x0c\xef\x97\x6e\xa6\x20\xde\xc5\xd3\x1e\x3e\x5d\xcd\x58\x3d\x5c\x55\x7a\x90\x94"; static const qbyte triptohell_certdata[933] = "\x30\x82\x03\xa1\x30\x82\x02\x89\xa0\x03\x02\x01\x02\x02\x09\x00\xea\xb7\x13\xcf\x55\xe5\xe8\x8c\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x31\x18\x30\x16\x06\x03\x55\x04\x03\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x1e\x17\x0d\x31\x34\x31\x32\x32\x35\x30\x30\x35\x38\x33\x37\x5a\x17\x0d\x31\x37\x30\x33\x30\x34\x30\x30\x35\x38\x33\x37\x5a\x30\x67\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x11\x30\x0f\x06\x03\x55\x04\x07\x0c\x08\x4e\x65\x77\x20\x59\x6f\x72\x6b\x31\x18\x30\x16\x06\x03\x55\x04\x0a\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x31\x18\x30\x16\x06\x03\x55\x04\x03\x0c\x0f\x74\x72\x69\x70\x74\x6f\x68\x65\x6c\x6c\x2e\x69\x6e\x66\x6f\x30\x82\x01\x22\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x00\x30\x82\x01\x0a\x02\x82\x01\x01\x00\xd8\x77\x62\xf6\x74\xa7\x75\xde\xda\x09\xae\x9e\x76\x7a\xc6\x2a\xcf\x9a\xbe\xc6\xb9\x6d\xe2\xca\x0f\x2d\x95\xb8\x89\x93\xf7\x50\x64\x92\x7d\x95\x34\xe4\x6e\xef\x52\x56\xef\x13\x9a\x3a\xae\x84\x5b\x57\x82\x04\x86\x74\xbd\x4e\x38\x32\x56\x00\xd6\x34\x9c\x23\xd6\x81\x8e\x29\x77\x45\x61\x20\xdf\x28\xf8\xe5\x61\x83\xec\xe6\xa0\x1a\x75\xa8\x3b\x53\x6f\xc4\x09\x61\x66\x3a\xf0\x81\xbf\x2c\xf5\x8e\xf1\xe2\x35\xe4\x24\x7f\x16\xcc\xce\x60\xa2\x42\x6e\xc2\x3a\x29\x75\x6c\x79\xb0\x99\x9c\xe2\xfe\x27\x32\xb6\xf7\x0d\x71\xfd\x62\x9d\x54\x7c\x40\xb2\xf5\xa0\xa4\x25\x31\x8d\x65\xfd\x3f\x3b\x9b\x7e\x84\x74\x17\x3c\x1f\xec\x50\xcf\x75\xb8\x5c\xca\xfc\x0f\xe8\x47\xd8\x64\xec\x5f\x6c\x45\x9a\x55\x49\x97\x3f\xcb\x49\x34\x71\x0a\x12\x13\xbc\x3d\x53\x81\x17\x9a\x92\x44\x91\x07\xc2\xef\x6d\x64\x86\x5d\xfd\x67\xd5\x99\x38\x95\x46\x74\x6d\xb6\xbf\x29\xc9\x5b\xac\xb1\x46\xd6\x9e\x57\x5c\x7b\x24\x91\xf4\x7c\xe4\x01\x31\x8c\xec\x79\x94\xb7\x3f\xd2\x93\x6d\xe2\x69\xbe\x61\x44\x2e\x8f\x1a\xdc\xa8\x97\xf5\x81\x8e\x0c\xe1\x00\xf2\x71\x51\xf3\x02\x03\x01\x00\x01\xa3\x50\x30\x4e\x30\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x18\xb2\x6b\x63\xcc\x17\x54\xf6\xf0\xb6\x9e\x62\xa4\x35\xcf\x47\x74\x13\x29\xbf\x30\x1f\x06\x03\x55\x1d\x23\x04\x18\x30\x16\x80\x14\x18\xb2\x6b\x63\xcc\x17\x54\xf6\xf0\xb6\x9e\x62\xa4\x35\xcf\x47\x74\x13\x29\xbf\x30\x0c\x06\x03\x55\x1d\x13\x04\x05\x30\x03\x01\x01\xff\x30\x0d\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x01\x0b\x05\x00\x03\x82\x01\x01\x00\x7f\x24\x18\x8a\x79\xee\xf9\xeb\xed\x29\x1e\x21\x15\x8a\x53\xc9\xb7\xec\x30\xc4\x85\x9f\x45\x85\x26\x36\xb7\x07\xf3\xf1\xff\x3b\x89\x05\x0a\xd4\x30\x68\x31\x68\x33\xdd\xf6\x58\xa3\x85\x9f\x49\x50\x76\x9a\xc5\x79\x13\xe1\x4d\x67\x0c\xf3\x92\xf0\x1d\x02\x1f\xc4\x5c\xd4\xa1\x0c\x57\xdf\x46\x84\x43\x9f\xb0\xe2\x91\x62\xa8\xe0\x86\x0d\x47\xe1\xd9\x60\x01\xc4\xe0\xda\x6f\x06\x0a\xad\x38\xf3\x66\x68\xc5\xe2\x66\x3e\x47\x83\x65\x64\xcd\xff\xf3\xbb\xa7\xfa\x23\xf1\x82\x5e\x06\x6a\x91\x37\x51\xcd\xb9\x95\x20\x89\xff\xa1\x54\xb2\x76\xcf\x8e\xe1\xcd\x13\x93\x13\xd1\xda\x0d\x0d\xbc\x0f\xd5\x11\x26\xd6\xaf\x60\x0f\x4d\x8a\x4f\x28\xee\x6c\xf1\x99\xdc\xed\x16\xdc\x87\x26\xfd\x23\x8a\xb8\xb0\x20\x0e\xe2\x32\xf5\x8e\xb0\x65\x98\x13\xb8\x4b\x39\x7c\x8c\x98\xa2\x29\x75\x48\x3a\x89\xf9\x61\x77\x6c\x2d\x84\x41\x40\x17\xa6\x50\xc5\x09\x63\x10\xe7\x09\xd4\x5c\xdd\x0e\x71\x16\xaf\xb1\x32\xe4\xc0\xe6\xea\xfd\x26\x55\x07\x40\x95\x84\x48\x62\x04\x10\x92\xb2\xd9\x27\xfb\x8a\xf3\x7c\xe6\xfe\xd4\xfc\xa6\x33\x79\x01\x5c\xc3\x1f\x80\xa8\xf3"; static struct @@ -402,6 +399,7 @@ static struct } knowncerts[] = { {L"triptohell.info", sizeof(triptohell_certdata), triptohell_certdata}, {L"fte.triptohell.info", sizeof(fte_triptohell_certdata), fte_triptohell_certdata}, + {L"updates.triptohell.info", sizeof(updates_triptohell_certdata), updates_triptohell_certdata}, {NULL} }; @@ -558,11 +556,11 @@ static DWORD VerifyServerCertificate(PCCERT_CONTEXT pServerCert, PWSTR pwszServe case CERT_E_WRONG_USAGE: err = "CERT_E_WRONG_USAGE"; break; default: err = "(unknown)"; break; } - Con_Printf("Error verifying certificate for '%ls': %s\n", pwszServerName, err); + Con_Printf(CON_ERROR "Error verifying certificate for '%ls': %s\n", pwszServerName, err); - if (tls_ignorecertificateerrors->ival) + if (tls_ignorecertificateerrors.ival) { - Con_Printf("pretending it didn't happen... (tls_ignorecertificateerrors is set)\n"); + Con_Printf(CON_WARNING "pretending it didn't happen... (tls_ignorecertificateerrors is set)\n"); Status = SEC_E_OK; } } diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index afe46985..2141f57e 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -119,6 +119,9 @@ cvar_t net_fakeloss = CVARFD("net_fakeloss", "0", CVAR_CHEAT, "Simulates pac static cvar_t net_dns_ipv4 = CVARD("net_dns_ipv4", "1", "If 0, disables dns resolution of names to ipv4 addresses (removing any associated error messages). Also hides ipv4 addresses in address:port listings."); static cvar_t net_dns_ipv6 = CVARD("net_dns_ipv6", "1", "If 0, disables dns resolution of names to ipv6 addresses (removing any associated error messages). Also hides ipv6 addresses in address:port listings."); cvar_t net_enabled = CVARD("net_enabled", "1", "If 0, disables all network access, including name resolution and socket creation. Does not affect loopback/internal connections."); +#if defined(HAVE_SSL) +cvar_t tls_ignorecertificateerrors = CVARFD("tls_ignorecertificateerrors", "0", CVAR_NOTFROMSERVER|CVAR_NOSAVE|CVAR_NOUNSAFEEXPAND|CVAR_NOSET, "This should NEVER be set to 1!"); +#endif #if defined(TCPCONNECT) && (defined(HAVE_SERVER) || defined(HAVE_HTTPSV)) #ifdef HAVE_SERVER cvar_t net_enable_qizmo = CVARD("net_enable_qizmo", "1", "Enables compatibility with qizmo's tcp connections serverside. Frankly, using sv_port_tcp without this is a bit pointless."); @@ -1026,6 +1029,13 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin if (!(*s) || !addresses) return result; + //EVIL HACK! + //updates.tth uses a known self-signed certificate. its not meant to be used for browsers etc, and I cba to register dns stuff for it. + //besides, browsers/etc would just bitch about its cert, so w/e. + //redirect the dns to the base host without affecting http(s) hosts/certificates. + if (!strcmp(s, "updates.triptohell.info")) + s = "triptohell.info"; + memset (sadr, 0, sizeof(*sadr)); #ifdef UNIXSOCKETS @@ -7878,6 +7888,7 @@ void NET_Init (void) #endif #if defined(HAVE_SSL) Cvar_Register(&net_enable_tls, "networking"); + Cvar_Register(&tls_ignorecertificateerrors, "networking"); #endif #ifdef HAVE_HTTPSV Cvar_Register(&net_enable_http, "networking"); diff --git a/engine/common/pr_bgcmd.c b/engine/common/pr_bgcmd.c index f2122ba0..7e030e0c 100644 --- a/engine/common/pr_bgcmd.c +++ b/engine/common/pr_bgcmd.c @@ -6754,6 +6754,7 @@ lh_extension_t QSG_Extensions[] = { {"DP_SOLIDCORPSE"}, {"DP_SPRITE32"}, //hmm... is it legal to advertise this one? {"DP_SV_BOTCLIENT", 2, NULL, {"spawnclient", "clienttype"}}, + {"DP_SV_CLIENTCAMERA", 0, NULL, {NULL}, "Works like svc_setview except also handles pvs."}, {"DP_SV_CLIENTCOLORS", 0, NULL, {NULL}, "Provided only for compatibility with DP."}, {"DP_SV_CLIENTNAME", 0, NULL, {NULL}, "Provided only for compatibility with DP."}, {"DP_SV_DRAWONLYTOCLIENT"}, diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index c1203518..322c16fd 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -2754,7 +2754,6 @@ void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemo unsigned int orig_numvisedicts = cl_numvisedicts; // unsigned int orig_numstrisidx = cl_numstrisidx; // unsigned int orig_numstrisvert = cl_numstrisvert; - extern cvar_t chase_active; //I fucking hate this cvar. die die die. extern cvar_t r_ignoreentpvs; //legacy value is 1... if (r_ignoreentpvs.ival) diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 6b58810f..599c2b7b 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -411,10 +411,15 @@ void GL_ForceDepthWritable(void) void GL_SetShaderState2D(qboolean is2d) { + shaderstate.depthrange = 0; //force projection matrix info to get reset shaderstate.updatetime = realtime; shaderstate.force2d = is2d; if (is2d) + { memcpy(shaderstate.modelviewmatrix, r_refdef.m_view, sizeof(shaderstate.modelviewmatrix)); + if (qglLoadMatrixf) + qglLoadMatrixf(r_refdef.m_view); + } BE_SelectMode(BEM_STANDARD); @@ -1306,7 +1311,8 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass) #ifdef HAVE_MEDIA_DECODER case T_GEN_VIDEOMAP: t = Media_UpdateForShader(pass->cin); - t = shaderstate.curtexnums?shaderstate.curtexnums->base:r_nulltex; + if (!TEXLOADED(t)) + t = shaderstate.curtexnums?shaderstate.curtexnums->base:r_nulltex; break; #endif diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index 2b4a1abe..65026854 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -561,15 +561,6 @@ void GL_Set2D (qboolean flipped) /*flush that gl state*/ GL_ViewportUpdate(); - if (qglLoadMatrixf) - { - qglMatrixMode(GL_PROJECTION); - qglLoadMatrixf(r_refdef.m_projection_std); - - qglMatrixMode(GL_MODELVIEW); - qglLoadMatrixf(r_refdef.m_view); - } - if (flipped) r_refdef.flipcull = SHADER_CULL_FLIP; else diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index 44a4af3d..fc3e1f31 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -313,6 +313,7 @@ typedef union eval_s #define PR_AddressableAlloc(pf,size) (*pf->AddressableAlloc) (pf, size) #define PR_AddressableFree(pf,mem) (*pf->AddressableFree) (pf, mem) +#define PROG_TO_EDICTINDEX(pf, ed) ed #define PROG_TO_EDICT(pf, ed) (*pf->ProgsToEdict) (pf, ed) #define EDICT_TO_PROG(pf, ed) (*pf->EdictToProgs) (pf, (struct edict_s*)ed) diff --git a/engine/qclib/qccguiqt.cpp b/engine/qclib/qccguiqt.cpp index 266955e6..1034ecea 100644 --- a/engine/qclib/qccguiqt.cpp +++ b/engine/qclib/qccguiqt.cpp @@ -422,7 +422,7 @@ class documentlist : public QAbstractListModel int savefmt; //encoding to save as QsciDocument doc; QsciLexer *l; - } **docs, *curdoc; + } **docs, *curdoc = nullptr; class docstacklock { @@ -1699,11 +1699,68 @@ void GUI_DoDecompile(void *buf, size_t size) c = "COPYRIGHT OWNER NOT KNOWN"; //all work is AUTOMATICALLY copyrighted under the terms of the Berne Convention in all major nations. It _IS_ copyrighted, even if there's no license etc included. Good luck guessing what rights you have. if (QMessageBox::Open == QMessageBox::question(mainwnd, "Copyright", QString::asprintf("The copyright message from this progs is\n%s\n\nPlease respect the wishes and legal rights of the person who created this.", c), QMessageBox::Open|QMessageBox::Cancel, QMessageBox::Cancel)) { + extern pbool qcc_vfiles_changed; + extern vfile_t *qcc_vfiles; + GUIprintf(""); DecompileProgsDat(progssrcname, buf, size); -// QCC_SaveVFiles(); + if (qcc_vfiles_changed) + { + switch (QMessageBox::question(mainwnd, "Decompile", "Save as archive?", QMessageBox::Yes|QMessageBox::SaveAll|QMessageBox::Ignore, QMessageBox::Ignore)) + { + case QMessageBox::Yes: + { + QString fname = QFileDialog::getSaveFileName(mainwnd, "Output Archive", QString(), "Zips (*.zip)"); + if (!fname.isNull()) + { + int h = SafeOpenWrite(fname.toUtf8().data(), -1); + + progfuncs_t funcs; + progexterns_t ext; + memset(&funcs, 0, sizeof(funcs)); + funcs.funcs.parms = &ext; + memset(&ext, 0, sizeof(ext)); + ext.ReadFile = GUIReadFile; + ext.FileSize = GUIFileSize; + ext.WriteFile = QCC_WriteFile; + ext.Sys_Error = Sys_Error; + ext.Printf = GUIprintf; + + qccprogfuncs = &funcs; + WriteSourceFiles(qcc_vfiles, h, true, false); + qccprogfuncs = NULL; + + SafeClose(h); + + qcc_vfiles_changed = false; + return; + } + } + break; + case QMessageBox::SaveAll: + { + QString path = QFileDialog::getExistingDirectory(mainwnd, "Where do you want to save the decompiled code?", QString()); + for (vfile_t *f = qcc_vfiles; f; f = f->next) + { + char nname[MAX_OSPATH]; + int h; + QC_snprintfz(nname, sizeof(nname), "%s/%s", path.toUtf8().data(), f->filename); + h = SafeOpenWrite(f->filename, -1); + + if (h >= 0) + { + SafeWrite(h, f->file, f->size); + SafeClose(h); + } + } + } + break; + default: + return; + } + } } } diff --git a/engine/server/net_preparse.c b/engine/server/net_preparse.c index 36e34a0d..f9f5ee15 100644 --- a/engine/server/net_preparse.c +++ b/engine/server/net_preparse.c @@ -585,7 +585,6 @@ static int multicasttype; static int requireextension; static qboolean ignoreprotocol; static int te_515sevilhackworkaround; -extern qboolean ssqc_deprecated_warned; #define svc_setfrags 14 #define svc_updatecolors 17 diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 0e1b4deb..ba0a6215 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -62,6 +62,9 @@ cvar_t temp1 = CVARF("temp1", "0", CVAR_ARCHIVE); cvar_t noexit = CVAR("noexit", "0"); extern cvar_t sv_specprint; +//cvar_t sv_aim = {"sv_aim", "0.93"}; +cvar_t sv_aim = CVAR("sv_aim", "2"); + extern cvar_t pr_autocreatecvars; cvar_t pr_ssqc_memsize = CVARD("pr_ssqc_memsize", "-1", "The ammount of memory available to the QC vm. This has a theoretical maximum of 1gb, but that value can only really be used in 64bit builds. -1 will attempt to use some conservative default, but you may need to increase it. Consider also clearing pr_fixbrokenqccarrays if you need to change this cvar."); @@ -74,39 +77,39 @@ cvar_t pr_maxedicts = CVARAFD("pr_maxedicts", "32768", "max_edicts", CVAR_LATCH, #ifndef HAVE_LEGACY cvar_t pr_no_playerphysics = CVARFD("pr_no_playerphysics", "1", CVAR_LATCH, "Prevents support of the 'SV_PlayerPhysics' QC function. This allows servers to prevent needless breakage of player prediction."); #else -cvar_t pr_no_playerphysics = CVARFD("pr_no_playerphysics", "0", CVAR_LATCH, "Prevents support of the 'SV_PlayerPhysics' QC function. This allows servers to prevent needless breakage of player prediction."); +static cvar_t pr_no_playerphysics = CVARFD("pr_no_playerphysics", "0", CVAR_LATCH, "Prevents support of the 'SV_PlayerPhysics' QC function. This allows servers to prevent needless breakage of player prediction."); #endif -cvar_t pr_no_parsecommand = CVARFD("pr_no_parsecommand", "0", 0, "Provides a way around invalid mod usage of SV_ParseClientCommand, eg xonotic."); +static cvar_t pr_no_parsecommand = CVARFD("pr_no_parsecommand", "0", 0, "Provides a way around invalid mod usage of SV_ParseClientCommand, eg xonotic."); extern cvar_t pr_sourcedir; cvar_t pr_ssqc_progs = CVARAF("progs", "", "sv_progs", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_NOTFROMSERVER); -cvar_t pr_nonetaccess = CVARD("pr_nonetaccess", "0", "Block all direct access to network buffers (the writebyte builtin and friends will ignore the call)."); //prevent write_... builtins from doing anything. This means we can run any mod, specific to any engine, on the condition that it also has a qw or nq crc. +static cvar_t pr_nonetaccess = CVARD("pr_nonetaccess", "0", "Block all direct access to network buffers (the writebyte builtin and friends will ignore the call)."); //prevent write_... builtins from doing anything. This means we can run any mod, specific to any engine, on the condition that it also has a qw or nq crc. -cvar_t pr_overridebuiltins = CVAR("pr_overridebuiltins", "1"); +static cvar_t pr_overridebuiltins = CVAR("pr_overridebuiltins", "1"); -cvar_t pr_compatabilitytest = CVARFD("pr_compatabilitytest", "0", CVAR_LATCH, "Only enables builtins if the extension they are part of was queried."); +static cvar_t pr_compatabilitytest = CVARFD("pr_compatabilitytest", "0", CVAR_LATCH, "Only enables builtins if the extension they are part of was queried."); cvar_t pr_ssqc_coreonerror = CVAR("pr_coreonerror", "1"); -cvar_t sv_gameplayfix_honest_tracelines = CVAR("sv_gameplayfix_honest_tracelines", "1"); +static cvar_t sv_gameplayfix_honest_tracelines = CVAR("sv_gameplayfix_honest_tracelines", "1"); #ifndef HAVE_LEGACY -cvar_t sv_gameplayfix_setmodelrealbox = CVARD("sv_gameplayfix_setmodelrealbox", "1", "Vanilla setmodel will setsize the entity to a hardcoded size for non-bsp models. This cvar will always use the real size of the model instead, but will require that the server actually loads the model."); +static cvar_t sv_gameplayfix_setmodelrealbox = CVARD("sv_gameplayfix_setmodelrealbox", "1", "Vanilla setmodel will setsize the entity to a hardcoded size for non-bsp models. This cvar will always use the real size of the model instead, but will require that the server actually loads the model."); #else -cvar_t sv_gameplayfix_setmodelrealbox = CVARD("sv_gameplayfix_setmodelrealbox", "0", "Vanilla setmodel will setsize the entity to a hardcoded size for non-bsp models. This cvar will always use the real size of the model instead, but will require that the server actually loads the model."); +static cvar_t sv_gameplayfix_setmodelrealbox = CVARD("sv_gameplayfix_setmodelrealbox", "0", "Vanilla setmodel will setsize the entity to a hardcoded size for non-bsp models. This cvar will always use the real size of the model instead, but will require that the server actually loads the model."); #endif -cvar_t sv_gameplayfix_setmodelsize_qw = CVARD("sv_gameplayfix_setmodelsize_qw", "0", "The setmodel builtin will act as a setsize for QuakeWorld mods also."); +static cvar_t sv_gameplayfix_setmodelsize_qw = CVARD("sv_gameplayfix_setmodelsize_qw", "0", "The setmodel builtin will act as a setsize for QuakeWorld mods also."); cvar_t dpcompat_nopreparse = CVARD("dpcompat_nopreparse", "0", "Xonotic uses svc_tempentity with unknowable lengths mixed with other data that needs to be translated. This cvar disables any attempt to translate or pre-parse network messages, including disabling nq/qw cross compatibility. NOTE: because preparsing will be disabled, messages might not get backbuffered correctly if too much reliable data is written."); -cvar_t dpcompat_traceontouch = CVARD("dpcompat_traceontouch", "0", "Report trace plane etc when an entity touches another."); +static cvar_t dpcompat_traceontouch = CVARD("dpcompat_traceontouch", "0", "Report trace plane etc when an entity touches another."); extern cvar_t sv_listen_dp; -cvar_t sv_addon[MAXADDONS]; -char cvargroup_progs[] = "Progs variables"; +static cvar_t sv_addon[MAXADDONS]; +static char cvargroup_progs[] = "Progs variables"; -evalc_t evalc_idealpitch, evalc_pitch_speed; +static evalc_t evalc_idealpitch, evalc_pitch_speed; qboolean ssqc_deprecated_warned; int pr_teamfield; -unsigned int h2infoplaque[2]; /*hexen2 stat*/ +static unsigned int h2infoplaque[2]; /*hexen2 stat*/ static void PRSV_ClearThreads(void); void PR_fclose_progs(pubprogfuncs_t*); @@ -129,7 +132,7 @@ typedef struct qcstate_s struct qcstate_s *next; } qcstate_t; -qcstate_t *qcthreads; +static qcstate_t *qcthreads; typedef struct { //for func finding and swapping. @@ -150,7 +153,7 @@ typedef struct { } BuiltinList_t; builtin_t pr_builtin[1024]; -struct { +static struct { func_t ChatMessage; //mvdsv parsing of 'say' commands func_t UserCmd; //mvdsv func_t ConsoleCmd; //mvdsv @@ -181,7 +184,7 @@ func_t SpectatorDisconnect; //QW func_t SV_PlayerPhysicsQC; //DP's DP_SV_PLAYERPHYSICS extension func_t EndFrameQC; //a common extension -globalptrs_t realpr_global_ptrs; +static globalptrs_t realpr_global_ptrs; globalptrs_t *pr_global_ptrs = &realpr_global_ptrs; pubprogfuncs_t *svprogfuncs; @@ -1520,7 +1523,7 @@ void QCLibTest(void) #endif */ typedef char char32[32]; -char32 sv_addonname[MAXADDONS]; +static char32 sv_addonname[MAXADDONS]; void PR_Init(void) { int i; @@ -1877,7 +1880,7 @@ void PR_SpawnInitialEntities(const char *file) } void SV_RegisterH2CustomTents(void); -void Q_InitProgs(void) +void Q_InitProgs(qboolean cinematic) { int i, i2; func_t f, f2; @@ -1979,7 +1982,8 @@ void Q_InitProgs(void) if (oldprnum < 0) { PR_LoadGlabalStruct(true); -// SV_Error("Couldn't open or compile progs\n"); + if (cinematic) //making this fatal, because it sucks to sit through a cinematic only to find the game isn't playable after. + SV_Error("No gamecode available. Try using the downloads menu.\n"); Con_Printf(CON_ERROR"Running without gamecode\n"); } @@ -2724,7 +2728,7 @@ static int SV_CustomTEnt_Spawn(int index, float *org, float *org2, int count, fl -int externcallsdepth; +static int externcallsdepth; float PR_LoadAditionalProgs(char *s); static void QCBUILTIN PF_addprogs(pubprogfuncs_t *prinst, globalvars_t *pr_globals) @@ -3847,8 +3851,8 @@ static void QCBUILTIN PF_TraceToss (pubprogfuncs_t *prinst, struct globalvars_s //============================================================================ -pvsbuffer_t checkpvsbuffer; -vec3_t checkorg; +static pvsbuffer_t checkpvsbuffer; +static vec3_t checkorg; extern cvar_t sv_nopvs; void PF_newcheckclient (pubprogfuncs_t *prinst, world_t *w) @@ -4007,48 +4011,11 @@ void PF_stuffcmd_Internal(int entnum, const char *str, unsigned int flags) if (strcmp(str, "disconnect\n") == 0) { // so long and thanks for all the fish - if (cl->netchan.remote_address.type == NA_LOOPBACK) - return; //don't drop the local client. It looks wrong. - cl->drop = true; + if (cl->netchan.remote_address.type != NA_LOOPBACK) //don't drop the local client. It looks wrong. + cl->drop = true; return; } -#ifdef HAVE_LEGACY - //this block is a hack to 'fix' nq mods that expect all clients to support nq commands - but we're a qw engine. - //FIXME: should buffer the entire command instead. - if (progstype != PROG_QW) - { - static qboolean expectingcolour; - if (!strncmp(str, "color ", 6)||!strncmp(str, ";color ", 7)) //okay, so this is a hack, but it fixes the qw scoreboard - { - expectingcolour = true; - if (!strcmp(str, "color ")||!strcmp(str, ";color ")) - return; - else - str += 6; - } - // FIXME: this seems broken and color->teamname needs a common functions - if (expectingcolour) - { - int team = atoi(str); - char *tname; - - expectingcolour = false; - - switch(team) - { - case 4: tname = "red"; break; - case 13: tname = "blue"; break; - default: tname = va("t%i", team); break; //good job our va has multiple buffers - } - PF_ForceInfoKey_Internal(entnum, "team", tname, strlen(tname)); - - ClientReliableWrite_Begin (cl, svc_stufftext, 2+strlen("color ")); - ClientReliableWrite_String (cl, "color "); - } - } -#endif - if (!(flags & STUFFCMD_DEMOONLY)) { if (flags & STUFFCMD_UNRELIABLE) @@ -4877,8 +4844,6 @@ Pick a vector for the player to shoot along vector aim(entity, missilespeed) ============= */ -//cvar_t sv_aim = {"sv_aim", "0.93"}; -cvar_t sv_aim = CVAR("sv_aim", "2"); void QCBUILTIN PF_aim (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { edict_t *ent, *check, *bestent; @@ -7127,7 +7092,7 @@ float str2short (string str) static void QCBUILTIN PF_str2short (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals) { - G_FLOAT(OFS_RETURN) = (float) LittleShort(*(short*)PR_GetStringOfs(prinst, OFS_PARM0)); + G_FLOAT(OFS_RETURN) = LittleShort(*(const short*)PR_GetStringOfs(prinst, OFS_PARM0)); } /* @@ -7262,7 +7227,7 @@ static void QCBUILTIN PF_strstr (pubprogfuncs_t *prinst, struct globalvars_s *pr RETURN_TSTRING(p); } -char readable2[256] = +static char readable2[256] = { '.', '_', '_', '_', '_', '.', '_', '_', '_', '_', '\n', '_', '\n', '>', '.', '.', @@ -7298,7 +7263,7 @@ char readable2[256] = 'x', 'y', 'z', '{', '|', '}', '~', '_' }; -void PR_CleanText(unsigned char *text) +static void PR_CleanText(unsigned char *text) { for ( ; *text; text++) *text = readable2[*text]; @@ -8107,7 +8072,7 @@ enum ce_max }; -int h2customtents[ce_max]; +static int h2customtents[ce_max]; void SV_RegisterH2CustomTents(void) { int i; @@ -10322,7 +10287,7 @@ static void QCBUILTIN PF_setpause(pubprogfuncs_t *prinst, struct globalvars_s *p #else #define D(p,d) p,d #endif -BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs +static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs {"fixme", PF_Fixme, 0, 0, 0, 0, D("void()", "Some builtin that should never be called. Ends the game with some weird message.")}, #ifndef SERVERONLY @@ -11714,7 +11679,7 @@ void PR_SVExtensionList_f(void) } } -builtin_t *pr_builtins = pr_builtin; +static builtin_t *pr_builtins = pr_builtin; int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]); void PR_RegisterFields(void) //it's just easier to do it this way. diff --git a/engine/server/progdefs.h b/engine/server/progdefs.h index ed17fcb7..6404ec2b 100644 --- a/engine/server/progdefs.h +++ b/engine/server/progdefs.h @@ -287,6 +287,7 @@ and the extension fields are added on the end and can have extra vm-specific stu comfieldentity(drawonlytoclient,"This entity will be sent *only* to the player named by this field. To other players they will be invisible and not emit dlights/particles. Does not work in MVD-recorded game.")\ comfieldentity(viewmodelforclient,"This entity will be sent only to the player named by this field, and this entity will be attached to the player's view as an additional weapon model.")/*DP_ENT_VIEWMODEL*/\ comfieldentity(exteriormodeltoclient,"This entity will be invisible to the player named by this field, except in mirrors or mirror-like surfaces, where it will be visible as normal. It may still cast shadows as normal, and generate lights+particles, depending on client settings. Does not affect how other players see the entity.")\ + comfieldentity(clientcamera,"Controls which entity to use for this client's camera.")\ comfieldfloat(glow_size,NULL)\ comfieldfloat(glow_color,NULL)\ comfieldfloat(glow_trail,NULL)\ diff --git a/engine/server/progs.h b/engine/server/progs.h index b6a54e08..c9db5995 100644 --- a/engine/server/progs.h +++ b/engine/server/progs.h @@ -30,7 +30,7 @@ void Q_SetProgsParms(qboolean forcompiler); void PR_Deinit(void); //server shutting down void PR_Shutdown(void); //server quitting void PR_LoadGlabalStruct(qboolean muted); -void Q_InitProgs(void); +void Q_InitProgs(qboolean cinematic); void PR_SpawnInitialEntities(const char *file); void PR_RegisterFields(void); void PR_Init(void); @@ -121,6 +121,12 @@ extern func_t SpectatorDisconnect; extern func_t SV_PlayerPhysicsQC; extern func_t EndFrameQC; +extern qboolean ssqc_deprecated_warned; +extern cvar_t pr_maxedicts; //used in too many places... +extern cvar_t noexit, temp1, saved1, saved2, saved3, saved4, savedgamecfg, scratch1, scratch2, scratch3, scratch4, gamecfg, nomonsters; //read by savegame.c +extern cvar_t pr_ssqc_memsize, pr_imitatemvdsv, sv_aim, pr_ssqc_coreonerror, dpcompat_nopreparse; +extern int pr_teamfield; + qboolean PR_QCChat(char *text, int say_type); void PR_ClientUserInfoChanged(char *name, char *oldivalue, char *newvalue); diff --git a/engine/server/savegame.c b/engine/server/savegame.c index a308935e..592d6c0a 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -1364,22 +1364,6 @@ void SV_SaveLevelCache(const char *savedir, qboolean dontharmgame) //mapchange is true for Q2's map-change autosaves. void SV_Savegame (const char *savename, qboolean mapchange) { - extern cvar_t nomonsters; - extern cvar_t gamecfg; - extern cvar_t scratch1; - extern cvar_t scratch2; - extern cvar_t scratch3; - extern cvar_t scratch4; - extern cvar_t savedgamecfg; - extern cvar_t saved1; - extern cvar_t saved2; - extern cvar_t saved3; - extern cvar_t saved4; - extern cvar_t temp1; - extern cvar_t noexit; - extern cvar_t pr_maxedicts; - - client_t *cl; int clnum; char comment[(SAVEGAME_COMMENT_LENGTH+1)*2]; diff --git a/engine/server/server.h b/engine/server/server.h index 0c5d01f4..3710157c 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -483,7 +483,8 @@ typedef struct client_s float maxspeed; // localized maxspeed float entgravity; // localized ent gravity - int viewent; //fake the entity positioning. + int viewent; //fake the entity positioning. + int clientcamera; //cache for dp_sv_clientcamera. edict_t *edict; // EDICT_NUM(clientnum+1) //additional game modes use additional edict pointers. this ensures that references are crashes. @@ -1378,7 +1379,7 @@ void SV_ReplaceEntityFrame(client_t *cl, int framenum); // void ClientReliableCheckBlock(client_t *cl, int maxsize); -sizebuf_t *ClientReliableWrite_StartWrite(client_t *cl, int maxsize); //MUST be followed by a call to ClientReliable_FinishWrite before the next start +sizebuf_t *ClientReliable_StartWrite(client_t *cl, int maxsize); //MUST be followed by a call to ClientReliable_FinishWrite before the next start void ClientReliable_FinishWrite(client_t *cl); void ClientReliableWrite_Begin(client_t *cl, int c, int maxsize); client_t *ClientReliableWrite_BeginSplit(client_t *cl, int svc, int svclen); diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 80e1a440..9c0fe734 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -817,7 +817,6 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents, extern cvar_t allow_download_refpackages; func_t f; const char *file; - extern cvar_t pr_maxedicts; gametype_e newgametype; @@ -1142,7 +1141,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents, #endif { newgametype = GT_PROGS; //let's just hope this loads. - Q_InitProgs(); + Q_InitProgs(usecinematic); } // if ((sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) && !*progs.string && SVQ2_InitGameProgs()) //full q2 dll decision in one if statement diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index d89d883f..dfcf688d 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -342,7 +342,7 @@ void VARGS SV_Error (char *error, ...) SV_EndRedirect(); - Con_Printf ("SV_Error: %s\n",string); + Con_Printf (CON_ERROR"SV_Error: %s\n",string); if (sv.state) SV_FinalMessage (va("server crashed: %s\n", string)); @@ -365,8 +365,10 @@ void VARGS SV_Error (char *error, ...) if (!isDedicated) //dedicated servers crash... { + extern cvar_t cl_disconnectreason; extern jmp_buf host_abort; SCR_EndLoadingPlaque(); + Cvar_Set(&cl_disconnectreason, va("SV_Error: %s", string)); inerror=false; longjmp (host_abort, 1); } @@ -1012,32 +1014,32 @@ void SV_FullClientUpdate (client_t *client, client_t *to) if (ping > 0xffff) ping = 0xffff; - buf = ClientReliableWrite_StartWrite(to, 4); + buf = ClientReliable_StartWrite(to, 4); MSG_WriteByte(buf, svc_updatefrags); MSG_WriteByte(buf, i); MSG_WriteShort(buf, client->old_frags); ClientReliable_FinishWrite(to); - buf = ClientReliableWrite_StartWrite(to, 4); + buf = ClientReliable_StartWrite(to, 4); MSG_WriteByte(buf, svc_updateping); MSG_WriteByte(buf, i); MSG_WriteShort(buf, ping); ClientReliable_FinishWrite(to); - buf = ClientReliableWrite_StartWrite(to, 3); + buf = ClientReliable_StartWrite(to, 3); MSG_WriteByte(buf, svc_updatepl); MSG_WriteByte(buf, i); MSG_WriteByte(buf, client->lossage); ClientReliable_FinishWrite(to); - buf = ClientReliableWrite_StartWrite(to, 6); + buf = ClientReliable_StartWrite(to, 6); MSG_WriteByte(buf, svc_updateentertime); MSG_WriteByte(buf, i); MSG_WriteFloat(buf, realtime - client->connection_started); ClientReliable_FinishWrite(to); InfoBuf_ToString(&client->userinfo, info, (pext&PEXT_BIGUSERINFOS)?BASIC_INFO_STRING:sizeof(info), basicuserinfos, privateuserinfos, (pext&PEXT_BIGUSERINFOS)?NULL:basicuserinfos, NULL, NULL); - buf = ClientReliableWrite_StartWrite(to, 7 + strlen(info)); + buf = ClientReliable_StartWrite(to, 7 + strlen(info)); MSG_WriteByte(buf, svc_updateuserinfo); MSG_WriteByte(buf, i); MSG_WriteLong(buf, client->userid); @@ -1049,13 +1051,13 @@ void SV_FullClientUpdate (client_t *client, client_t *to) int top, bottom, playercolor; char *nam = InfoBuf_ValueForKey(&client->userinfo, "name"); - buf = ClientReliableWrite_StartWrite(to, 4); + buf = ClientReliable_StartWrite(to, 4); MSG_WriteByte(buf, svc_updatefrags); MSG_WriteByte(buf, i); MSG_WriteShort(buf, client->old_frags); ClientReliable_FinishWrite(to); - buf = ClientReliableWrite_StartWrite(to, 3 + strlen(nam)); + buf = ClientReliable_StartWrite(to, 3 + strlen(nam)); MSG_WriteByte(buf, svc_updatename); MSG_WriteByte(buf, i); MSG_WriteString(buf, nam); @@ -1072,7 +1074,7 @@ void SV_FullClientUpdate (client_t *client, client_t *to) bottom = 13; playercolor = top*16 + bottom; - buf = ClientReliableWrite_StartWrite(to, 3); + buf = ClientReliable_StartWrite(to, 3); MSG_WriteByte(buf, svc_updatecolors); MSG_WriteByte(buf, i); MSG_WriteByte(buf, playercolor); @@ -1083,7 +1085,7 @@ void SV_FullClientUpdate (client_t *client, client_t *to) char *s; InfoBuf_ToString(&client->userinfo, info, sizeof(info), basicuserinfos, privateuserinfos, NULL, NULL, NULL); s = va("//fui %i \"%s\"\n", i, info); - buf = ClientReliableWrite_StartWrite(to, 2 + strlen(s)); + buf = ClientReliable_StartWrite(to, 2 + strlen(s)); ClientReliableWrite_Begin(to, svc_stufftext, 2+strlen(s)); ClientReliableWrite_String(to, s); ClientReliable_FinishWrite(to); diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index 95687899..2496c724 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -1388,7 +1388,6 @@ mvddest_t *SV_MVD_InitRecordFile (char *name) SV_BroadcastPrintf (PRINT_CHAT, "Server starts recording (%s):\n%s\n", "disk", name); break; } - Cvar_ForceSet(Cvar_Get("serverdemo", "", CVAR_NOSET, ""), SV_Demo_CurrentOutput()); txtname = SV_MVDName2Txt(name); if (sv_demotxt.value) @@ -1436,7 +1435,7 @@ char *SV_Demo_CurrentOutput(void) if (d->desttype == DEST_FILE || d->desttype == DEST_BUFFEREDFILE || d->desttype == DEST_THREADEDFILE) return d->simplename; } - return "QTV"; + return ""; } void SV_Demo_PrintOutputs(void) { @@ -1680,6 +1679,8 @@ qboolean SV_MVD_Record (mvddest_t *dest) dest->nextdest = demo.dest; demo.dest = dest; + Cvar_ForceSet(Cvar_Get("serverdemo", "", CVAR_NOSET, ""), SV_Demo_CurrentOutput()); + SV_ClientProtocolExtensionsChanged(&demo.recorder); SV_MVD_SendInitialGamestate(dest); diff --git a/engine/server/sv_nchan.c b/engine/server/sv_nchan.c index a0f2b3e5..90c36964 100644 --- a/engine/server/sv_nchan.c +++ b/engine/server/sv_nchan.c @@ -97,7 +97,7 @@ client_t *ClientReliableWrite_BeginSplit(client_t *cl, int svc, int svclen) } } -sizebuf_t *ClientReliableWrite_StartWrite(client_t *cl, int maxsize) +sizebuf_t *ClientReliable_StartWrite(client_t *cl, int maxsize) { #ifdef MVD_RECORDING if (cl == &demo.recorder) diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index 98f9919d..69df5cb8 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -2803,6 +2803,7 @@ static qboolean SV_SyncInfoBuf(client_t *client) size_t bufferspace; qboolean final; + sizebuf_t *buf; if (client->protocol == SCP_QUAKE2) { //q2 gamecode is fully responsible for networking this via configstrings. @@ -2830,13 +2831,14 @@ static qboolean SV_SyncInfoBuf(client_t *client) int playerslot = (client_t*)((char*)info-(char*)&((client_t*)NULL)->userinfo)-svs.clients; s = va("//ui %i \"%s\" \"%s\"\n", playerslot, key, blobdata); } - ClientReliableWrite_Begin(client, svc_stufftext, strlen(s)+2); - ClientReliableWrite_String(client, s); + buf = ClientReliable_StartWrite(client, 2+strlen(s)); + MSG_WriteByte(buf, svc_stufftext); + MSG_WriteString(buf, s); + ClientReliable_FinishWrite(client); } -#ifdef MVD_RECORDING - else if (client == &demo.recorder) + else if (ISQWCLIENT(client)) { - sizebuf_t *buf = MVDWrite_Begin(dem_all, 0, 2+strlen(key)+1+strlen(blobdata)+1); + buf = ClientReliable_StartWrite(client, 2+strlen(key)+1+strlen(blobdata)+1); if (info == &svs.info) MSG_WriteByte(buf, svc_serverinfo); else @@ -2846,19 +2848,7 @@ static qboolean SV_SyncInfoBuf(client_t *client) } MSG_WriteString(buf, key); MSG_WriteString(buf, blobdata); - } -#endif - else - { - if (info == &svs.info) - ClientReliableWrite_Begin(client, svc_serverinfo, 1+strlen(key)+1+strlen(blobdata)+1); - else - { - ClientReliableWrite_Begin(client, svc_setinfo, 2+strlen(key)+1+strlen(blobdata)+1); - ClientReliableWrite_Byte(client, (client_t*)((char*)info-(char*)&((client_t*)NULL)->userinfo)-svs.clients); - } - ClientReliableWrite_String(client, key); - ClientReliableWrite_String(client, blobdata); + ClientReliable_FinishWrite(client); } } else if (client->fteprotocolextensions2 & PEXT2_INFOBLOBS) @@ -2884,27 +2874,14 @@ static qboolean SV_SyncInfoBuf(client_t *client) sendsize = min(bufferspace, sendsize); final = (bloboffset+sendsize >= blobsize); -#ifdef MVD_RECORDING - if (client == &demo.recorder) - { - sizebuf_t *buf = MVDWrite_Begin(dem_all, 0, 8+strlen(enckey)+1+sendsize); - MSG_WriteByte(buf, svcfte_setinfoblob); - MSG_WriteByte(buf, pl); //special meaning to say that this is a partial update - MSG_WriteString(buf, enckey); - MSG_WriteLong(buf, (final?0x80000000:0)|bloboffset); - MSG_WriteShort(buf, sendsize); - SZ_Write(buf, blobdata+bloboffset, sendsize); - } - else -#endif - { - ClientReliableWrite_Begin(client, svcfte_setinfoblob, 8+strlen(enckey)+1+sendsize); - ClientReliableWrite_Byte(client, pl); //special meaning to say that this is a partial update - ClientReliableWrite_String(client, enckey); - ClientReliableWrite_Long(client, (final?0x80000000:0)|bloboffset); - ClientReliableWrite_Short(client, sendsize); - ClientReliableWrite_SZ(client, blobdata+bloboffset, sendsize); - } + buf = ClientReliable_StartWrite(client, 8+strlen(enckey)+1+sendsize); + MSG_WriteByte(buf, svcfte_setinfoblob); + MSG_WriteByte(buf, pl); //special meaning to say that this is a partial update + MSG_WriteString(buf, enckey); + MSG_WriteLong(buf, (final?0x80000000:0)|bloboffset); + MSG_WriteShort(buf, sendsize); + SZ_Write(buf, blobdata+bloboffset, sendsize); + ClientReliable_FinishWrite(client); if (!final) { @@ -2957,6 +2934,24 @@ void SV_UpdateToReliableMessages (void) *host_client->dp_pl = host_client->lossage; #endif + j = PROG_TO_EDICTINDEX(svprogfuncs, host_client->edict->xv->clientcamera); + if (j) + { + if ((unsigned int)j >= svprogfuncs->edicttable_length) + j = i+1; + if (j != host_client->clientcamera) + { + if (host_client->fteprotocolextensions & PEXT_VIEW2) + { + ClientReliableWrite_Begin(host_client, svc_setview, 4); + ClientReliableWrite_Entity(host_client, j); + } + if (j == i+1) + j = 0; //self. + host_client->viewent = j; + } + } + name = PR_GetString(svprogfuncs, host_client->edict->v->netname); #ifndef QCGC //this optimisation doesn't really work with a QC instead of static string management if (name != host_client->name) diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index fa967228..2207630e 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -5130,7 +5130,6 @@ void SV_SetUpClientEdict (client_t *cl, edict_t *ent) #ifdef HAVE_LEGACY { - extern int pr_teamfield; if (pr_teamfield) ((string_t *)ent->v)[pr_teamfield] = (string_t)(cl->team-svprogfuncs->stringtable); } diff --git a/engine/server/svq2_game.c b/engine/server/svq2_game.c index 9f04109b..6eee37bb 100644 --- a/engine/server/svq2_game.c +++ b/engine/server/svq2_game.c @@ -33,8 +33,10 @@ void *SVQ2_GetGameAPI (void *parms) void *iterator; int o; const char *gamename[] = { - "", - "", + "", //binarydir/q2gameCPU_gamedir.ext + "", //homedir/q2gameCPU_gamedir.ext + "", //basedir/q2gameCPU_gamedir.ext + "", //binarydir/libgame_gamedir.ext #ifdef _DEBUG "debug/game" ARCH_CPU_POSTFIX ARCH_DL_POSTFIX, #endif @@ -44,7 +46,7 @@ void *SVQ2_GetGameAPI (void *parms) "game" ARCH_CPU_POSTFIX ARCH_DL_POSTFIX, "game" ARCH_DL_POSTFIX, #if defined(__linux__) //FTE doesn't provide gamecode. Borrow someone else's. Lets just hope that its installed. - "/usr/lib/yamagi-quake2/%s/game.so", +// "/usr/lib/yamagi-quake2/%s/game.so", #endif NULL }; @@ -68,6 +70,18 @@ void *SVQ2_GetGameAPI (void *parms) Q_snprintfz(name, sizeof(name), "%sq2game"ARCH_CPU_POSTFIX"_%s"ARCH_DL_POSTFIX, host_parms.binarydir, gamepath); } else if (o == 1) + { //nice and specific + if (!*com_homepath) + continue; + Q_snprintfz(name, sizeof(name), "%sq2game"ARCH_CPU_POSTFIX"_%s"ARCH_DL_POSTFIX, com_homepath, gamepath); + } + else if (o == 2) + { //nice and specific + if (!*com_gamepath) + continue; + Q_snprintfz(name, sizeof(name), "%sq2game"ARCH_CPU_POSTFIX"_%s"ARCH_DL_POSTFIX, com_gamepath, gamepath); + } + else if (o == 3) { //because some people don't like knowing what cpu arch they're compiling for if (!host_parms.binarydir) continue;