diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index 386f866af..b99123ca9 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -363,7 +363,7 @@ void CL_ProgressDemoTime(void) { extern cvar_t cl_demospeed; - if (cl.parsecount && Media_PausedDemo()) + if (cl.parsecount && Media_PausedDemo(true)) { //console visible whilst democapturing cls.netchan.last_received = realtime; return; @@ -1634,6 +1634,8 @@ void CL_PlayDemoStream(vfsfile_t *file, struct dl_download *dl, char *filename, CL_Disconnect_f (); demo_flushcache(); + + NET_InitClient(true); // // open the demo file // @@ -1703,6 +1705,8 @@ void CL_PlayDemoFile(vfsfile_t *f, char *demoname, qboolean issyspath) VFS_READ(f, &type, sizeof(type)); VFS_READ(f, &protocol, sizeof(protocol)); VFS_SEEK(f, start); + len = LittleLong(len); + protocol = LittleLong(protocol); if (len > 5 && type == svcq2_serverdata && protocol == PROTOCOL_VERSION_Q2) { CL_PlayDemoStream(f, NULL, demoname, issyspath, DPB_QUAKE2, 0); diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index fb72ce2a1..3bf1f9bc6 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -677,6 +677,9 @@ void CL_CheckForResend (void) pext2 = 0; connectinfo.trying = true; connectinfo.istransfer = false; + + NET_InitClient(true); + Q_strncpyz (cls.servername, "internalserver", sizeof(cls.servername)); Cvar_ForceSet(&cl_servername, cls.servername); NET_StringToAdr(cls.servername, 0, &connectinfo.adr); @@ -842,6 +845,8 @@ void CL_CheckForResend (void) if (connectinfo.time && realtime - connectinfo.time < 5.0) return; + NET_InitClient(false); + t1 = Sys_DoubleTime (); if (!connectinfo.istransfer) { @@ -5171,7 +5176,6 @@ void Host_Init (quakeparms_t *parms) #endif Host_FixupModelNames(); - NET_InitClient (); Netchan_Init (); Renderer_Init(); Mod_Init(true); diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index bc65a03e4..1b880899d 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -2847,7 +2847,7 @@ qboolean Media_UnregisterEncoder(struct plugin_s *plug, media_encoder_funcs_t *f } return success; } - + //returns 0 if not capturing. 1 if capturing live. 2 if capturing a demo (where frame timings are forced). int Media_Capturing (void) { @@ -2861,12 +2861,17 @@ void Media_CapturePause_f (void) capturepaused = !capturepaused; } -qboolean Media_PausedDemo (void) +qboolean Media_PausedDemo (qboolean fortiming) { + //if fortiming is set, then timing might need to advance if we still need to parse the demo to get the first valid data out of it. + + if (capturepaused) + return true; + //capturedemo doesn't record any frames when the console is visible //but that's okay, as we don't load any demo frames either. - if ((cls.demoplayback && Media_Capturing()) || capturepaused) - if (Key_Dest_Has(~kdm_game) || scr_con_current > 0 || !cl.validsequence || capturepaused) + if ((cls.demoplayback && Media_Capturing())) + if (Key_Dest_Has(~kdm_game) || scr_con_current > 0 || (!fortiming&&!cl.validsequence)) return true; return false; @@ -2908,7 +2913,7 @@ void Media_RecordFrame (void) captureframe = 0; } */ - if (Media_PausedDemo()) + if (Media_PausedDemo(false)) { int y = vid.height -32-16; if (y < scr_con_current) y = scr_con_current; diff --git a/engine/client/render.h b/engine/client/render.h index 89b6f1ff8..7f7e2783a 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -482,7 +482,7 @@ extern struct model_s *currentmodel; qboolean Media_ShowFilm(void); void Media_CaptureDemoEnd(void); void Media_RecordFrame (void); -qboolean Media_PausedDemo (void); +qboolean Media_PausedDemo (qboolean fortiming); int Media_Capturing (void); double Media_TweekCaptureFrameTime(double oldtime, double time); diff --git a/engine/common/net.h b/engine/common/net.h index 1b66244ba..0213dcc6c 100644 --- a/engine/common/net.h +++ b/engine/common/net.h @@ -86,7 +86,7 @@ struct ftenet_connections_s; void NET_Init (void); void NET_Tick (void); void SVNET_RegisterCvars(void); -void NET_InitClient (void); +void NET_InitClient (qboolean loopbackonly); void NET_InitServer (void); qboolean NET_WasSpecialPacket(netsrc_t netsrc); void NET_CloseServer (void); diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index e083d5db5..1fb0afa3f 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -77,6 +77,7 @@ void IPX_CloseSocket (int socket); #endif cvar_t net_hybriddualstack = CVAR("net_hybriddualstack", "1"); cvar_t net_fakeloss = CVARFD("net_fakeloss", "0", CVAR_CHEAT, "Simulates packetloss in both receiving and sending, on a scale from 0 to 1."); +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."); extern cvar_t sv_public, sv_listen_qw, sv_listen_nq, sv_listen_dp, sv_listen_q3; @@ -938,8 +939,6 @@ size_t NET_StringToAdr2 (const char *s, int defaultport, netadr_t *a, size_t num memset(a, 0, sizeof(*a)*numaddresses); - Con_DPrintf("Resolving address: %s\n", s); - if (!numaddresses) return false; @@ -948,6 +947,7 @@ size_t NET_StringToAdr2 (const char *s, int defaultport, netadr_t *a, size_t num a->type = NA_LOOPBACK; return true; } + if (!strncmp(s, "QLoopBack", 9)) { a->type = NA_LOOPBACK; @@ -958,6 +958,10 @@ size_t NET_StringToAdr2 (const char *s, int defaultport, netadr_t *a, size_t num return true; } + if (!net_enabled.ival) + return false; + Con_DPrintf("Resolving address: %s\n", s); + #ifdef HAVE_WEBSOCKCL if (!strncmp (s, "ws://", 5) || !strncmp (s, "wss://", 6)) { @@ -2557,17 +2561,19 @@ qboolean FTENET_Generic_SendPacket(ftenet_generic_connection_t *con, int length, qboolean NET_PortToAdr (int adrfamily, const char *s, netadr_t *a) { char *e; - int port; - port = strtoul(s, &e, 10); - if (*e) //if *e then its not just a single number in there, so treat it as a proper address. - return NET_StringToAdr(s, 0, a); - else if (e != s) //if we actually read something (even a 0) + if (net_enabled.ival || adrfamily == NA_LOOPBACK) { - memset(a, 0, sizeof(*a)); - a->port = htons((unsigned short)port); - a->type = adrfamily; + int port = strtoul(s, &e, 10); + if (*e) //if *e then its not just a single number in there, so treat it as a proper address. + return NET_StringToAdr(s, 0, a); + else if (e != s) //if we actually read something (even a 0) + { + memset(a, 0, sizeof(*a)); + a->port = htons((unsigned short)port); + a->type = adrfamily; - return a->type != NA_INVALID; + return a->type != NA_INVALID; + } } a->type = NA_INVALID; return false; @@ -5553,23 +5559,27 @@ NET_Init */ void NET_Init (void) { -#if defined(_WIN32) && defined(HAVE_PACKET) - int r; -#ifdef IPPROTO_IPV6 - dllfunction_t fncs[] = + Cvar_Register(&net_enabled, "networking"); + if (!net_enabled.ival) { - {(void**)&pgetaddrinfo, "getaddrinfo"}, - {(void**)&pfreeaddrinfo, "freeaddrinfo"}, - {NULL, NULL} - }; - Sys_LoadLibrary("ws2_32.dll", fncs); +#if defined(_WIN32) && defined(HAVE_PACKET) + int r; +#ifdef IPPROTO_IPV6 + dllfunction_t fncs[] = + { + {(void**)&pgetaddrinfo, "getaddrinfo"}, + {(void**)&pfreeaddrinfo, "freeaddrinfo"}, + {NULL, NULL} + }; + Sys_LoadLibrary("ws2_32.dll", fncs); #endif - r = WSAStartup (MAKEWORD(2, 2), &winsockdata); + r = WSAStartup (MAKEWORD(2, 2), &winsockdata); - if (r) - Sys_Error ("Winsock initialization failed."); + if (r) + Sys_Error ("Winsock initialization failed."); #endif + } Cvar_Register(&net_hybriddualstack, "networking"); Cvar_Register(&net_fakeloss, "networking"); @@ -5591,7 +5601,7 @@ void NET_Init (void) Net_Master_Init(); } #ifndef SERVERONLY -void NET_InitClient(void) +void NET_InitClient(qboolean loopbackonly) { const char *port; int p; @@ -5608,10 +5618,13 @@ void NET_InitClient(void) port = com_argv[p+1]; } - cls.sockets = FTENET_CreateCollection(false); + if (!cls.sockets) + cls.sockets = FTENET_CreateCollection(false); #ifndef CLIENTONLY FTENET_AddToCollection(cls.sockets, "CLLoopback", "1", NA_LOOPBACK, true); #endif + if (loopbackonly) + port = ""; #ifdef HAVE_IPV4 FTENET_AddToCollection(cls.sockets, "CLUDP4", port, NA_IP, true); #endif