From d74c6f738ac663b9ca9fd1f5f6a17cb6bd773756 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sun, 10 Jun 2007 21:33:24 +0000 Subject: [PATCH] Added some new bugs. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2515 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/common/protocol.h | 3 ++ engine/gl/gl_draw.c | 8 ++- engine/qclib/qcc_pr_comp.c | 81 +++++++++++++++++++++++++++++ engine/server/sv_main.c | 10 +++- engine/server/sv_send.c | 2 +- engine/server/sv_user.c | 104 ++++++++++++++++++++++++++++++++++++- 6 files changed, 203 insertions(+), 5 deletions(-) diff --git a/engine/common/protocol.h b/engine/common/protocol.h index 589a72bb8..7d4111beb 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -253,6 +253,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //DP extended svcs +#define svcdp_downloaddata 50 #define svcdp_updatestatbyte 51 #define svcnq_effect 52 // [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate #define svcnq_effect2 53 // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate @@ -319,6 +320,8 @@ enum clcq2_ops_e #define clc_tmove 6 // teleport request, spectator only #define clc_upload 7 // teleport request, spectator only +#define clcdp_ackdownloaddata 51 + //============================================== diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index b4269a41f..c79fc977d 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -510,7 +510,13 @@ mpic_t *GLDraw_SafeCachePic (char *path) sprintf(alternatename, "gfx/%s.lmp", path); qpic = (qpic_t *)COM_LoadTempFile (alternatename); if (!qpic) - return GLDraw_SafePicFromWad(path); + { + mpic_t *m; + m = GLDraw_SafePicFromWad(path); + if (!m && !strncmp(path, "gfx/", 4)) + return GLDraw_SafePicFromWad(path+4); + return m; + } } SwapPic (qpic); diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index 71b60a98e..d0604ad21 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -795,6 +795,7 @@ QCC_def_t *QCC_SupplyConversion(QCC_def_t *var, etype_t wanted) QCC_def_t *QCC_MakeStringDef(char *value); QCC_def_t *QCC_MakeFloatDef(float value); QCC_def_t *QCC_MakeIntDef(int value); +QCC_def_t *QCC_MakeVectorDef(float a, float b, float c); typedef struct freeoffset_s { struct freeoffset_s *next; @@ -1330,6 +1331,38 @@ QCC_def_t *QCC_PR_Statement ( QCC_opcode_t *op, QCC_def_t *var_a, QCC_def_t *var case OP_SUB_I: optres_constantarithmatic++; return QCC_MakeIntDef(G_INT(var_a->ofs) - G_INT(var_b->ofs)); + + case OP_AND: + optres_constantarithmatic++; + return QCC_MakeIntDef(G_INT(var_a->ofs) && G_INT(var_b->ofs)); + case OP_OR: + optres_constantarithmatic++; + return QCC_MakeIntDef(G_INT(var_a->ofs) || G_INT(var_b->ofs)); + case OP_MUL_V: //mul_f is actually a dot-product + optres_constantarithmatic++; + return QCC_MakeFloatDef( G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+0) + + G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+1) + + G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+2)); + case OP_MUL_FV: + optres_constantarithmatic++; + return QCC_MakeVectorDef( G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+0), + G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+1), + G_FLOAT(var_a->ofs) * G_FLOAT(var_b->ofs+2)); + case OP_MUL_VF: + optres_constantarithmatic++; + return QCC_MakeVectorDef( G_FLOAT(var_a->ofs+0) * G_FLOAT(var_b->ofs), + G_FLOAT(var_a->ofs+1) * G_FLOAT(var_b->ofs), + G_FLOAT(var_a->ofs+2) * G_FLOAT(var_b->ofs)); + case OP_ADD_V: + optres_constantarithmatic++; + return QCC_MakeVectorDef( G_FLOAT(var_a->ofs+0) + G_FLOAT(var_b->ofs+0), + G_FLOAT(var_a->ofs+1) + G_FLOAT(var_b->ofs+1), + G_FLOAT(var_a->ofs+2) + G_FLOAT(var_b->ofs+2)); + case OP_SUB_V: + optres_constantarithmatic++; + return QCC_MakeVectorDef( G_FLOAT(var_a->ofs+0) - G_FLOAT(var_b->ofs+0), + G_FLOAT(var_a->ofs+1) - G_FLOAT(var_b->ofs+1), + G_FLOAT(var_a->ofs+2) - G_FLOAT(var_b->ofs+2)); } } @@ -2940,6 +2973,54 @@ QCC_def_t *QCC_MakeIntDef(int value) return cn; } +QCC_def_t *QCC_MakeVectorDef(float a, float b, float c) +{ + QCC_def_t *cn; + +// check for a constant with the same value + for (cn=pr.def_head.next ; cn ; cn=cn->next) + { + varchecks++; + if (!cn->initialized) + continue; + if (!cn->constant) + continue; + constchecks++; + if (cn->type != type_vector) + continue; + typechecks++; + + if ( G_FLOAT(cn->ofs+0) == a && + G_FLOAT(cn->ofs+1) == b && + G_FLOAT(cn->ofs+2) == c) + { + return cn; + } + } + +// allocate a new one + cn = (void *)qccHunkAlloc (sizeof(QCC_def_t)); + cn->next = NULL; + pr.def_tail->next = cn; + pr.def_tail = cn; + + cn->type = type_vector; + cn->name = "IMMEDIATE"; + cn->constant = true; + cn->initialized = 1; + cn->scope = NULL; // always share immediates + cn->arraysize = 1; + +// copy the immediate to the global area + cn->ofs = QCC_GetFreeOffsetSpace (type_size[type_integer->type]); + + G_FLOAT(cn->ofs+0) = a; + G_FLOAT(cn->ofs+1) = b; + G_FLOAT(cn->ofs+2) = c; + + return cn; +} + hashtable_t floatconstdefstable; QCC_def_t *QCC_MakeFloatDef(float value) { diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 4fbbde520..810723b1f 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -1228,7 +1228,7 @@ void SVC_GetChallenge (void) } #endif } - if (sv_listen_qw.value) + if (sv_listen_qw.value || svs.gametype != GT_PROGS) Netchan_OutOfBand(NS_SERVER, net_from, over-buf, buf); if (sv_listen_dp.value) @@ -1532,6 +1532,14 @@ client_t *SVC_DirectConnect(void) if (protocol == SCP_QUAKEWORLD) //readd? { + if (!sv_listen_qw.value && net_from.type != NA_LOOPBACK) + { + SV_RejectMessage (SCP_BAD, "QuakeWorld protocols are not permitted on this server.\n"); + Con_Printf ("* rejected connect from quakeworld\n", version); + return NULL; + } + + while(!msg_badread) { Cmd_TokenizeString(MSG_ReadStringLine(), false, false); diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index c452a1171..11e1e9f62 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -233,7 +233,7 @@ EVENT MESSAGES ============================================================================= */ -static void SV_PrintToClient(client_t *cl, int level, char *string) +void SV_PrintToClient(client_t *cl, int level, char *string) { switch (cl->protocol) { diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 41ac0c48a..00f1ec714 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -346,6 +346,10 @@ void SVNQ_New_f (void) if (host_client->protocol == SCP_DARKPLACES7) { char *f; + + MSG_WriteByte (&host_client->netchan.message, svc_stufftext); + MSG_WriteString (&host_client->netchan.message, "cl_serverextension_download 1\n"); + f = COM_LoadTempFile("csprogs.dat"); if (f) { @@ -1500,6 +1504,71 @@ void SV_Begin_f (void) //============================================================================= +void SV_DarkPlacesDownloadChunk(client_t *cl) +{ +#define MAXDPDOWNLOADCHUNK 1024 + char buffer[MAXDPDOWNLOADCHUNK]; + + int size, start; + + if (cl->num_backbuf) + size = 16; + else + size = 512; + if (size > MAXDPDOWNLOADCHUNK) //don't clog it too much + size = MAXDPDOWNLOADCHUNK; + + start = VFS_TELL(cl->download); + if (start+size > cl->downloadsize) //clamp to the size of the file. + size = cl->downloadsize - start; + + VFS_READ(cl->download, buffer, size); + + //reliable? I don't care, this works. + ClientReliableWrite_Begin (cl, svcdp_downloaddata, 7+size); + ClientReliableWrite_Long (cl, start); + ClientReliableWrite_Short (cl, size); + ClientReliableWrite_SZ (cl, buffer, size); +} + +void SVDP_ForceDownloadChunk_f(void) +{ + if (host_client->protocol != SCP_DARKPLACES7) + return; + SV_DarkPlacesDownloadChunk(host_client); +} + +void SV_DarkPlacesDownloadAck(client_t *cl) +{ + int start = MSG_ReadLong(); + int size = (unsigned short)MSG_ReadShort(); + + if (size == 0) + { + char *s; + unsigned short crc; + int pos=0, csize; + qbyte chunk[1024]; + QCRC_Init(&crc); + VFS_SEEK(host_client->download, 0); + while (pos < host_client->downloadsize) + { + csize = sizeof(chunk); + if (pos + csize > host_client->downloadsize) + csize = host_client->downloadsize - pos; + VFS_READ(host_client->download, chunk, csize); + QCRC_AddBlock(&crc, chunk, csize); + pos += csize; + } + + s = va("\ncl_downloadfinished %i %i \"\"\n", host_client->downloadsize, crc); + ClientReliableWrite_Begin (cl, svc_stufftext, 2+strlen(s)); + ClientReliableWrite_String(cl, s); + } + else + SV_DarkPlacesDownloadChunk(cl); +} + void SV_NextChunkedDownload(int chunknum) { #define CHUNKSIZE 1024 @@ -1780,11 +1849,22 @@ void SV_BeginDownload_f(void) if (!strncmp(name, "demonum/", 8)) name = SV_MVDNum(atoi(name+8)); + if (ISNQCLIENT(host_client) && host_client->protocol != SCP_DARKPLACES7) + { + SV_PrintToClient(host_client, PRINT_HIGH, "Your client isn't meant to support downloads\n"); + return; + } + // hacked by zoid to allow more conrol over download if (!SV_AllowDownload(name)) { // don't allow anything with .. path + if (ISNQCLIENT(host_client)) + { + ClientReliableWrite_Begin (host_client, svc_stufftext, 2+strlen(name)); + ClientReliableWrite_String (host_client, "\nstopdownload\n"); + } #ifdef PEXT_CHUNKEDDOWNLOADS - if (host_client->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS) + else if (host_client->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS) { ClientReliableWrite_Begin (host_client, svc_download, 10+strlen(name)); ClientReliableWrite_Long (host_client, -1); @@ -1830,6 +1910,12 @@ void SV_BeginDownload_f(void) } Sys_Printf ("Couldn't download %s to %s\n", name, host_client->name); + if (ISNQCLIENT(host_client)) + { + ClientReliableWrite_Begin (host_client, svc_stufftext, 2+strlen(name)); + ClientReliableWrite_String (host_client, "\nstopdownload\n"); + } + else #ifdef PEXT_CHUNKEDDOWNLOADS if (host_client->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS) { @@ -1882,7 +1968,15 @@ void SV_BeginDownload_f(void) } #endif - SV_NextDownload_f (); + if (ISNQCLIENT(host_client)) + { + char *s = va("\ncl_downloadbegin %i %s\n", host_client->downloadsize, name); + ClientReliableWrite_Begin (host_client, svc_stufftext, 2+strlen(s)); + ClientReliableWrite_String (host_client, s); + } + else + SV_NextDownload_f (); + SV_EndRedirect(); Con_Printf ("Downloading %s to %s\n", name, host_client->name); } @@ -3741,6 +3835,9 @@ ucmd_t nqucmds[] = {"ban", NULL}, {"vote", SV_Vote_f}, + {"download", SV_BeginDownload_f}, + {"sv_startdownload", SVDP_ForceDownloadChunk_f}, + {"setinfo", SV_SetInfo_f}, {"playermodel", NULL}, {"playerskin", NULL}, @@ -5163,6 +5260,9 @@ void SVNQ_ExecuteClientMessage (client_t *cl) sv_player = cl->edict; break; + case clcdp_ackdownloaddata: + SV_DarkPlacesDownloadAck(host_client); + break; } } }