diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 640474199..09637a795 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -946,8 +946,12 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf) for (i=0 ; i<3 ; i++) { - if (cls.protocol_nq == CPNQ_FITZ666 || cls.protocol_nq == CPNQ_PROQUAKE3_4) + if ((cls.protocol_nq == CPNQ_FITZ666 || cls.protocol_nq == CPNQ_PROQUAKE3_4) && buf->prim.anglesize <= 1) + { + //fitz/proquake protocols are always 16bit for this angle and 8bit elsewhere. rmq is always at least 16bit + //the above logic should satify everything. MSG_WriteAngle16 (buf, cl.playerview[pnum].viewangles[i]); + } else MSG_WriteAngle (buf, cl.playerview[pnum].viewangles[i]); } diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 44f9f1c17..b18897b2b 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -642,7 +642,12 @@ void CL_CheckForResend (void) cl.movemessages = 0; if (!strcmp(cl_loopbackprotocol.string, "qw")) cls.protocol = CP_QUAKEWORLD; - else if (!strcmp(cl_loopbackprotocol.string, "nq")) + else if (!strcmp(cl_loopbackprotocol.string, "nq")) //actually proquake, because we might as well use the extra angles + { + cls.protocol = CP_NETQUAKE; + cls.protocol_nq = CPNQ_PROQUAKE3_4; + } + else if (!strcmp(cl_loopbackprotocol.string, "nqid")) { cls.protocol = CP_NETQUAKE; cls.protocol_nq = CPNQ_ID; @@ -690,6 +695,13 @@ void CL_CheckForResend (void) SVC_DirectConnect(); } + else if (cls.protocol_nq == CPNQ_PROQUAKE3_4) + { + net_from = adr; + Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\\mod\\1\"", NET_PROTOCOL_VERSION, 0, SV_NewChallenge()), false, false); + + SVC_DirectConnect(); + } else CL_ConnectToDarkPlaces("", adr); } @@ -2604,7 +2616,7 @@ void CLNQ_ConnectionlessPacket(void) if (MSG_ReadByte() == 1) //a proquake server adds a little extra info { int ver = MSG_ReadByte(); - Con_Printf("ProQuake server %i.%i\n", ver/10, ver%10); + Con_DPrintf("ProQuake server %i.%i\n", ver/10, ver%10); // if (ver >= 34) cls.protocol_nq = CPNQ_PROQUAKE3_4; diff --git a/engine/common/fs.c b/engine/common/fs.c index 9248ed25e..cd1c29eec 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -2580,6 +2580,9 @@ void FS_StartupWithGame(int gamenum) if (i && i < com_argc-1) { COM_Gamedir(com_argv[i+1]); +#ifndef CLIENTONLY + Info_SetValueForStarKey (svs.info, "*gamedir", com_argv[i+1], MAX_SERVERINFO_STRING); +#endif } //+gamedir specifies the mod gamedir to use in QW diff --git a/engine/server/server.h b/engine/server/server.h index 97e9973d0..19c5c6720 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -523,6 +523,7 @@ typedef struct client_s SCP_QUAKE3, //all the below are considered netquake clients. SCP_NETQUAKE, + SCP_PROQUAKE, SCP_FITZ666, SCP_DARKPLACES6, SCP_DARKPLACES7 //extra prediction stuff diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index cb134df8f..0bbfb0f55 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -428,6 +428,7 @@ void SV_DropClient (client_t *drop) break; case SCP_QUAKEWORLD: case SCP_NETQUAKE: + case SCP_PROQUAKE: case SCP_FITZ666: case SCP_DARKPLACES6: case SCP_DARKPLACES7: @@ -795,6 +796,7 @@ int SV_CalcPing (client_t *cl, qboolean forcecalc) case SCP_DARKPLACES6: case SCP_DARKPLACES7: case SCP_NETQUAKE: + case SCP_PROQUAKE: case SCP_FITZ666: case SCP_QUAKEWORLD: ping = 0; @@ -1572,6 +1574,7 @@ void VARGS SV_RejectMessage(int protocol, char *format, ...) #ifdef NQPROT case SCP_NETQUAKE: case SCP_FITZ666: + case SCP_PROQUAKE: string[4] = CCREP_REJECT; vsnprintf (string+5,sizeof(string)-1-5, format,argptr); len = strlen(string+4)+1+4; @@ -1624,13 +1627,16 @@ void SV_AcceptMessage(int protocol) #ifdef NQPROT case SCP_NETQUAKE: case SCP_FITZ666: - if (net_from.type != NA_LOOPBACK) + case SCP_PROQUAKE: +// if (net_from.type != NA_LOOPBACK) { SZ_Clear(&sb); MSG_WriteLong(&sb, 0); MSG_WriteByte(&sb, CCREP_ACCEPT); NET_LocalAddressForRemote(svs.sockets, &net_from, &localaddr, 0); MSG_WriteLong(&sb, ShortSwap(localaddr.port)); + MSG_WriteByte(&sb, 1/*MOD_PROQUAKE*/); + MSG_WriteByte(&sb, 10 * 3.50/*MOD_PROQUAKE_VERSION*/); *(int*)sb.data = BigLong(NETFLAG_CTL|sb.cursize); NET_SendPacket(NS_SERVER, sb.cursize, sb.data, net_from); return; @@ -1823,6 +1829,8 @@ client_t *SVC_DirectConnect(void) { numssclients = 1; protocol = SCP_NETQUAKE; //because we can + if (atoi(Info_ValueForKey(Cmd_Argv(4), "mod")) == 1) + protocol = SCP_PROQUAKE; } else if (version != PROTOCOL_VERSION_QW) { @@ -3005,7 +3013,7 @@ void SVNQ_ConnectionlessPacket(void) { client_t *newcl; /*okay, so this is a reliable packet from a client, containing a 'cmd challengeconnect $challenge' response*/ - str = va("connect %i %i %s \"\\name\\unconnected\"", NET_PROTOCOL_VERSION, 0, Cmd_Argv(1)); + str = va("connect %i %i %s \"\\name\\unconnected\\mod\\%s\\modver\\%s\\flags\\%s\\password\\%s\"", NET_PROTOCOL_VERSION, 0, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3), Cmd_Argv(4)); Cmd_TokenizeString (str, false, false); newcl = SVC_DirectConnect(); @@ -3037,13 +3045,16 @@ void SVNQ_ConnectionlessPacket(void) NET_SendPacket(NS_SERVER, sb.cursize, sb.data, net_from); - /*resend the cmd request, cos if they didn't send it then it must have gotten dropped*/ + /*resend the cmd request, cos if they didn't send it then it must have gotten dropped. + at this point, we assume its a proquake clone and that it already thinks that we are proquake + a vanilla client will not start spamming nops until it has received the server info, so its only the proquake clients+clones that will send a nop before a challengeconnect + unfortunatly we don't know the modver+flags+password any more. I hope its not needed. if it does, server admins will be forced to use sv_listen_nq 1 instead of 2*/ SZ_Clear(&sb); MSG_WriteLong(&sb, 0); MSG_WriteLong(&sb, 0); MSG_WriteByte(&sb, svc_stufftext); - MSG_WriteString(&sb, va("cmd challengeconnect %i\n", SV_NewChallenge())); + MSG_WriteString(&sb, va("cmd challengeconnect %i %i\n", SV_NewChallenge(), 1/*MOD_PROQUAKE*/)); *(int*)sb.data = BigLong(NETFLAG_UNRELIABLE|sb.cursize); NET_SendPacket(NS_SERVER, sb.cursize, sb.data, net_from); @@ -3101,6 +3112,8 @@ void SVNQ_ConnectionlessPacket(void) MSG_WriteByte(&sb, CCREP_ACCEPT); NET_LocalAddressForRemote(svs.sockets, &net_from, &localaddr, 0); MSG_WriteLong(&sb, ShortSwap(localaddr.port)); + MSG_WriteByte(&sb, 1/*MOD_PROQUAKE*/); + MSG_WriteByte(&sb, 10 * 3.50/*MOD_PROQUAKE_VERSION*/); *(int*)sb.data = BigLong(NETFLAG_CTL|sb.cursize); NET_SendPacket(NS_SERVER, sb.cursize, sb.data, net_from); @@ -3110,7 +3123,7 @@ void SVNQ_ConnectionlessPacket(void) MSG_WriteLong(&sb, 0); MSG_WriteByte(&sb, svc_stufftext); - MSG_WriteString(&sb, va("cmd challengeconnect %i\n", SV_NewChallenge())); + MSG_WriteString(&sb, va("cmd challengeconnect %i %i %i %i %i\n", SV_NewChallenge(), mod, modver, flags, passwd)); *(int*)sb.data = BigLong(NETFLAG_UNRELIABLE|sb.cursize); NET_SendPacket(NS_SERVER, sb.cursize, sb.data, net_from); @@ -3118,7 +3131,7 @@ void SVNQ_ConnectionlessPacket(void) } else { - str = va("connect %i %i %i \"\\name\\unconnected\"", NET_PROTOCOL_VERSION, 0, SV_NewChallenge()); + str = va("connect %i %i %i \"\\name\\unconnected\\mod\\%i\\modver\\%i\\flags\\%i\\password\\%i\"", NET_PROTOCOL_VERSION, 0, SV_NewChallenge(), mod, modver, flags, passwd); Cmd_TokenizeString (str, false, false); SVC_DirectConnect(); diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index cf53bb333..48db7bc6d 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -253,6 +253,7 @@ void SV_PrintToClient(client_t *cl, int level, char *string) case SCP_DARKPLACES6: case SCP_DARKPLACES7: case SCP_NETQUAKE: + case SCP_PROQUAKE: case SCP_FITZ666: #ifdef NQPROT ClientReliableWrite_Begin (cl, svc_print, strlen(string)+3); @@ -282,6 +283,7 @@ void SV_StuffcmdToClient(client_t *cl, char *string) case SCP_DARKPLACES6: case SCP_DARKPLACES7: case SCP_NETQUAKE: + case SCP_PROQUAKE: case SCP_FITZ666: ClientReliableWrite_Begin (cl, svc_stufftext, strlen(string)+3); ClientReliableWrite_String (cl, string); @@ -612,6 +614,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int break; #ifdef NQPROT case SCP_NETQUAKE: + case SCP_PROQUAKE: case SCP_FITZ666: case SCP_DARKPLACES6: case SCP_DARKPLACES7: @@ -764,6 +767,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int #ifdef NQPROT case SCP_NETQUAKE: + case SCP_PROQUAKE: case SCP_FITZ666: case SCP_DARKPLACES6: case SCP_DARKPLACES7: //extra prediction stuff diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index d8999b766..080fdf12e 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -520,9 +520,10 @@ void SVNQ_New_f (void) { #ifdef NQPROT case SCP_NETQUAKE: + case SCP_PROQUAKE: case SCP_FITZ666: SV_LogPlayer(host_client, "new (NQ)"); - if (sv.nqdatagram.prim.anglesize != 1 || sv.nqdatagram.prim.coordsize != 2 || sv_protocol_nq.ival == 666) + if (sv.nqdatagram.prim.anglesize != 1 || sv.nqdatagram.prim.coordsize != 2 || sv_protocol_nq.ival == 666 || host_client->protocol == SCP_FITZ666) { int rmqfl = ((sv.nqdatagram.prim.coordsize==4)?RMQFL_FLOATCOORD:0) | @@ -542,7 +543,7 @@ void SVNQ_New_f (void) } else { - host_client->protocol = SCP_NETQUAKE; + host_client->protocol = (host_client->protocol==SCP_PROQUAKE)?SCP_PROQUAKE:SCP_NETQUAKE; //identical other than the client->server angles MSG_WriteLong (&host_client->netchan.message, NQ_PROTOCOL_VERSION); host_client->datagram.maxsize = MAX_NQDATAGRAM; } @@ -6283,7 +6284,7 @@ void SV_ExecuteClientMessage (client_t *cl) { if (msg_badread) { - Con_Printf ("SV_ReadClientMessage: badread\n"); + Con_Printf ("SVQW_ReadClientMessage: badread\n"); SV_DropClient (cl); return; } @@ -6298,7 +6299,7 @@ haveannothergo: switch (c) { default: - Con_Printf ("SV_ReadClientMessage: unknown command char %i\n", c); + Con_Printf ("SVQW_ReadClientMessage: unknown command char %i\n", c); SV_DropClient (cl); return; @@ -6414,7 +6415,7 @@ haveannothergo: if (msg_badread) { - Con_Printf ("SV_ReadClientMessage: badread\n"); + Con_Printf ("SV_QWReadClientMessage: badread\n"); SV_DropClient (cl); return; } @@ -6583,7 +6584,7 @@ void SVQ2_ExecuteClientMessage (client_t *cl) switch (c) { default: - Con_Printf ("SV_ReadClientMessage: unknown command char %i\n", c); + Con_Printf ("SVQ2_ReadClientMessage: unknown command char %i\n", c); SV_DropClient (cl); return; @@ -6719,7 +6720,10 @@ void SVNQ_ReadClientMove (usercmd_t *move) // read current angles for (i=0 ; i<3 ; i++) { - host_client->edict->v->v_angle[i] = MSG_ReadAngle (); + if ((host_client->protocol == SCP_FITZ666 || host_client->protocol == SCP_PROQUAKE)) + host_client->edict->v->v_angle[i] = MSG_ReadAngle16 (); + else + host_client->edict->v->v_angle[i] = MSG_ReadAngle (); move->angles[i] = (host_client->edict->v->v_angle[i] * 256*256)/360; } @@ -6831,7 +6835,7 @@ void SVNQ_ExecuteClientMessage (client_t *cl) { if (msg_badread) { - Con_Printf ("SV_ReadClientMessage: badread\n"); + Con_Printf ("SVNQ_ReadClientMessage: badread\n"); SV_DropClient (cl); return; } @@ -6843,7 +6847,7 @@ void SVNQ_ExecuteClientMessage (client_t *cl) switch (c) { default: - Con_Printf ("SV_ReadClientMessage: unknown command char %i\n", c); + Con_Printf ("SVNQ_ReadClientMessage: unknown command char %i\n", c); SV_DropClient (cl); return;