From 95948b35ecd684d9ff388f5f05b8b31f5af6a90b Mon Sep 17 00:00:00 2001 From: Spoike Date: Thu, 26 May 2005 12:55:34 +0000 Subject: [PATCH] Rewrote FTE's NQ-compatable networking code. The nqnet functions have gone, as we support both udp and ipx through the qw code. cl_netfps has also had some work. Added polling of http-based master servers (gameaholic). Lots of darkplaces compatability things added, for nexuiz. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1054 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/Makefile | 23 +- engine/client/cd_win.c | 27 +- engine/client/cl_demo.c | 45 +- engine/client/cl_ents.c | 19 +- engine/client/cl_input.c | 378 +++----- engine/client/cl_main.c | 321 ++++--- engine/client/cl_master.h | 3 + engine/client/cl_parse.c | 119 ++- engine/client/cl_pred.c | 20 +- engine/client/cl_screen.c | 2 +- engine/client/cl_tent.c | 8 +- engine/client/client.h | 16 +- engine/client/keys.c | 4 +- engine/client/m_download.c | 4 +- engine/client/m_master.c | 9 +- engine/client/m_mp3.c | 18 +- engine/client/menu.c | 2 +- engine/client/net_master.c | 166 +++- engine/client/quakedef.h | 1 + engine/client/r_part.c | 8 +- engine/client/sbar.c | 14 +- engine/client/skin.c | 4 +- engine/client/snd_dma.c | 5 +- engine/client/snd_mix.c | 7 +- engine/client/snd_ov.c | 10 + engine/client/snd_win.c | 2 +- engine/client/textedit.c | 19 +- engine/client/view.c | 32 +- engine/common/bspfile.h | 16 +- engine/common/cmd.c | 4 +- engine/common/common.c | 104 +- engine/common/cvar.c | 2 +- engine/common/gl_q2bsp.c | 134 ++- engine/common/mathlib.c | 4 +- engine/common/net.h | 47 +- engine/common/net_chan.c | 171 +++- engine/common/net_wins.c | 92 +- engine/common/plugin.c | 4 +- engine/common/protocol.h | 4 + engine/ftequake/ftequake.dsp | 54 +- engine/gl/gl_alias.c | 38 +- engine/gl/gl_backend.c | 15 +- engine/gl/gl_model.h | 2 +- engine/gl/gl_rlight.c | 46 +- engine/gl/gl_rsurf.c | 2 +- engine/gl/gl_shader.c | 40 +- engine/gl/gl_warp.c | 3 +- engine/gl/shader.h | 3 +- engine/http/ftpclient.c | 58 +- engine/http/httpclient.c | 67 +- engine/http/iweb.h | 4 +- engine/nqnet/net_dgrm.c | 1717 ---------------------------------- engine/nqnet/net_dgrm.h | 37 - engine/nqnet/net_loop.c | 268 ------ engine/nqnet/net_loop.h | 37 - engine/nqnet/net_main.c | 1004 -------------------- engine/nqnet/net_ser.h | 33 - engine/nqnet/net_udp.c | 429 --------- engine/nqnet/net_vcr.c | 22 - engine/nqnet/net_vcr.h | 37 - engine/nqnet/net_win.c | 765 --------------- engine/nqnet/net_wins.h | 39 - engine/nqnet/net_wipx.c | 442 --------- engine/nqnet/net_wipx.h | 39 - engine/nqnet/nqnet.h | 331 ------- engine/qclib/qccmain.c | 6 +- engine/server/net_preparse.c | 55 +- engine/server/pr_cmds.c | 149 ++- engine/server/savegame.c | 2 +- engine/server/server.h | 24 +- engine/server/sv_ccmds.c | 36 +- engine/server/sv_ents.c | 53 +- engine/server/sv_init.c | 6 +- engine/server/sv_main.c | 1077 +++++++++++---------- engine/server/sv_phys.c | 33 +- engine/server/sv_send.c | 196 ++-- engine/server/sv_sys_unix.c | 5 +- engine/server/sv_sys_win.c | 5 +- engine/server/sv_user.c | 87 +- engine/server/world.c | 12 +- engine/sw/r_bsp.c | 2 +- 81 files changed, 2268 insertions(+), 6880 deletions(-) delete mode 100644 engine/nqnet/net_dgrm.c delete mode 100644 engine/nqnet/net_dgrm.h delete mode 100644 engine/nqnet/net_loop.c delete mode 100644 engine/nqnet/net_loop.h delete mode 100644 engine/nqnet/net_main.c delete mode 100644 engine/nqnet/net_ser.h delete mode 100644 engine/nqnet/net_udp.c delete mode 100644 engine/nqnet/net_vcr.c delete mode 100644 engine/nqnet/net_vcr.h delete mode 100644 engine/nqnet/net_win.c delete mode 100644 engine/nqnet/net_wins.h delete mode 100644 engine/nqnet/net_wipx.c delete mode 100644 engine/nqnet/net_wipx.h delete mode 100644 engine/nqnet/nqnet.h diff --git a/engine/Makefile b/engine/Makefile index 26d42408..3f831cec 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -32,7 +32,6 @@ GL_DIR=$(BASE_DIR)/gl SW_DIR=$(BASE_DIR)/sw SERVER_DIR=$(BASE_DIR)/server COMMON_DIR=$(BASE_DIR)/common -NQPROT_DIR=$(BASE_DIR)/nqnet HTTP_DIR=$(BASE_DIR)/http #LIBS_DIR=$(BASE_DIR)/libs LIBS_DIR?=. @@ -96,14 +95,6 @@ RELEASE_CFLAGS=-O6 -s -fno-strict-aliasing -ffast-math -funroll-loops -fexpensiv GLCFLAGS=-DGLQUAKE SWCFLAGS=-DSWQUAKE -NQPROT_OBJS = \ - net_main.o \ - net_loop.o \ - net_dgrm.o \ - net_udp.o \ - net_wipx.o \ - net_vcr.o - CLIENT_OBJS = $(CLIENT_ASM_OBJS) \ textedit.o \ fragstats.o \ @@ -326,7 +317,7 @@ SW_CFLAGS=$(SWCFLAGS) `sdl-config --cflags` SWB_DIR=sw_sdl SWCL_DIR=swcl_sdl -SV_OBJS=$(COMMON_OBJS) $(NQPROT_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS) +SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(SERVERONLY_OBJS) SV_EXE_NAME=../fteqw.sv SV_CFLAGS=$(SERVER_ONLY_CFLAGS) @@ -337,7 +328,7 @@ ifeq ($(FTE_TARGET),win32) SV_EXE_NAME=../fteqwsv.exe SV_LDFLAGS=libs/zlib.lib -lwsock32 SV_DIR=sv_mingw - SV_OBJS=$(COMMON_OBJS) $(NQPROT_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) + SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) ifeq ($(USEASM),true) GLCL_OBJS=$(GL_OBJS) $(GLQUAKE_OBJS) gl_vidnt.o snd_win.o cd_win.o in_win.o sys_win.o sys_dosa.o @@ -469,7 +460,7 @@ SV_DIR?=sv_sdl .default: help all: sv-rel sw-rel gl-rel m-rel plugins -VPATH = $(BASE_DIR) : $(CLIENT_DIR) : $(GL_DIR) : $(COMMON_DIR) : $(SW_DIR) : $(SERVER_DIR) : $(NQPROT_DIR) : $(HTTP_DIR) : $(BASE_DIR)/irc : $(BASE_DIR)/email : $(QUX_DIR) : $(PROGS_DIR) : $(SNDCODEC_DIR) +VPATH = $(BASE_DIR) : $(CLIENT_DIR) : $(GL_DIR) : $(COMMON_DIR) : $(SW_DIR) : $(SERVER_DIR) : $(HTTP_DIR) : $(BASE_DIR)/irc : $(BASE_DIR)/email : $(QUX_DIR) : $(PROGS_DIR) : $(SNDCODEC_DIR) $(OUT_DIR)/%.o : %.c @@ -501,16 +492,16 @@ _out-dbg: $(MAKE) $(OUT_DIR)/$(EXE_NAME) EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(WCFLAGS) $(DEBUG_CFLAGS)" LDFLAGS="$(BASELDFLAGS) $(LDFLAGS)" OBJS="$(OBJS)" _cl-rel: - $(MAKE) _out-rel EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(CLIENT_ONLY_CFLAGS) $(WCFLAGS)" LDFLAGS="$(LDFLAGS)" SOBJS="$(SOBJS)" OBJS="SOBJS COMMON_OBJS NQPROT_OBJS CLIENT_OBJS PROGS_OBJS" + $(MAKE) _out-rel EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(CLIENT_ONLY_CFLAGS) $(WCFLAGS)" LDFLAGS="$(LDFLAGS)" SOBJS="$(SOBJS)" OBJS="SOBJS COMMON_OBJS CLIENT_OBJS PROGS_OBJS" _cl-dbg: - $(MAKE) _out-dbg EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(CLIENT_ONLY_CFLAGS) $(WCFLAGS)" LDFLAGS="$(LDFLAGS)" SOBJS="$(SOBJS)" OBJS="SOBJS COMMON_OBJS NQPROT_OBJS CLIENT_OBJS PROGS_OBJS" + $(MAKE) _out-dbg EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(CLIENT_ONLY_CFLAGS) $(WCFLAGS)" LDFLAGS="$(LDFLAGS)" SOBJS="$(SOBJS)" OBJS="SOBJS COMMON_OBJS CLIENT_OBJS PROGS_OBJS" _clsv-rel: reldir - $(MAKE) _out-rel EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(JOINT_CFLAGS) $(WCFLAGS)" LDFLAGS="$(LDFLAGS)" SOBJS="$(SOBJS)" OBJS="SOBJS COMMON_OBJS NQPROT_OBJS CLIENT_OBJS PROGS_OBJS SERVER_OBJS" + $(MAKE) _out-rel EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(JOINT_CFLAGS) $(WCFLAGS)" LDFLAGS="$(LDFLAGS)" SOBJS="$(SOBJS)" OBJS="SOBJS COMMON_OBJS CLIENT_OBJS PROGS_OBJS SERVER_OBJS" _clsv-dbg: debugdir - $(MAKE) _out-dbg EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(JOINT_CFLAGS) $(WCFLAGS)" LDFLAGS="$(LDFLAGS)" SOBJS="$(SOBJS)" OBJS="SOBJS COMMON_OBJS NQPROT_OBJS CLIENT_OBJS PROGS_OBJS SERVER_OBJS" + $(MAKE) _out-dbg EXE_NAME="$(EXE_NAME)" OUT_DIR="$(OUT_DIR)" WCFLAGS="$(JOINT_CFLAGS) $(WCFLAGS)" LDFLAGS="$(LDFLAGS)" SOBJS="$(SOBJS)" OBJS="SOBJS COMMON_OBJS CLIENT_OBJS PROGS_OBJS SERVER_OBJS" sv-tmp: reldir debugdir diff --git a/engine/client/cd_win.c b/engine/client/cd_win.c index 55d11c32..fb96c688 100644 --- a/engine/client/cd_win.c +++ b/engine/client/cd_win.c @@ -106,19 +106,32 @@ void CDAudio_Play(int track, qboolean looping) MCI_STATUS_PARMS mciStatusParms; if (!enabled) + { +#ifndef NOMEDIA + Media_FakeTrack(track, looping); +#endif return; + } if (!cdValid) { CDAudio_GetAudioDiskInfo(); - if (!cdValid) + if (!cdValid) + { +#ifndef NOMEDIA + Media_FakeTrack(track, looping); +#endif return; + } } track = remap[track]; if (track < 1 || track > maxTrack) { +#ifndef NOMEDIA + Media_FakeTrack(track, looping); +#endif Con_DPrintf("CDAudio: Bad track number %u.\n", track); return; } @@ -307,6 +320,12 @@ static void CD_f (void) return; } + if (Q_strcasecmp(command, "loop") == 0) + { + CDAudio_Play((qbyte)Q_atoi(Cmd_Argv (2)), true); + return; + } + if (!cdValid) { CDAudio_GetAudioDiskInfo(); @@ -317,12 +336,6 @@ static void CD_f (void) } } - if (Q_strcasecmp(command, "loop") == 0) - { - CDAudio_Play((qbyte)Q_atoi(Cmd_Argv (2)), true); - return; - } - if (Q_strcasecmp(command, "stop") == 0) { CDAudio_Stop(); diff --git a/engine/client/cl_demo.c b/engine/client/cl_demo.c index a7cdad38..d1f21b24 100644 --- a/engine/client/cl_demo.c +++ b/engine/client/cl_demo.c @@ -482,46 +482,6 @@ qboolean CL_GetMessage (void) return true; } -#ifdef NQPROT -int CLNQ_GetMessage (void) -{ - int r; - if (!cls.netcon) - return 0; -// int i; -// float f; - - while (1) - { - r = NET_GetMessage (cls.netcon); - - if (r == -1) - { - NET_Close(cls.netcon); - cls.netcon = cls.netchan.qsocket = NULL; - } - - if (cls.netcon) - NET_StringToAdr(cls.netcon->address, &net_from); - - if (r != 1 && r != 2) - return r; - - // discard nop keepalive message - if (net_message.cursize == 1 && net_message.data[0] == svc_nop) - Con_Printf ("<-- server to client keepalive\n"); - else - { -/* if (cls.demorecording) - CL_WriteDemoMessage (&net_message); -*/ - return r; - } - } -} - -#endif - /* ==================== @@ -1163,7 +1123,7 @@ void CL_PlayDemo_f (void) { #ifdef Q2CLIENT cls.demoplayback = DPB_QUAKE2; - cls.q2server = true; + cls.protocol = CP_QUAKE2; #else Con_Printf ("ERROR: cannot play Quake2 demos.\n"); CL_StopPlayback(); @@ -1173,7 +1133,7 @@ void CL_PlayDemo_f (void) else { #ifdef Q2CLIENT - cls.q2server = false; + cls.protocol = CP_QUAKEWORLD; #endif ft = 0; //work out if the first line is a int for the track number. while ((c = getc(cls.demofile)) != '\n') @@ -1192,6 +1152,7 @@ void CL_PlayDemo_f (void) CL_StopPlayback(); return; #else + cls.protocol = CP_NETQUAKE; cls.demoplayback = DPB_NETQUAKE; //nq demos. :o) #endif } diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index b7231fc1..8d15689e 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -665,9 +665,9 @@ entity_state_t *CL_FindOldPacketEntity(int num) int pnum; entity_state_t *s1; packet_entities_t *pack; - if (!cls.netchan.incoming_sequence) + if (!cl.validsequence) return NULL; - pack = &cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities; + pack = &cl.frames[(cl.validsequence)&UPDATE_MASK].packet_entities; for (pnum=0 ; pnumnum_entities ; pnum++) { @@ -892,10 +892,11 @@ void CLNQ_ParseDarkPlaces5Entities(void) //the things I do.. :o( int oldi; qboolean remove; - cl.validsequence = cls.netchan.incoming_sequence++; - cl_latestframenum = MSG_ReadLong(); + if (nq_dp_protocol >=7) + /*cl.servermovesequence =*/ MSG_ReadLong(); + pack = &cl.frames[(cls.netchan.incoming_sequence)&UPDATE_MASK].packet_entities; oldpack = &cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities; @@ -1370,7 +1371,7 @@ void CL_LinkPacketEntities (void) { entity_t *ent; packet_entities_t *pack; - entity_state_t *s1; + entity_state_t *s1, *s2; float f; model_t *model; vec3_t old_origin; @@ -1382,7 +1383,7 @@ void CL_LinkPacketEntities (void) vec3_t angles; int flicker; - pack = &cl.frames[cl.validsequence&UPDATE_MASK].packet_entities; + pack = &cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities; autorotate = anglemod(100*cl.time); @@ -1544,7 +1545,7 @@ void CL_LinkPacketEntities (void) if (ent->keynum <= MAX_CLIENTS #ifdef NQPROT - && cls.demoplayback != DPB_NETQUAKE && (!cls.netcon || cls.netcon->qwprotocol) + && cls.protocol != CP_NETQUAKE #endif ) ent->keynum += MAX_EDICTS; @@ -2365,7 +2366,7 @@ void CL_LinkViewModel(void) return; #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) return; #endif @@ -2673,7 +2674,7 @@ void CL_EmitEntities (void) CL_DecayLights (); #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) { CLQ2_AddEntities(); return; diff --git a/engine/client/cl_input.c b/engine/client/cl_input.c index 15efed22..f43c92eb 100644 --- a/engine/client/cl_input.c +++ b/engine/client/cl_input.c @@ -37,6 +37,8 @@ cvar_t cl_netfps = {"cl_netfps", "0"}; cvar_t cl_smartjump = {"cl_smartjump", "1"}; +usercmd_t independantphysics[MAX_SPLITS]; + /* =============================================================================== @@ -205,7 +207,7 @@ void IN_JumpDown (void) condition = (cls.state == ca_active && cl_smartjump.value); #ifdef Q2CLIENT - if (condition && cls.q2server) + if (condition && cls.protocol == CP_QUAKE2) KeyDown(&in_up); else #endif @@ -461,43 +463,38 @@ CL_BaseMove Send the intended movement message to the server ================ */ -void CL_BaseMove (usercmd_t *cmd, int pnum) +void CL_BaseMove (usercmd_t *cmd, int pnum, float extra, float wantfps) { - CL_AdjustAngles (pnum); - - VectorCopy (cl.viewangles[pnum], cmd->angles); + float scale = 1;//extra/1000.0f * 1/wantfps; + +// +// adjust for speed key +// + if (in_speed.state[pnum] & 1) + scale *= cl_movespeedkey.value; + if (in_strafe.state[pnum] & 1) { - cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_right, pnum); - cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_left, pnum); + cmd->sidemove += scale*cl_sidespeed.value * CL_KeyState (&in_right, pnum); + cmd->sidemove -= scale*cl_sidespeed.value * CL_KeyState (&in_left, pnum); } - cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_moveright, pnum); - cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_moveleft, pnum); + cmd->sidemove += scale*cl_sidespeed.value * CL_KeyState (&in_moveright, pnum); + cmd->sidemove -= scale*cl_sidespeed.value * CL_KeyState (&in_moveleft, pnum); #ifdef IN_XFLIP if(in_xflip.value) cmd->sidemove *= -1; #endif - cmd->upmove += cl_upspeed.value * CL_KeyState (&in_up, pnum); - cmd->upmove -= cl_upspeed.value * CL_KeyState (&in_down, pnum); + cmd->upmove += scale*cl_upspeed.value * CL_KeyState (&in_up, pnum); + cmd->upmove -= scale*cl_upspeed.value * CL_KeyState (&in_down, pnum); if (! (in_klook.state[pnum] & 1) ) { - cmd->forwardmove += cl_forwardspeed.value * CL_KeyState (&in_forward, pnum); - cmd->forwardmove -= cl_backspeed.value * CL_KeyState (&in_back, pnum); - } - -// -// adjust for speed key -// - if (in_speed.state[pnum] & 1) - { - cmd->forwardmove *= cl_movespeedkey.value; - cmd->sidemove *= cl_movespeedkey.value; - cmd->upmove *= cl_movespeedkey.value; - } + cmd->forwardmove += scale*cl_forwardspeed.value * CL_KeyState (&in_forward, pnum); + cmd->forwardmove -= scale*cl_backspeed.value * CL_KeyState (&in_back, pnum); + } } int MakeChar (int i) @@ -513,7 +510,7 @@ void CL_ClampPitch (int pnum) { #ifdef Q2CLIENT float pitch; - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) { pitch = SHORT2ANGLE(cl.q2frame.playerstate.pmove.delta_angles[PITCH]); if (pitch > 180) @@ -572,12 +569,8 @@ void CL_FinishMove (usercmd_t *cmd, int msecs, int pnum) cmd->buttons = bits; // send milliseconds of time to apply the move - ms = msecs;//host_frametime * 1000; -// if (ms > 250) -// ms = 100; // time was unreasonable - cmd->msec = ms; + cmd->msec = msecs; - //VectorCopy (cl.viewangles, cmd->angles); for (i=0 ; i<3 ; i++) cmd->angles[i] = ((int)(cl.viewangles[pnum][i]*65536.0/360)&65535); @@ -589,17 +582,10 @@ void CL_FinishMove (usercmd_t *cmd, int msecs, int pnum) } else cmd->impulse = 0; - - -// -// chop down so no extra bits are kept that the server wouldn't get -// - cmd->forwardmove = MakeChar (cmd->forwardmove); - cmd->sidemove = MakeChar (cmd->sidemove); - cmd->upmove = MakeChar (cmd->upmove); } cvar_t cl_prydoncursor = {"cl_prydoncursor", "0"}; +void ML_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy); void CL_UpdatePrydonCursor(float cursor_screen[2], vec3_t cursor_start, vec3_t cursor_impact, int *entnum) { float modelview[16]; @@ -648,10 +634,11 @@ void CL_UpdatePrydonCursor(float cursor_screen[2], vec3_t cursor_start, vec3_t c VectorCopy(cl.simorg[0], cursor_start); - temp[0] = cursor_screen[2] * scale[2]; - temp[1] = cursor_screen[0] * scale[0]; - temp[2] = cursor_screen[1] * scale[1]; + temp[0] = cursor_screen[0]; + temp[1] = cursor_screen[1]; + temp[2] = 1; +// ML_UnProject(temp, cursor_end, cl.viewangles[0], cl.simorg[0], vid.width/vid.height, 90); ML_ModelViewMatrix(modelview, cl.viewangles[0], cl.simorg[0]); Matrix4_Transform3(modelview, temp, cursor_end); @@ -663,34 +650,42 @@ void CL_UpdatePrydonCursor(float cursor_screen[2], vec3_t cursor_start, vec3_t c // CL_SelectTraceLine(cursor_start, cursor_end, cursor_impact, entnum); // makes sparks where cursor is //CL_SparkShower(cl.cmd.cursor_impact, cl.cmd.cursor_normal, 5, 0); + P_RunParticleEffectType(cursor_impact, vec3_origin, 1, 0); +//P_ParticleTrail(cursor_start, cursor_impact, 0, NULL); } #ifdef NQPROT -void CLNQ_SendMove (usercmd_t *cmd, int pnum) +void CLNQ_SendMove (usercmd_t *cmd, int pnum, sizebuf_t *buf) { int bits; int i; - sizebuf_t buf; - qbyte data[128]; float cursor_screen[2]; vec3_t cursor_start, cursor_impact; int cursor_entitynumber=0;//I hate warnings as errors - - buf.maxsize = 128; - buf.cursize = 0; - buf.data = data; - MSG_WriteByte (&buf, clc_move); + if (cls.demoplayback!=DPB_NONE) + return; //err... don't bother... :) +// +// allways dump the first two message, because it may contain leftover inputs +// from the last level +// + if (++cl.movemessages <= 2) + return; - MSG_WriteFloat (&buf, cl.gametime); // so server can get ping times + MSG_WriteByte (buf, clc_move); + + if (nq_dp_protocol>=7) + MSG_WriteLong(buf, 0); + + MSG_WriteFloat (buf, cl.gametime); // so server can get ping times for (i=0 ; i<3 ; i++) - MSG_WriteAngle (&buf, cl.viewangles[pnum][i]); + MSG_WriteAngle (buf, cl.viewangles[pnum][i]); - MSG_WriteShort (&buf, cmd->forwardmove); - MSG_WriteShort (&buf, cmd->sidemove); - MSG_WriteShort (&buf, cmd->upmove); + MSG_WriteShort (buf, cmd->forwardmove); + MSG_WriteShort (buf, cmd->sidemove); + MSG_WriteShort (buf, cmd->upmove); // // send button bits @@ -707,77 +702,58 @@ void CLNQ_SendMove (usercmd_t *cmd, int pnum) if (in_button7.state[pnum] & 3) bits |= 64; in_button7.state[pnum] &= ~2; if (in_button8.state[pnum] & 3) bits |= 128; in_button8.state[pnum] &= ~2; - if (nq_dp_protocol == 6) + if (nq_dp_protocol >= 6) { CL_UpdatePrydonCursor(cursor_screen, cursor_start, cursor_impact, &cursor_entitynumber); - MSG_WriteLong (&buf, bits); + MSG_WriteLong (buf, bits); } else - MSG_WriteByte (&buf, bits); + MSG_WriteByte (buf, bits); if (in_impulsespending[pnum]) { in_nextimpulse[pnum]++; in_impulsespending[pnum]--; - MSG_WriteByte(&buf, in_impulse[pnum][(in_nextimpulse[pnum]-1)%IN_IMPULSECACHE]); + MSG_WriteByte(buf, in_impulse[pnum][(in_nextimpulse[pnum]-1)%IN_IMPULSECACHE]); } else - MSG_WriteByte (&buf, 0); + MSG_WriteByte (buf, 0); - if (nq_dp_protocol == 6) + if (nq_dp_protocol >= 6) { - MSG_WriteShort (&buf, cursor_screen[0] * 32767.0f); - MSG_WriteShort (&buf, cursor_screen[1] * 32767.0f); - MSG_WriteFloat (&buf, cursor_start[0]); - MSG_WriteFloat (&buf, cursor_start[1]); - MSG_WriteFloat (&buf, cursor_start[2]); - MSG_WriteFloat (&buf, cursor_impact[0]); - MSG_WriteFloat (&buf, cursor_impact[1]); - MSG_WriteFloat (&buf, cursor_impact[2]); - MSG_WriteShort (&buf, cursor_entitynumber); - } - - - -// -// deliver the message -// - if (cls.demoplayback!=DPB_NONE) - return; //err... don't bother... :) - -// -// allways dump the first two message, because it may contain leftover inputs -// from the last level -// - if (++cl.movemessages <= 2) - return; - - if (NET_SendUnreliableMessage (cls.netcon, &buf) == -1) - { - Con_Printf ("CL_SendMove: lost server connection\n"); - CL_Disconnect (); + MSG_WriteShort (buf, cursor_screen[0] * 32767.0f); + MSG_WriteShort (buf, cursor_screen[1] * 32767.0f); + MSG_WriteFloat (buf, cursor_start[0]); + MSG_WriteFloat (buf, cursor_start[1]); + MSG_WriteFloat (buf, cursor_start[2]); + MSG_WriteFloat (buf, cursor_impact[0]); + MSG_WriteFloat (buf, cursor_impact[1]); + MSG_WriteFloat (buf, cursor_impact[2]); + MSG_WriteShort (buf, cursor_entitynumber); } } + void CLNQ_SendCmd(void) { extern int cl_latestframenum, nq_dp_protocol; - usercmd_t cmd; + sizebuf_t unrel; + char unrel_buf[256]; if (cls.state <= ca_connected) return; + memset(&unrel, 0, sizeof(unrel)); + unrel.data = unrel_buf; + unrel.maxsize = sizeof(unrel_buf); + if (cls.signon == 4) { - memset(&cmd, 0, sizeof(cmd)); - // get basic movement from keyboard - CL_BaseMove (&cmd, 0); - - // allow mice or other external controllers to add to the move - IN_Move (&cmd, 0); - // send the unreliable message - CLNQ_SendMove (&cmd, 0); + if (independantphysics[0].impulse && !cls.netchan.message.cursize) + CLNQ_SendMove (&independantphysics[0], 0, &cls.netchan.message); + else + CLNQ_SendMove (&independantphysics[0], 0, &unrel); } if (name.modified) @@ -792,46 +768,13 @@ void CLNQ_SendCmd(void) MSG_WriteLong(&cls.netchan.message, cl_latestframenum); } - -// send the reliable message - if (!cls.netchan.message.cursize) - return; // no message at all - - if (!NET_CanSendMessage (cls.netcon)) - { - Con_DPrintf ("CL_WriteToServer: can't send\n"); - return; - } + Netchan_Transmit(&cls.netchan, unrel.cursize, unrel.data, 2500); - if (NET_SendMessage (cls.netcon, &cls.netchan.message) == -1) - Host_EndGame ("CL_WriteToServer: lost server connection"); - - SZ_Clear (&cls.netchan.message); + memset(&independantphysics[0], 0, sizeof(independantphysics[0])); + cl.allowsendpacket = false; } #endif - -//returns result in the form of the -void ComponantVectors(vec3_t angles, vec3_t move, vec3_t result, float multi) -{ - vec3_t f, r, u; - AngleVectors(angles, f, r, u); - - result[0] = DotProduct (move, f)*multi; - result[1] = DotProduct (move, r)*multi; - result[2] = DotProduct (move, u)*multi; -} - -void AddComponant(vec3_t angles, vec3_t dest, float fm, float rm, float um) -{ - vec3_t f, r, u; - AngleVectors(angles, f, r, u); - - VectorMA(dest, fm, f, dest); - VectorMA(dest, rm, r, dest); - VectorMA(dest, um, u, dest); -} - float CL_FilterTime (double time, float wantfps) //now returns the extra time not taken in this slot. Note that negative 1 means uncapped. { extern cvar_t rate; @@ -1016,7 +959,6 @@ void CL_UseIndepPhysics(qboolean allow) CL_SendCmd ================= */ -usercmd_t independantphysics[MAX_SPLITS]; vec3_t accum[MAX_SPLITS]; void CL_SendCmd (float frametime) { @@ -1030,6 +972,7 @@ void CL_SendCmd (float frametime) int firstsize; int extramsec; vec3_t v; + float wantfps; qbyte lightlev; @@ -1082,8 +1025,9 @@ void CL_SendCmd (float frametime) cmd->msec = frametime*1000; independantphysics[0].msec = 0; - // get basic movement from keyboard - CL_BaseMove (cmd, 0); + CL_AdjustAngles (plnum); + // get basic movement from keyboard + CL_BaseMove (cmd, 0, 1, 1); // allow mice or other external controllers to add to the move IN_Move (cmd, 0); @@ -1127,14 +1071,6 @@ void CL_SendCmd (float frametime) } } -#ifdef NQPROT - if (cls.netcon && !cls.netcon->qwprotocol) - { - CLNQ_SendCmd (); - return; - } -#endif - if (msecs>150) //q2 has 200 slop. msecs=150; @@ -1144,67 +1080,58 @@ void CL_SendCmd (float frametime) if (msecs<0) msecs=0; //erm. + // if (cls.state < ca_active) // msecs = 0; msecstouse = (int)msecs; //casts round down. - - if (!CL_FilterTime(msecstouse, cl_netfps.value<=0?cl_maxfps.value:cl_netfps.value) && msecstouse<255 && cls.state == ca_active) - { - usercmd_t new; - - for (plnum = 0; plnum < cl.splitclients; plnum++) - { - cmd = &new; - memset(cmd, 0, sizeof(new)); - - // get basic movement from keyboard - CL_BaseMove (cmd, plnum); - - // allow mice or other external controllers to add to the move - IN_Move (cmd, plnum); - - if (cl.spectator) - Cam_Track(plnum, cmd); - - cmd->msec = msecstouse; - extramsec = msecstouse - independantphysics[plnum].msec; - - //acumulate this frame. - AddComponant(cl.viewangles[plnum], accum[plnum], cmd->forwardmove*extramsec, cmd->sidemove*extramsec, cmd->upmove*extramsec); - - //evaluate from accum - ComponantVectors(cl.viewangles[plnum], accum[plnum], v, 1.0f/msecstouse); - independantphysics[plnum].forwardmove = v[0];//MakeChar(v[0]); - independantphysics[plnum].sidemove = v[1];//MakeChar(v[1]); - independantphysics[plnum].upmove = v[2];//MakeChar(v[2]); - - for (i=0 ; i<3 ; i++) - independantphysics[plnum].angles[i] = ((int)(cl.viewangles[plnum][i]*65536.0/360)&65535); - - independantphysics[plnum].msec = msecstouse; - independantphysics[plnum].buttons |= cmd->buttons; - } - return; - } - if (msecstouse > 255) msecstouse = 255; -// Con_Printf("sending %i msecs\n", msecstouse); + wantfps = cl_netfps.value<=0?cl_maxfps.value:cl_netfps.value; + if (wantfps < cls.maxfps ? max (30.0, cls.maxfps) : 0x7fff) + wantfps = cls.maxfps ? max (30.0, cls.maxfps) : 0x7fff; for (plnum = 0; plnum < cl.splitclients; plnum++) { - // save this command off for prediction - i = cls.netchan.outgoing_sequence & UPDATE_MASK; - cmd = &cl.frames[i].cmd[plnum]; - memcpy(cmd, &independantphysics[plnum], sizeof(*cmd)); - cl.frames[i].senttime = realtime; - cl.frames[i].receivedtime = -1; // we haven't gotten a reply yet +// CL_BaseMove (&independantphysics[plnum], plnum, (msecstouse - independantphysics[plnum].msec), wantfps); + CL_AdjustAngles (plnum); + IN_Move (&independantphysics[plnum], plnum); + + for (i=0 ; i<3 ; i++) + independantphysics[plnum].angles[i] = ((int)(cl.viewangles[plnum][i]*65536.0/360)&65535); - memset(&independantphysics[plnum], 0, sizeof(independantphysics[plnum])); + if (!independantphysics[plnum].msec) + { + CL_BaseMove (&independantphysics[plnum], plnum, (msecstouse - independantphysics[plnum].msec), wantfps); + CL_FinishMove(&independantphysics[plnum], msecstouse, plnum); + } + + // if we are spectator, try autocam + if (cl.spectator) + Cam_Track(plnum, cmd); + Cam_FinishMove(plnum, cmd); + independantphysics[plnum].msec = msecstouse; } + if (!CL_FilterTime(msecstouse, cl_netfps.value<=0?cl_maxfps.value:cl_netfps.value) && msecstouse<255 && cls.state == ca_active) + { + return; + } + +#ifdef NQPROT + if (cls.protocol == CP_NETQUAKE) + { + if (!cl.allowsendpacket) + return; + msecs -= msecstouse; + CLNQ_SendCmd (); + return; + } +#endif + +// Con_Printf("sending %i msecs\n", msecstouse); + seq_hash = cls.netchan.outgoing_sequence; // send this and the previous cmds in the message, so @@ -1216,7 +1143,7 @@ void CL_SendCmd (float frametime) if (1) //wait for server data before sending clc_move stuff? nope, mvdsv doesn't like that. { #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) { i = cls.netchan.outgoing_sequence & UPDATE_MASK; cmd = &cl.frames[i].cmd[plnum]; @@ -1267,61 +1194,14 @@ void CL_SendCmd (float frametime) { i = cls.netchan.outgoing_sequence & UPDATE_MASK; cmd = &cl.frames[i].cmd[plnum]; - - // get basic movement from keyboard - CL_BaseMove (cmd, plnum); - - // allow mice or other external controllers to add to the move - IN_Move (cmd, plnum); - - /* - if (cl_minmsec.value>200) - cl_minmsec.value=200; - - if (!(msecstouse > cl_minmsec.value)) - { - cmd->msec = msecstouse; - for (i=0 ; i<3 ; i++) - cmd->angles[i] = ((int)(cl.viewangles[i]*65536.0/360)&65535); - cmd->forwardmove = MakeChar (cmd->forwardmove); - cmd->sidemove = MakeChar (cmd->sidemove); - cmd->upmove = MakeChar (cmd->upmove); - - if (!dropcount) - cls.netchan.outgoing_sequence++; - dropcount = true; - return; - } - else*/ - - // if we are spectator, try autocam - if (cl.spectator) - Cam_Track(plnum, cmd); - - CL_FinishMove(cmd, msecstouse, plnum); - - Cam_FinishMove(plnum, cmd); + *cmd = independantphysics[plnum]; + memset(&independantphysics[plnum], 0, sizeof(independantphysics[plnum])); #ifdef Q2CLIENT - if (cls.q2server && cmd->buttons) - cmd->buttons |= 128; + if (cls.protocol == CP_QUAKE2 && cmd->buttons) + cmd->buttons |= 128; //fixme: this isn't really what's meant by the anykey. #endif - for (i=0 ; i<3 ; i++) - cmd->angles[i] = ((int)(cl.viewangles[plnum][i]*65536.0/360)&65535); - - extramsec = msecstouse - independantphysics[plnum].msec; - //add this frame to accum - AddComponant(cl.viewangles[plnum], accum[plnum], cmd->forwardmove*extramsec, cmd->sidemove*extramsec, cmd->upmove*extramsec); - - //evaluate from accum - ComponantVectors(cl.viewangles[plnum], accum[plnum], v, 1.0f/msecstouse); - cmd->forwardmove = v[0]; - cmd->sidemove = v[1]; - cmd->upmove = v[2]; - - memset(accum[plnum], 0, sizeof(accum[plnum])); //clear accum - if (plnum) MSG_WriteByte (&buf, clc_move); @@ -1355,7 +1235,7 @@ void CL_SendCmd (float frametime) // calculate a checksum over the move commands #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) buf.data[checksumIndex] = Q2COM_BlockSequenceCRCByte( buf.data + checksumIndex + 1, firstsize - checksumIndex - 1, seq_hash); @@ -1368,14 +1248,14 @@ void CL_SendCmd (float frametime) // request delta compression of entities #ifdef Q2CLIENT - if (!cls.q2server) + if (cls.protocol == CP_QUAKEWORLD) #endif if (cls.netchan.outgoing_sequence - cl.validsequence >= UPDATE_BACKUP-1) cl.validsequence = 0; if ( #ifdef Q2CLIENT - !cls.q2server && + cls.protocol == CP_QUAKEWORLD && #endif cl.validsequence && !cl_nodelta.value && cls.state == ca_active && !cls.demorecording) diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 53407eba..28407543 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -145,6 +145,7 @@ entity_t cl_visedicts_list[2][MAX_VISEDICTS]; double connect_time = -1; // for connection retransmits int connect_type = 0; +int connect_tries = 0; //increased each try, every fourth trys nq connect packets. quakeparms_t host_parms; @@ -359,7 +360,7 @@ void CL_SendConnectPacket ( fteprotextsupported &= ftepext; #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) fteprotextsupported = 0; #endif @@ -368,11 +369,7 @@ void CL_SendConnectPacket ( t1 = Sys_DoubleTime (); - if ( -#ifdef NQPROT - !cls.netcon && -#endif - !NET_StringToAdr (cls.servername, &adr)) + if (!NET_StringToAdr (cls.servername, &adr)) { Con_TPrintf (TLC_BADSERVERADDRESS); connect_time = -1; @@ -416,7 +413,7 @@ void CL_SendConnectPacket ( clients = MAX_SPLITS; #ifdef Q2CLIENT - if (cls.q2server) //sorry - too lazy. + if (cls.protocol == CP_QUAKE2) //sorry - too lazy. clients = 1; #endif @@ -434,7 +431,7 @@ void CL_SendConnectPacket ( strcat(data, va("%i", clients)); #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) strcat(data, va(" %i", PROTOCOL_VERSION_Q2)); else #endif @@ -467,20 +464,8 @@ void CL_SendConnectPacket ( else #endif cls.netchan.compress = false; -#ifdef NQPROT - if (cls.netcon) - { - sizebuf_t msg; - msg.allowoverflow = false; - msg.cursize = strlen(data); - msg.data = data; - msg.maxsize = sizeof(data); - msg.overflowed = false; - NET_SendMessage(cls.netcon, &msg); - } - else -#endif - NET_SendPacket (NS_CLIENT, strlen(data), data, adr); + + NET_SendPacket (NS_CLIENT, strlen(data), data, adr); cl.splitclients = 0; CL_RegisterSplitCommands(); @@ -514,14 +499,14 @@ void CL_CheckForResend (void) #endif #ifdef Q2CLIENT case GT_QUAKE2: - cls.q2server = true; + cls.protocol = CP_QUAKE2; break; #endif default: - cls.q2server = false; + cls.protocol = CP_QUAKEWORLD; break; } - + CL_SendConnectPacket (svs.fteprotocolextensions, false); return; } @@ -531,6 +516,7 @@ void CL_CheckForResend (void) return; if (cls.state != ca_disconnected) return; + /* #ifdef NQPROT if (connect_type) { @@ -545,6 +531,7 @@ void CL_CheckForResend (void) return; } #endif + */ if (connect_time && realtime - connect_time < 5.0) return; @@ -568,34 +555,46 @@ void CL_CheckForResend (void) connect_time = realtime+t2-t1; // for retransmit requests - Con_TPrintf (TLC_CONNECTINGTO, cls.servername); - sprintf (data, "%c%c%c%cgetchallenge\n", 255, 255, 255, 255); - NET_SendPacket (NS_CLIENT, strlen(data), data, adr); +#ifdef NQPROT + if (connect_type || ((connect_tries&3)==3)) + { + sizebuf_t sb; + memset(&sb, 0, sizeof(sb)); + sb.data = data; + sb.maxsize = sizeof(data); + + Con_TPrintf (TLC_CONNECTINGTO, cls.servername); + + MSG_WriteLong(&sb, BigLong(NETFLAG_CTL | (strlen(NET_GAMENAME_NQ)+7))); + MSG_WriteByte(&sb, CCREQ_CONNECT); + MSG_WriteString(&sb, NET_GAMENAME_NQ); + MSG_WriteByte(&sb, NET_PROTOCOL_VERSION); + NET_SendPacket (NS_CLIENT, sb.cursize, sb.data, adr); + } + else +#endif + { + Con_TPrintf (TLC_CONNECTINGTO, cls.servername); + sprintf (data, "%c%c%c%cgetchallenge\n", 255, 255, 255, 255); + NET_SendPacket (NS_CLIENT, strlen(data), data, adr); + } + + connect_tries++; } void CL_BeginServerConnect(void) { -#ifdef NQPROT - if (cls.netcon) - { - NET_Close(cls.netcon); - cls.netcon = cls.netchan.qsocket = NULL; - } -#endif connect_time = 0; - connect_type=0; + connect_type = 0; + connect_tries = 0; CL_CheckForResend(); } #ifdef NQPROT void CLNQ_BeginServerConnect(void) { - if (cls.netcon) - { - NET_Close(cls.netcon); - cls.netcon = NULL; - } connect_time = 0; - connect_type=1; + connect_type = 1; + connect_tries = 0; CL_CheckForResend(); } #endif @@ -840,6 +839,10 @@ void CL_ClearState (void) cl.viewheight[i] = DEFAULT_VIEWHEIGHT; cl.minpitch = -70; cl.maxpitch = 80; + + cl.oldgametime = 0; + cl.gametime = 0; + cl.gametimemark = 0; } /* @@ -877,36 +880,33 @@ void CL_Disconnect (void) if (cls.demorecording) CL_Stop_f (); + switch(cls.protocol) + { #ifdef NQPROT - if (cls.netcon) - { - sizebuf_t msg; + case CP_NETQUAKE: final[0] = clc_disconnect; - msg.data = final; - msg.cursize = 1; - msg.maxsize = 10; - NET_SendMessage(cls.netcon, &msg); - NET_SendMessage(cls.netcon, &msg); - NET_SendMessage(cls.netcon, &msg); - } - else + Netchan_Transmit (&cls.netchan, 1, final, 2500); + Netchan_Transmit (&cls.netchan, 1, final, 2500); + Netchan_Transmit (&cls.netchan, 1, final, 2500); + break; #endif - { #ifdef Q2CLIENT - if (cls.q2server) - { - final[0] = clcq2_stringcmd; - strcpy (final+1, "disconnect"); - } - else + case CP_QUAKE2: + final[0] = clcq2_stringcmd; + strcpy (final+1, "disconnect"); + Netchan_Transmit (&cls.netchan, strlen(final)+1, final, 2500); + Netchan_Transmit (&cls.netchan, strlen(final)+1, final, 2500); + Netchan_Transmit (&cls.netchan, strlen(final)+1, final, 2500); + break; + #endif - { - final[0] = clc_stringcmd; - strcpy (final+1, "drop"); - } + case CP_QUAKEWORLD: + final[0] = clc_stringcmd; + strcpy (final+1, "drop"); Netchan_Transmit (&cls.netchan, strlen(final)+1, final, 2500); Netchan_Transmit (&cls.netchan, strlen(final)+1, final, 2500); Netchan_Transmit (&cls.netchan, strlen(final)+1, final, 2500); + break; } cls.state = ca_disconnected; @@ -963,8 +963,6 @@ void CL_Disconnect (void) #ifdef NQPROT cls.signon=0; - NET_Close(cls.netcon); - cls.netcon = NULL; #endif CL_StopUpload(); @@ -973,9 +971,7 @@ void CL_Disconnect (void) #endif SCR_EndLoadingPlaque(); -#ifdef Q2CLIENT - cls.q2server = 0; -#endif + cls.protocol = CP_UNKNOWN; } #undef serverrunning @@ -1121,7 +1117,7 @@ void CL_Color_f (void) else Cvar_Set (&bottomcolor, num); #ifdef NQPROT - if (cls.netcon) + if (cls.protocol == CP_NETQUAKE) Cmd_ForwardToServer(); #endif } @@ -1391,7 +1387,7 @@ void CL_SetInfo_f (void) if (cls.state >= ca_connected) { #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) cls.resendinfo = true; else #endif @@ -1612,7 +1608,7 @@ void CL_Reconnect_f (void) if (cls.downloadqw) // don't change when downloading return; #ifdef NQPROT - if (cls.netcon) + if (cls.protocol == CP_NETQUAKE) { CL_Changing_f(); return; @@ -1687,6 +1683,7 @@ void CL_ConnectionlessPacket (void) if (*s2) {//and if it's not, we're unlikly to be compatable with whatever it is that's talking at us. #ifdef NQPROT + cls.protocol = CP_NETQUAKE; CL_ConnectToDarkPlaces(s+9, net_from); #else Con_Printf("\nUnable connect to DarkPlaces\n"); @@ -1695,7 +1692,7 @@ void CL_ConnectionlessPacket (void) } #ifdef Q2CLIENT - cls.q2server = true; + cls.protocol = CP_QUAKE2; #else Con_Printf("\nUnable to connect to Quake2\n"); #endif @@ -1713,7 +1710,7 @@ void CL_ConnectionlessPacket (void) goto client_connect; } else - cls.q2server = false; + cls.protocol = CP_QUAKEWORLD; #endif cls.challenge = atoi(s); @@ -1736,7 +1733,7 @@ void CL_ConnectionlessPacket (void) return; } #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) { char *nl; msg_readcount--; @@ -1791,16 +1788,12 @@ void CL_ConnectionlessPacket (void) COM_Parse(s); if (!strcmp(com_token, "ccept")) { - cls.netcon = Datagram_ConnectToDarkPlacesServer(&net_from); - - SockadrToNetadr(&cls.netcon->addr, &net_from); - Netchan_Setup(cls.netcon->socket, &cls.netchan, net_from, cls.qport); - cls.netchan.qsocket = cls.netcon; + Netchan_Setup(NS_CLIENT, &cls.netchan, net_from, cls.qport); Con_DPrintf ("CL_EstablishConnection: connected to %s\n", cls.servername); - cls.netchan.qsocket = cls.netcon; cls.netchan.isnqprotocol = true; + cls.protocol = CP_NETQUAKE; cls.demonum = -1; // not in the demo loop now cls.state = ca_connected; @@ -1835,9 +1828,6 @@ client_connect: //fixme: make function compress = cls.netchan.compress; Netchan_Setup (NS_CLIENT, &cls.netchan, net_from, cls.qport); cls.netchan.compress = compress; -#ifdef NQPROT - cls.netchan.qsocket = cls.netcon; -#endif #ifdef Q3CLIENT if (cls.q2server < 2) #endif @@ -1853,8 +1843,8 @@ client_connect: //fixme: make function char cmdtext[2048]; Con_TPrintf (TLC_CONLESS_CONCMD); - if (net_from.type != net_local_ipadr.type - || ((*(unsigned *)net_from.ip != *(unsigned *)net_local_ipadr.ip) && (*(unsigned *)net_from.ip != htonl(INADDR_LOOPBACK)))) + if (net_from.type != net_local_cl_ipadr.type + || ((*(unsigned *)net_from.ip != *(unsigned *)net_local_cl_ipadr.ip) && (*(unsigned *)net_from.ip != htonl(INADDR_LOOPBACK)))) { Con_TPrintf (TLC_CMDFROMREMOTE); return; @@ -1940,6 +1930,46 @@ client_connect: //fixme: make function Con_TPrintf (TLC_CONLESSPACKET_UNKNOWN, c); } +#ifdef NQPROT +void CLNQ_ConnectionlessPacket(void) +{ + char *s; + int length; + + MSG_BeginReading (); + length = BigLong(MSG_ReadLong ()); + if (!(length & NETFLAG_CTL)) + return; //not an nq control packet. + length &= NETFLAG_LENGTH_MASK; + if (length != net_message.cursize) + return; //not an nq packet. + + switch(MSG_ReadByte()) + { + case CCREP_ACCEPT: + if (cls.state >= ca_connected) + { + if (cls.demoplayback == DPB_NONE) + Con_TPrintf (TLC_DUPCONNECTION); + return; + } + net_from.port = htons(MSG_ReadLong()); + Netchan_Setup (NS_CLIENT, &cls.netchan, net_from, cls.qport); + cls.netchan.isnqprotocol = true; + cls.netchan.compress = 0; + cls.protocol = CP_NETQUAKE; + cls.state = ca_connected; + Con_TPrintf (TLC_CONNECTED); + allowremotecmd = false; // localid required now for remote cmds + return; + + case CCREP_REJECT: + s = MSG_ReadString(); + Con_Printf("Connect failed\n%s\n"); + return; + } +} +#endif /* ================= @@ -1954,6 +1984,7 @@ void CL_ReadPackets (void) #ifdef NQPROT if (cls.demoplayback == DPB_NETQUAKE) { + MSG_BeginReading (); cls.netchan.last_received = realtime; CLNQ_ParseServerMessage (); continue; @@ -1983,84 +2014,65 @@ void CL_ReadPackets (void) continue; } + if (cls.state == ca_disconnected) + { //connect to nq servers, but don't get confused with sequenced packets. +#ifdef NQPROT + CLNQ_ConnectionlessPacket (); +#endif + continue; //ignore it. We arn't connected. + } + // // packet from server // if (!cls.demoplayback && !NET_CompareAdr (net_from, cls.netchan.remote_address)) { - Con_DPrintf ("%s:sequenced packet without connection\n" + Con_DPrintf ("%s:sequenced packet from wrong server\n" ,NET_AdrToString(net_from)); continue; } - if (cls.state == ca_disconnected) - continue; //ignore it. We arn't connected. -#ifdef Q3CLIENT - if (cls.q2server == 2) + switch(cls.protocol) { +#ifdef Q3CLIENT + case CP_QUAKE3: CLQ3_ParseServerMessage(); - continue; - } + break; +#endif +#ifdef NQPROT + case CP_NETQUAKE: + switch(NQNetChan_Process(&cls.netchan)) + { + case 0: + break; + case 1: + cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence - 3; + case 2: + CLNQ_ParseServerMessage (); + break; + } + break; #endif - - if (cls.demoplayback == DPB_MVD) - MSG_BeginReading(); - else if (!Netchan_Process(&cls.netchan)) - continue; // wasn't accepted for some reason - #ifdef Q2CLIENT - if (cls.q2server) + case CP_QUAKE2: + if (!Netchan_Process(&cls.netchan)) + continue; // wasn't accepted for some reason CLQ2_ParseServerMessage (); - else + break; #endif + case CP_QUAKEWORLD: + if (cls.demoplayback == DPB_MVD) + MSG_BeginReading(); + else if (!Netchan_Process(&cls.netchan)) + continue; // wasn't accepted for some reason CL_ParseServerMessage (); + break; + } // if (cls.demoplayback && cls.state >= ca_active && !CL_DemoBehind()) // return; } -#ifdef NQPROT - while(CLNQ_GetMessage()>0) - { - //allow qw protocol over nq transports - if (cls.netcon->qwprotocol) - { - if (*(int *)net_message.data == -1) - { - CL_ConnectionlessPacket (); - continue; - } - - if (net_message.cursize < 8) - { - Con_TPrintf (TL_RUNTPACKET,NET_AdrToString(net_from)); - continue; - } - - if (cls.state == ca_disconnected) - continue; //ignore it. We arn't connected. - - memcpy(&cls.netchan.remote_address, &net_from, sizeof(net_from)); - if (!Netchan_Process(&cls.netchan)) - continue; // wasn't accepted for some reason -// MSG_BeginReading(); -// MSG_ReadLong(); -// MSG_ReadLong(); - -#ifdef Q2CLIENT - if (cls.q2server) - CLQ2_ParseServerMessage (); - else -#endif - CL_ParseServerMessage (); - } - else - { - cls.netchan.last_received = realtime; - CLNQ_ParseServerMessage (); - } - } -#endif // // check timeout @@ -2096,7 +2108,7 @@ void CL_Download_f (void) { if (Cmd_IsInsecure()) return; - HTTP_CL_Get(url, Cmd_Argv(2));//"test.txt"); + HTTP_CL_Get(url, Cmd_Argv(2), NULL);//"test.txt"); return; } #endif @@ -2209,7 +2221,7 @@ void CL_ServerInfo_f(void) #ifdef WEBCLIENT void CL_FTP_f(void) { - FTP_Client_Command(Cmd_Args()); + FTP_Client_Command(Cmd_Args(), NULL); } #endif #ifdef IRCCLIENT @@ -2664,14 +2676,8 @@ void Host_Frame (float time) oldrealtime = realtime; -#if defined(NQPROT) || defined(Q2CLIENT) -#if defined(NQPROT) && defined(Q2CLIENT) - if (cls.q2server || cls.demoplayback == DPB_NETQUAKE) -#elif defined(NQPROT) - if (cls.demoplayback == DPB_NETQUAKE) -#elif defined(Q2CLIENT) - if (cls.q2server) -#endif +#if defined(Q2CLIENT) + if (cls.protocol == CP_QUAKE2) cl.time += host_frametime; #endif @@ -2697,11 +2703,6 @@ void Host_Frame (float time) RSpeedRemark(); -#ifdef NQPROT - NET_Poll(); -#endif - - CL_UseIndepPhysics(!!cl_indepphysics.value); CL_AllowIndependantSendCmd(false); @@ -2792,10 +2793,6 @@ void Host_Frame (float time) // process console commands Cbuf_Execute (); -#ifdef NQPROT - NET_Poll(); -#endif - if (cls.downloadtype == dl_none && !*cls.downloadname && cl.downloadlist) { CL_RequestNextDownload(); diff --git a/engine/client/cl_master.h b/engine/client/cl_master.h index 44005547..3a43a695 100644 --- a/engine/client/cl_master.h +++ b/engine/client/cl_master.h @@ -10,6 +10,7 @@ //despite not supporting nq or q2, we still load them. We just filter them. This is to make sure we properly write the listing files. enum { MT_BAD, //this would be an error + MT_MASTERHTTP, //an http/ftp based master server MT_BCASTQW, //-1status MT_BCASTQ2, //-1status MT_BCASTNQ, //see code @@ -95,7 +96,9 @@ typedef struct serverinfo_s { typedef struct master_s{ struct master_s *next; netadr_t adr; + char *address; int type; + int servertype; //filled in for http servers char name[1]; } master_t; diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 59461ba5..e0a4247e 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -488,7 +488,7 @@ void Model_NextDownload (void) cl.worldmodel = NULL; } #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) { R_SetSky(cl.skyname, 0, r_origin); for (i = 0; i < Q2MAX_IMAGES; i++) @@ -519,7 +519,7 @@ void Model_NextDownload (void) continue; #ifdef Q2CLIENT - if (cls.q2server && s[0] == '#') //this is a vweap + if (cls.protocol == CP_QUAKE2 && s[0] == '#') //this is a vweap continue; #endif @@ -588,7 +588,7 @@ void Model_NextDownload (void) Hunk_Check (); // make sure nothing is hurt #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) { cls.downloadnumber = 0; Skin_NextDownload(); @@ -654,7 +654,7 @@ void Sound_NextDownload (void) cl_lightningindex = -1; #endif #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) { cls.downloadnumber = 0; Model_NextDownload(); @@ -1466,6 +1466,15 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution. cls.z_ext = Z_EXT_VIEWHEIGHT; } + else if (protover == 3504) + { + //darkplaces7 (it's a small difference from dp5) + nq_dp_protocol = 7; + sizeofcoord = 4; + sizeofangle = 2; + + cls.z_ext = Z_EXT_VIEWHEIGHT; + } else if (protover != NQ_PROTOCOL_VERSION) { Host_EndGame ("Server returned version %i, not %i\nYou will need to use a different client.", protover, NQ_PROTOCOL_VERSION); @@ -1653,7 +1662,7 @@ void CLNQ_ParseClientdata (int bits) if (bits & SU_VIEWHEIGHT) CL_SetStat(0, STAT_VIEWHEIGHT, MSG_ReadChar ()); - else if (nq_dp_protocol != 6) + else if (nq_dp_protocol < 6) CL_SetStat(0, STAT_VIEWHEIGHT, DEFAULT_VIEWHEIGHT); if (bits & SU_IDEALPITCH) @@ -1678,7 +1687,7 @@ void CLNQ_ParseClientdata (int bits) if (bits & (SU_VELOCITY1<= 5) /*cl.simvel[0][i] =*/ MSG_ReadFloat(); else /*cl.mvelocity[0][i] =*/ MSG_ReadChar()/**16*/; @@ -1693,7 +1702,7 @@ void CLNQ_ParseClientdata (int bits) // cl.onground = (bits & SU_ONGROUND) != 0; // cl.inwater = (bits & SU_INWATER) != 0; - if (nq_dp_protocol == 6) + if (nq_dp_protocol >= 6) { } else if (nq_dp_protocol == 5) @@ -1733,7 +1742,7 @@ void CLNQ_ParseClientdata (int bits) if (bits & DPSU_VIEWZOOM) { - if (nq_dp_protocol == 5 || nq_dp_protocol == 6) + if (nq_dp_protocol >= 6) i = (unsigned short) MSG_ReadShort(); else i = MSG_ReadByte(); @@ -1741,7 +1750,7 @@ void CLNQ_ParseClientdata (int bits) i = 2; CL_SetStat(0, STAT_VIEWZOOM, i); } - else if (nq_dp_protocol != 6) + else if (nq_dp_protocol < 6) CL_SetStat(0, STAT_VIEWZOOM, 255); } #endif @@ -3060,6 +3069,44 @@ int getplayerchatcolour(char *msg) return CL_PlayerChatColour(id); } +void CL_ParsePrecache(void) +{ + int i = (unsigned short)MSG_ReadShort(); + char *s = MSG_ReadString(); + if (i < 32768) + { + if (i >= 1 && i < MAX_MODELS) + { + model_t *model; + CL_CheckOrDownloadFile(s, true); + model = Mod_ForName(s, i == 1); + if (!model) + Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s); + cl.model_precache[i] = model; + strcpy (cl.model_name[i], s); + } + else + Con_Printf("svc_precache: model index %i outside range %i...%i\n", i, 1, MAX_MODELS); + } + else + { + i -= 32768; + if (i >= 1 && i < MAX_SOUNDS) + { + sfx_t *sfx; + CL_CheckOrDownloadFile(va("sounds/%s", s), true); + sfx = S_PrecacheSound (s); + if (!sfx) + Con_Printf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s); + cl.sound_precache[i] = sfx; + strcpy (cl.sound_name[i], s); + } + else + Con_Printf("svc_precache: sound index %i outside range %i...%i\n", i, 1, MAX_SOUNDS); + } +} + + #define SHOWNET(x) if(cl_shownet.value==2)Con_Printf ("%3i:%s\n", msg_readcount-1, x); #define SHOWNET2(x, y) if(cl_shownet.value==2)Con_Printf ("%3i:%3i:%s\n", msg_readcount-1, y, x); /* @@ -3134,6 +3181,7 @@ void CL_ParseServerMessage (void) return; case svc_time: + cl.oldgametime = cl.gametime; cl.gametime = MSG_ReadFloat(); cl.gametimemark = realtime; break; @@ -3517,6 +3565,9 @@ void CL_ParseServerMessage (void) CSQC_ParseEntities(); break; #endif + case svc_precache: + CL_ParsePrecache(); + break; } } } @@ -3687,6 +3738,8 @@ void CLNQ_ParseServerMessage (void) CL_ClearProjectiles (); cl.fixangle = false; + cl.allowsendpacket = true; + // // if recording demos, copy the message out // @@ -3697,9 +3750,6 @@ void CLNQ_ParseServerMessage (void) CL_ParseClientdata (); - - - MSG_BeginReading (); // // parse the message // @@ -3759,7 +3809,7 @@ void CLNQ_ParseServerMessage (void) break; case svc_disconnect: -// CL_Disconnect(); + CL_Disconnect(); break; case svc_centerprint: @@ -3778,42 +3828,8 @@ void CLNQ_ParseServerMessage (void) vid.recalc_refdef = true; // leave full screen intermission break; - case 54://svc_precache: - { - int i = (unsigned short)MSG_ReadShort(); - char *s = MSG_ReadString(); - if (i < 32768) - { - if (i >= 1 && i < MAX_MODELS) - { - model_t *model; - CL_CheckOrDownloadFile(s, true); - model = Mod_ForName(s, i == 1); - if (!model) - Con_Printf("svc_precache: Mod_ForName(\"%s\") failed\n", s); - cl.model_precache[i] = model; - strcpy (cl.model_name[i], s); - } - else - Con_Printf("svc_precache: model index %i outside range %i...%i\n", i, 1, MAX_MODELS); - } - else - { - i -= 32768; - if (i >= 1 && i < MAX_SOUNDS) - { - sfx_t *sfx; - CL_CheckOrDownloadFile(va("sounds/%s", s), true); - sfx = S_PrecacheSound (s); - if (!sfx) - Con_Printf("svc_precache: S_PrecacheSound(\"%s\") failed\n", s); - cl.sound_precache[i] = sfx; - strcpy (cl.sound_name[i], s); - } - else - Con_Printf("svc_precache: sound index %i outside range %i...%i\n", i, 1, MAX_SOUNDS); - } - } + case svcdp_precache: + CL_ParsePrecache(); break; case svc_cdtrack: @@ -3862,14 +3878,17 @@ void CLNQ_ParseServerMessage (void) case svc_time: received_framecount = host_framecount; cl.last_servermessage = realtime; + cl.oldgametime = cl.gametime; cl.gametime = MSG_ReadFloat(); cl.gametimemark = realtime; if (nq_dp_protocol<5) { - cl.validsequence = cls.netchan.incoming_sequence++; // cl.frames[(cls.netchan.incoming_sequence-1)&UPDATE_MASK].packet_entities = cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities; cl.frames[cls.netchan.incoming_sequence&UPDATE_MASK].packet_entities.num_entities=0; } + cls.netchan.outgoing_sequence++; + cls.netchan.incoming_sequence = cls.netchan.outgoing_sequence-1; + cl.validsequence = cls.netchan.incoming_sequence-1; break; case svc_updatename: diff --git a/engine/client/cl_pred.c b/engine/client/cl_pred.c index e0e479b4..a11012d7 100644 --- a/engine/client/cl_pred.c +++ b/engine/client/cl_pred.c @@ -539,7 +539,7 @@ void CL_PredictMovePNum (int pnum) float *vel; float *org; #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) { cl.crouch[pnum] = 0; CLQ2_PredictMovement(); @@ -552,9 +552,14 @@ void CL_PredictMovePNum (int pnum) if (cl.paused && !cls.demoplayback!=DPB_MVD && (!cl.spectator || !autocam[pnum])) return; -#ifdef NQPROT - if (cls.demoplayback!=DPB_NETQUAKE) //don't increase time in nq demos. -#endif + + if (cl.oldgametime) + { + cl.time = cl.gametime; + if (cl.time > realtime) + cl.time = realtime; + } + else { cl.time = realtime - cls.latency - cl_pushlatency.value*0.001; if (cl.time > realtime) @@ -614,6 +619,8 @@ void CL_PredictMovePNum (int pnum) if (f<0)f=0; if (f>1)f=1; + vel = vec3_origin; + for (i=0 ; i<3 ; i++) lrp[i] = state->origin[i] + f * (old->origin[i] - state->origin[i]); @@ -621,10 +628,15 @@ void CL_PredictMovePNum (int pnum) org = lrp; } else + { org = state->origin; + Con_Printf("No old\n"); + } goto fixedorg; } + else + Con_Printf("No state\n"); } #endif if (((cl_nopred.value && cls.demoplayback!=DPB_MVD)|| cl.fixangle)) diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index 1b915fd3..fe523898 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -702,7 +702,7 @@ void SCR_CalcRefdef (void) size = scr_viewsize.value; #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) //q2 never has a hud. sb_lines = 0; else #endif diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 9d9decdf..ae6a4731 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -143,6 +143,7 @@ typedef struct float light; float lightcolor[3]; float start; + float framerate; model_t *model; int skinnum; } explosion_t; @@ -259,6 +260,7 @@ explosion_t *CL_AllocExplosion (void) if (!cl_explosions[i].model) { cl_explosions[i].firstframe = -1; + cl_explosions[i].framerate = 10; return &cl_explosions[i]; } // find the oldest explosion @@ -272,6 +274,7 @@ explosion_t *CL_AllocExplosion (void) index = i; } cl_explosions[index].firstframe = -1; + cl_explosions[index].framerate = 10; return &cl_explosions[index]; } @@ -367,7 +370,7 @@ void CL_ParseBeam (int tent) #endif } - if (tent <= 2 && cls.state == ca_active && etype >= 0) + if (cls.state == ca_active && etype >= 0) { vec3_t impact, normal; vec3_t extra; @@ -1271,6 +1274,7 @@ void CL_ParseEffect (qboolean effect2) ex->model = cl.model_precache[modelindex]; ex->firstframe = startframe; ex->numframes = framecount; + ex->framerate = framerate; ex->angles[0] = 0; ex->angles[1] = 0; @@ -2115,7 +2119,7 @@ void CL_UpdateExplosions (void) { if (!ex->model) continue; - f = 10*(cl.time - ex->start); + f = ex->framerate*(cl.time - ex->start); if (ex->firstframe >= 0) { firstframe = ex->firstframe; diff --git a/engine/client/client.h b/engine/client/client.h index 0c2b1360..a8619522 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -284,9 +284,13 @@ typedef struct { // connection information cactive_t state; -#ifdef Q2CLIENT - qboolean q2server; -#endif + + enum { + CP_UNKNOWN, + CP_QUAKEWORLD, + CP_NETQUAKE, + CP_QUAKE2 + } protocol; qboolean resendinfo; @@ -362,7 +366,6 @@ typedef struct #endif unsigned long z_ext; #ifdef NQPROT - struct qsocket_s *netcon; int signon; #endif translation_t language; @@ -402,6 +405,7 @@ typedef struct float gamespeed; qboolean csqcdebug; + qboolean allowsendpacket; char serverinfo[MAX_SERVERINFO_STRING]; @@ -448,6 +452,8 @@ typedef struct // is rendering at. allways <= realtime float gametime; float gametimemark; + float oldgametime; //used as the old time to lerp cl.time from. + //if it's 0, cl.time will casually increase. vec3_t simorg[MAX_SPLITS]; vec3_t simvel[MAX_SPLITS]; @@ -664,7 +670,7 @@ void CL_ClampPitch (int pnum); int CL_ReadFromServer (void); void CL_WriteToServer (usercmd_t *cmd); -void CL_BaseMove (usercmd_t *cmd, int pnum); +void CL_BaseMove (usercmd_t *cmd, int pnum, float extra, float wantfps); float CL_KeyState (kbutton_t *key, int pnum); diff --git a/engine/client/keys.c b/engine/client/keys.c index 039654b0..3c457133 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -357,8 +357,8 @@ void Con_ExecuteLine(console_t *con, char *line) else if (Cmd_IsCommand(line)) Cbuf_AddText (line, RESTRICT_LOCAL); // valid command #ifdef Q2CLIENT - else if (cls.q2server) - Cbuf_AddText (line, RESTRICT_LOCAL); // send the command to the server, and let the server convert to chat + else if (cls.protocol == CP_QUAKE2) + Cbuf_AddText (line, RESTRICT_LOCAL); // send the command to the server via console, and let the server convert to chat #endif else { // convert to a chat message diff --git a/engine/client/m_download.c b/engine/client/m_download.c index 6e144862..fae0fc7c 100644 --- a/engine/client/m_download.c +++ b/engine/client/m_download.c @@ -213,7 +213,7 @@ void M_Download_Draw (int x, int y, struct menucustom_s *c, struct menu_s *m) if (downloadablelist[info->parsedsourcenum]) { sprintf(basename, "../dlinfo_%i.inf", info->parsedsourcenum); - if (!HTTP_CL_Get(downloadablelist[info->parsedsourcenum], basename)) + if (!HTTP_CL_Get(downloadablelist[info->parsedsourcenum], basename, NULL)) Con_Printf("Could not contact server\n"); } } @@ -317,7 +317,7 @@ qboolean M_Download_Key (struct menucustom_s *c, struct menu_s *m, int key) { if ((p->flags&DPF_WANTTOINSTALL) && !(p->flags&DPF_HAVEAVERSION)) { //if we want it and don't have it: - if (HTTP_CL_Get(p->src, va("../%s", p->dest))) + if (HTTP_CL_Get(p->src, va("../%s", p->dest), NULL)) p->flags|=DPF_HAVEAVERSION; //FIXME: This is error prone. } } diff --git a/engine/client/m_master.c b/engine/client/m_master.c index 91e5ff70..43d099e4 100644 --- a/engine/client/m_master.c +++ b/engine/client/m_master.c @@ -474,7 +474,7 @@ void M_DrawSources (void) } } -#define NUMSLISTOPTIONS (7+7+3) +#define NUMSLISTOPTIONS (7+7+4) struct { char *title; cvar_t *cvar; @@ -498,7 +498,8 @@ void M_DrawSources (void) {"Max ping", &sb_maxping, 1}, {"GameDir", &sb_gamedir, 2}, - {"Using map", &sb_mapname, 2} + {"Using map", &sb_mapname, 2}, + {"Game name", &com_gamename, 2} }; void M_DrawSListOptions (void) @@ -539,12 +540,14 @@ void M_SListOptions_Key (int key) slist_option--; if (slist_option<0) slist_option=0; + return; } else if (key == K_DOWNARROW) { slist_option++; if (slist_option >= slist_numoptions) slist_option = slist_numoptions-1; + return; } switch(options[slist_option].type) @@ -567,7 +570,7 @@ void M_SListOptions_Key (int key) Cvar_SetValue(options[slist_option].cvar, (int)options[slist_option].cvar->value/10); break; case 2: - if ((key >= '0' && key <= '9') || (key >= 'a' && key <= 'z') || key == '_') + if ((key >= '0' && key <= '9') || (key >= 'a' && key <= 'z') || (key >= 'A' && key <= 'Z')|| key == '_') Cvar_Set(options[slist_option].cvar, va("%s%c", options[slist_option].cvar->string, key)); else if (key == K_DEL) Cvar_Set(options[slist_option].cvar, ""); diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index 382cf7f3..29e2faf5 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -247,6 +247,22 @@ void Media_Clear (void) } } +qboolean fakecdactive; +void Media_FakeTrack(int i, qboolean loop) +{ + char trackname[512]; + + sprintf(trackname, "sound/cdtracks/track%03i.ogg", i); + if (COM_FCheckExists(trackname)) + { + Media_Clear(); + strcpy(currenttrack.filename, trackname+6); + + fakecdactive = true; + media_playing = true; + } +} + //actually, this func just flushes and states that it should be playing. the ambientsound func actually changes the track. void Media_Next_f (void) { @@ -727,7 +743,7 @@ char *Media_NextTrack(void) if (!loadedtracknames) Media_LoadTrackNames("sound/media.m3u"); - if (!tracks) + if (!tracks && !fakecdactive) { *currenttrack.filename='\0'; *currenttrack.nicename='\0'; diff --git a/engine/client/menu.c b/engine/client/menu.c index 01718aa2..00824d4c 100644 --- a/engine/client/menu.c +++ b/engine/client/menu.c @@ -339,7 +339,7 @@ void M_Menu_Keys_f (void) m_entersound = true; #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) bindnames = q2bindnames; else #endif diff --git a/engine/client/net_master.c b/engine/client/net_master.c index 6b836e29..bcdf7d4b 100644 --- a/engine/client/net_master.c +++ b/engine/client/net_master.c @@ -488,14 +488,7 @@ void Master_AddMaster (char *address, int type, char *description) Con_Printf("Failed to resolve address \"%s\"\n", address); return; } -/* - if (type == MT_SINGLEQW || type == MT_SINGLENQ || type == MT_SINGLEQ2) //single servers are added to the serverlist as well as the masters list - { - net_from = adr; - CL_ReadServerInfo(va("\\hostname\\%s", description), MT_SINGLEQ2, true); -// return; - } -*/ + if (type < MT_SINGLEQW) //broadcasts { if (adr.type == NA_IP) @@ -509,10 +502,32 @@ void Master_AddMaster (char *address, int type, char *description) if (NET_CompareAdr(mast->adr, adr) && mast->type == type) //already exists. return; } - mast = Z_Malloc(sizeof(master_t)+strlen(description)); + mast = Z_Malloc(sizeof(master_t)+strlen(description)+1+strlen(address)+1); mast->adr = adr; + mast->address = mast->name + strlen(description)+1; mast->type = type; strcpy(mast->name, description); + strcpy(mast->address, address); + + mast->next = master; + master = mast; +} + +void Master_AddMasterHTTP (char *address, int servertype, char *description) +{ + master_t *mast; + + for (mast = master; mast; mast = mast->next) + { + if (!strcmp(mast->address, address) && mast->type == MT_MASTERHTTP) //already exists. + return; + } + mast = Z_Malloc(sizeof(master_t)+strlen(description)+1+strlen(address)+1); + mast->address = mast->name + strlen(description)+1; + mast->type = MT_MASTERHTTP; + mast->servertype = servertype; + strcpy(mast->name, description); + strcpy(mast->address, address); mast->next = master; master = mast; @@ -892,11 +907,63 @@ void SListOptionChanged(serverinfo_t *newserver) } } +#ifdef WEBCLIENT +void MasterInfo_ProcessHTTP(char *name, qboolean success) +{ + netadr_t adr; + char *s; + char *el; + serverinfo_t *info; + if (!success) + return; + + el = COM_LoadTempFile(name); + while(*el) + { + s = el; + while(*s <= ' ' && *s != '\n' && *s) + s++; + el = strchr(s, '\n'); + if (!el) + el = s + strlen(s); + else if (el>s && el[-1] == '\r') + el[-1] = '\0'; + + if (*s == '#') //hash is a comment, apparently. + continue; + *el = '\0'; + el++; + + if (!NET_StringToAdr(s, &adr)) + continue; + + if ((info = Master_InfoForServer(adr))) //remove if the server already exists. + { + info->sends = 1; //reset. + } + else + { + info = Z_Malloc(sizeof(serverinfo_t)); + info->adr = adr; + info->sends = 1; + info->special = SS_NETQUAKE; + info->refreshtime = 0; + + sprintf(info->name, "%s", NET_AdrToString(info->adr)); + + info->next = firstserver; + firstserver = info; + } + } + + Sys_remove(va("%s/%s", com_gamedir, name)); +} +#endif //don't try sending to servers we don't support void MasterInfo_Request(master_t *mast, qboolean evenifwedonthavethefiles) { - char *str; + static int mastersequence; if (!mast) return; switch(mast->type) @@ -924,13 +991,19 @@ void MasterInfo_Request(master_t *mast, qboolean evenifwedonthavethefiles) SZ_Clear(&net_message); break; case MT_MASTERDP: - str = va("%c%c%c%cgetservers %s %u empty full\x0A\n", 255, 255, 255, 255, "Nexuiz", 3); - NET_SendPollPacket (strlen(str), str, mast->adr); + { + char *str; + str = va("%c%c%c%cgetservers %s %u empty full\x0A\n", 255, 255, 255, 255, com_gamename.string, 3); + NET_SendPollPacket (strlen(str), str, mast->adr); + } break; case MT_SINGLEDP: case MT_BCASTDP: - str = va("%c%c%c%cgetinfo", 255, 255, 255, 255); - NET_SendPollPacket (strlen(str), str, mast->adr); + { + char *str; + str = va("%c%c%c%cgetinfo", 255, 255, 255, 255); + NET_SendPollPacket (strlen(str), str, mast->adr); + } break; #endif case MT_MASTERQW: @@ -942,6 +1015,11 @@ void MasterInfo_Request(master_t *mast, qboolean evenifwedonthavethefiles) NET_SendPollPacket (6, "query", mast->adr); break; #endif + case MT_MASTERHTTP: +#ifdef WEBCLIENT + HTTP_CL_Get(mast->address, va("master_%i_%i.tmp", mastersequence++, mast->servertype), MasterInfo_ProcessHTTP); +#endif + break; } } @@ -1033,20 +1111,8 @@ void MasterInfo_Begin(void) if (!Master_LoadMasterList("masters.txt", MT_MASTERQW, 5)) { Master_LoadMasterList("servers.txt", MT_SINGLEQW, 1); -// if (q1servers) - { - Master_AddMaster("255.255.255.255:26000", MT_BCASTNQ, "Nearby Quake1 servers"); - Master_AddMaster("255.255.255.255:27500", MT_BCASTQW, "Nearby QuakeWorld UDP servers."); - } -// if (q2servers) - { - Master_AddMaster("255.255.255.255:27910", MT_BCASTQ2, "Nearby Quake2 UDP servers."); - Master_AddMaster("00000000:ffffffffffff:27910", MT_BCASTQ2, "Nearby Quake2 IPX servers."); - } - - -// if (q1servers) +// if (q1servers) //qw master servers { Master_AddMaster("192.246.40.37:27000", MT_MASTERQW, "id Limbo"); Master_AddMaster("192.246.40.37:27002", MT_MASTERQW, "id CTF"); @@ -1055,20 +1121,28 @@ void MasterInfo_Begin(void) Master_AddMaster("192.246.40.37:27006", MT_MASTERQW, "id Deathmatch Only"); Master_AddMaster("150.254.66.120:27000", MT_MASTERQW, "Poland's master server."); Master_AddMaster("62.112.145.129:27000", MT_MASTERQW, "Ocrana master server."); + + Master_AddMaster("255.255.255.255:27500", MT_BCASTQW, "Nearby QuakeWorld UDP servers."); } -// if (q2servers) +// if (q1servers) //nq master servers { + Master_AddMasterHTTP("http://www.gameaholic.com/servers/qspy-quake",SS_NETQUAKE, "gameaholic's NQ master"); + Master_AddMaster("255.255.255.255:26000", MT_BCASTNQ, "Nearby Quake1 servers"); + + Master_AddMaster("ghdigital.com:27950", MT_MASTERDP, "DarkPlaces Master 1"); + Master_AddMaster("dpmaster.deathmask.net:27950", MT_MASTERDP, "DarkPlaces Master 2"); + Master_AddMaster("12.166.196.192:27950", MT_MASTERDP, "DarkPlaces Master 3"); + + Master_AddMaster("255.255.255.255:26000", MT_BCASTDP, "Nearby DarkPlaces servers"); + } + +// if (q2servers) //q2 + { + Master_AddMaster("255.255.255.255:27910", MT_BCASTQ2, "Nearby Quake2 UDP servers."); + Master_AddMaster("00000000:ffffffffffff:27910", MT_BCASTQ2, "Nearby Quake2 IPX servers."); Master_AddMaster("192.246.40.37:27900", MT_MASTERQ2, "id q2 Master."); } - - Master_AddMaster("ghdigital.com:27950", MT_MASTERDP, "DarkPlaces Master: Nexuiz"); - Master_AddMaster("dpmaster.deathmask.net:27950", MT_MASTERDP, "DarkPlaces Master: Nexuiz"); - Master_AddMaster("12.166.196.192:27950", MT_MASTERDP, "DarkPlaces Master: Nexuiz"); - - Master_AddMaster("255.255.255.255:26000", MT_BCASTDP, "Nearby DarkPlaces servers"); - - } for (mast = master; mast; mast=mast->next) @@ -1084,6 +1158,22 @@ void Master_QueryServer(serverinfo_t *server) server->refreshtime = Sys_DoubleTime(); if (server->special & SS_DARKPLACES) sprintf(data, "%c%c%c%cgetinfo", 255, 255, 255, 255); + else if (server->special & SS_NETQUAKE) + { +#ifdef NQPROT + SZ_Clear(&net_message); + net_message.packing = SZ_RAWBYTES; + net_message.currentbit = 0; + MSG_WriteLong(&net_message, 0);// save space for the header, filled in later + MSG_WriteByte(&net_message, CCREQ_SERVER_INFO); + MSG_WriteString(&net_message, NET_GAMENAME_NQ); //look for either sort of server + MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + NET_SendPollPacket(net_message.cursize, net_message.data, server->adr); + SZ_Clear(&net_message); +#endif + return; + } else sprintf(data, "%c%c%c%cstatus", 255, 255, 255, 255); NET_SendPollPacket (strlen(data), data, server->adr); @@ -1255,6 +1345,8 @@ int CL_ReadServerInfo(char *msg, int servertype, qboolean favorite) info->players = 0; info->maxplayers = atoi(Info_ValueForKey(msg, "maxclients")); + if (!info->maxplayers) + info->maxplayers = atoi(Info_ValueForKey(msg, "sv_maxclients")); info->tl = atoi(Info_ValueForKey(msg, "timelimit")); info->fl = atoi(Info_ValueForKey(msg, "fraglimit")); @@ -1414,7 +1506,7 @@ void CL_MasterListParse(int type, qboolean slashpad) p1 = MSG_ReadByte(); p2 = MSG_ReadByte(); - info->adr.port = htons((p1<<8)|p2); + info->adr.port = htons((unsigned short)((p1<<8)|p2)); if (!info->adr.port) { Z_Free(info); diff --git a/engine/client/quakedef.h b/engine/client/quakedef.h index 4149f553..9b91a167 100644 --- a/engine/client/quakedef.h +++ b/engine/client/quakedef.h @@ -209,6 +209,7 @@ extern qboolean noclip_anglehack; // extern quakeparms_t host_parms; +extern cvar_t com_gamename; extern cvar_t sys_ticrate; extern cvar_t sys_nostdout; extern cvar_t developer; diff --git a/engine/client/r_part.c b/engine/client/r_part.c index fe74c70a..894b6b81 100644 --- a/engine/client/r_part.c +++ b/engine/client/r_part.c @@ -3303,7 +3303,7 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void { if (type->clippeddecals) { - /* for ( ;; ) + for ( ;; ) { dkill = type->clippeddecals; if (dkill && dkill->die < particletime) @@ -3319,10 +3319,10 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void continue; } break; - }*/ + } for (d=type->clippeddecals ; d ; d=d->next) { - /* for ( ;; ) + for ( ;; ) { dkill = d->next; if (dkill && dkill->die < particletime) @@ -3336,7 +3336,7 @@ void DrawParticleTypes (void texturedparticles(particle_t *,part_type_t*), void } break; } -*/ + switch (type->rampmode) diff --git a/engine/client/sbar.c b/engine/client/sbar.c index ec05ff2d..0d67afbe 100644 --- a/engine/client/sbar.c +++ b/engine/client/sbar.c @@ -1592,7 +1592,7 @@ void Sbar_Draw (void) #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) { SCR_VRectForPlayer(&sbar_rect, 0); @@ -1890,11 +1890,7 @@ void Sbar_DeathmatchOverlay (int start) skip = 8; // request new ping times every two second - if (realtime - cl.last_ping_request > 2 -#ifdef Q2CLIENT - && !cls.q2server -#endif - ) + if (realtime - cl.last_ping_request > 2 && cls.protocol == CP_QUAKEWORLD) { cl.last_ping_request = realtime; CL_SendClientCommand(false, "pings"); @@ -2049,11 +2045,7 @@ void Sbar_ChatModeOverlay(void) skip = 8; // request new ping times every two second - if (realtime - cl.last_ping_request > 2 -#ifdef Q2CLIENT - && !cls.q2server -#endif - ) + if (realtime - cl.last_ping_request > 2 && cls.protocol == CP_QUAKEWORLD) { cl.last_ping_request = realtime; CL_SendClientCommand(false, "pings"); diff --git a/engine/client/skin.c b/engine/client/skin.c index c5d5cdb8..f6186ca8 100644 --- a/engine/client/skin.c +++ b/engine/client/skin.c @@ -150,7 +150,7 @@ void Skin_Find (player_info_t *sc) { *s = '\0'; #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) model = Mod_ForName(va("players/%s/tris.mdl", name), false); else #endif @@ -265,7 +265,7 @@ qbyte *Skin_Cache8 (skin_t *skin) } #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) sprintf (name, "players/%s.pcx", skin->name); else #endif diff --git a/engine/client/snd_dma.c b/engine/client/snd_dma.c index 8f314a0e..6c4493a1 100644 --- a/engine/client/snd_dma.c +++ b/engine/client/snd_dma.c @@ -85,6 +85,7 @@ cvar_t _snd_mixahead = {"_snd_mixahead", "0.2", NULL, CVAR_ARCHIVE}; cvar_t snd_leftisright = {"snd_leftisright", "0", NULL, CVAR_ARCHIVE}; cvar_t snd_eax = {"snd_eax", "0"}; cvar_t snd_speakers = {"snd_numspeakers", "2"}; +cvar_t snd_playersoundvolume = {"snd_localvolume", "1"}; //sugested by crunch cvar_t snd_capture = {"snd_capture", "0"}; @@ -494,6 +495,8 @@ void S_Init (void) Cvar_Register(&snd_inactive, "Sound controls"); + Cvar_Register(&snd_playersoundvolume, "Sound controls"); + if (host_parms.memsize < 0x800000) { Cvar_Set (&loadas8bit, "1"); @@ -716,7 +719,7 @@ void SND_Spatialize(soundcardinfo_t *sc, channel_t *ch) { for (i = 0; i < sc->sn.numchannels; i++) { - ch->vol[i] = ch->master_vol; + ch->vol[i] = ch->master_vol * snd_playersoundvolume.value; ch->delay[i] = 0; } return; diff --git a/engine/client/snd_mix.c b/engine/client/snd_mix.c index 1455de23..41c66d23 100644 --- a/engine/client/snd_mix.c +++ b/engine/client/snd_mix.c @@ -607,9 +607,12 @@ void S_PaintChannels(soundcardinfo_t *sc, int endtime) soundcardinfo_t *sndc; #define qmax(x, y) (x>y)?(x):(y) len_diff = scache->length; +// start = ch->end - scache->length; +// samples = end - start; + ch->sfx->decoder->decodemore(ch->sfx, - ch->pos + endtime-ltime+1000); - //ch->pos + qmax(end-ltime+1000, 1000)); //try to exceed by a little. + end - (ch->end - scache->length) + 1); +// ch->pos + end-ltime+1); scache = S_LoadSound (ch->sfx); if (!scache) diff --git a/engine/client/snd_ov.c b/engine/client/snd_ov.c index 5914646e..eb34af6e 100644 --- a/engine/client/snd_ov.c +++ b/engine/client/snd_ov.c @@ -152,8 +152,11 @@ int OV_DecodeSome(sfx_t *s, int minlength) ovdecoderbuffer_t *dec = s->decoder->buf; int bytesread; + Con_Printf("Minlength = %03i ", minlength); + if (dec->mediaaswavbuflen < dec->mediaaswavpos+minlength+11050) //expand if needed. { + Con_Printf("Expand buffer\n"); dec->mediaaswavbuflen += minlength+22100; dec->mediaaswavdata = BZ_Realloc(dec->mediaaswavdata, dec->mediaaswavbuflen); s->cache.data = dec->mediaaswavdata; @@ -168,6 +171,7 @@ int OV_DecodeSome(sfx_t *s, int minlength) if (minlength < sc->length) { + Con_Printf("No need for decode\n"); //done enough for now, don't whizz through the lot return 0; } @@ -176,7 +180,10 @@ int OV_DecodeSome(sfx_t *s, int minlength) { bytesread = p_ov_read(&dec->vf, dec->mediaaswavdata+dec->mediaaswavpos, dec->mediaaswavbuflen-dec->mediaaswavpos, bigendianp, 2, 1, ¤t_section); if (bytesread <= 0) + { + Con_Printf("ogg decoding failed\n"); return 0; + } if (snd_speed != dec->srcspeed) { //resample @@ -198,7 +205,10 @@ int OV_DecodeSome(sfx_t *s, int minlength) dec->mediasc.length = sc->length; if (minlength<=sc->length) + { + Con_Printf("Reached length\n"); return 1; + } } } void OV_CancelDecoder(sfx_t *s) diff --git a/engine/client/snd_win.c b/engine/client/snd_win.c index 5f3e96d0..ea64944b 100644 --- a/engine/client/snd_win.c +++ b/engine/client/snd_win.c @@ -529,7 +529,7 @@ sndinitstat SNDDMA_InitDirect (soundcardinfo_t *sc) if (snd_eax.value) { CoInitialize(NULL); - if (FAILED(CoCreateInstance( &CLSID_EAXDirectSound, dsndguid, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void **)&sc->pDS ))) + if (FAILED(CoCreateInstance( &CLSID_EAXDirectSound, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectSound, (void **)&sc->pDS ))) sc->pDS=NULL; else IDirectSound_Initialize(sc->pDS, dsndguid); diff --git a/engine/client/textedit.c b/engine/client/textedit.c index 40b2ea02..5b41e8e6 100644 --- a/engine/client/textedit.c +++ b/engine/client/textedit.c @@ -156,8 +156,6 @@ void CloseEditor(void) key_dest = key_console; editoractive = false; - editprogfuncs = NULL; - if (!firstblock) return; OpenEditorFile[0] = '\0'; @@ -170,6 +168,7 @@ void CloseEditor(void) } madechanges = false; + editormodal = false; firstblock = NULL; @@ -389,6 +388,11 @@ void Editor_Key(int key) switch(key) { case K_ESCAPE: + if (editprogfuncs) + *editprogfuncs->pr_trace = 0; + useeval = false; + break; + case K_F3: useeval = false; break; case K_DEL: @@ -502,9 +506,9 @@ void Editor_Key(int key) { int f = 0; #ifndef CLIENTONLY - if (svprogfuncs) + if (editprogfuncs) { - if (svprogfuncs->ToggleBreak(svprogfuncs, OpenEditorFile+strlen(com_gamedir)+1, cursorlinenum, 2)) + if (editprogfuncs->ToggleBreak(editprogfuncs, OpenEditorFile+4, cursorlinenum, 2)) f |= 1; else f |= 2; @@ -924,9 +928,6 @@ void Editor_Draw(void) int QCLibEditor(char *filename, int line, int nump, char **parms) { - editprogfuncs = svprogfuncs; - - if (editormodal || !developer.value) return line; //whoops @@ -979,6 +980,8 @@ int QCLibEditor(char *filename, int line, int nump, char **parms) } } + editprogfuncs = svprogfuncs; + for (cursorlinenum = 1, cursorblock = firstblock; cursorlinenum < line && cursorblock->next; cursorlinenum++) cursorblock=cursorblock->next; @@ -988,7 +991,7 @@ int QCLibEditor(char *filename, int line, int nump, char **parms) { editormodal = true; - while(editormodal && editoractive) + while(editormodal && editoractive && editprogfuncs) { key_dest = key_editor; scr_disabled_for_loading=false; diff --git a/engine/client/view.c b/engine/client/view.c index ebaba013..8ba54ae9 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -55,6 +55,7 @@ cvar_t lcd_x = {"lcd_x", "0"}; // FIXME: make this work sometime... cvar_t cl_rollspeed = {"cl_rollspeed", "200"}; cvar_t cl_rollangle = {"cl_rollangle", "2.0"}; +cvar_t v_deathtilt = {"cl_deathtilt", "1"}; cvar_t cl_bob = {"cl_bob","0.02"}; cvar_t cl_bobcycle = {"cl_bobcycle","0.6"}; @@ -95,6 +96,7 @@ cvar_t v_pentcshift = {"v_pentcshift", "0"}; cvar_t v_viewheight = {"v_viewheight", "0"}; + extern cvar_t cl_chasecam; float v_dmg_time[MAX_SPLITS], v_dmg_roll[MAX_SPLITS], v_dmg_pitch[MAX_SPLITS]; @@ -1088,7 +1090,7 @@ void V_CalcRefdef (int pnum) r_refdef.currentplayernum = pnum; #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) return; #endif @@ -1122,21 +1124,16 @@ void V_CalcRefdef (int pnum) V_CalcViewRoll (pnum); V_AddIdle (pnum); -#ifdef Q2CLIENT - if (!cls.q2server) -#endif - { - if (view_message && view_message->flags & PF_GIB) - r_refdef.vieworg[2] += 8; // gib view height - else if (view_message && view_message->flags & PF_DEAD) - r_refdef.vieworg[2] -= 16; // corpse view height - else - r_refdef.vieworg[2] += cl.viewheight[pnum]; + if (view_message && view_message->flags & PF_GIB) + r_refdef.vieworg[2] += 8; // gib view height + else if (view_message && view_message->flags & PF_DEAD) + r_refdef.vieworg[2] -= 16; // corpse view height + else + r_refdef.vieworg[2] += cl.viewheight[pnum]; - r_refdef.vieworg[2] += cl.crouch[pnum]; - } + r_refdef.vieworg[2] += cl.crouch[pnum]; - if (view_message && view_message->flags & PF_DEAD) // PF_GIB will also set PF_DEAD + if (view_message && view_message->flags & PF_DEAD && v_deathtilt.value) // PF_GIB will also set PF_DEAD { if (!cl.spectator || !cl_chasecam.value) r_refdef.viewangles[ROLL] = 80; // dead view angle @@ -1171,11 +1168,6 @@ void V_CalcRefdef (int pnum) else if (scr_viewsize.value == 80) view->origin[2] += 0.5; -#ifdef Q2CLIENT - if (cls.q2server) - view->model = NULL; - else -#endif if (!view_message || view_message->flags & (PF_GIB|PF_DEAD) ) view->model = NULL; else @@ -1288,7 +1280,7 @@ void V_RenderPlayerViews(int plnum) SCR_VRectForPlayer(&r_refdef.vrect, plnum); view_message = &view_frame->playerstate[cl.playernum[plnum]]; #ifdef NQPROT - if (cls.netcon) + if (cls.protocol == CP_NETQUAKE) view_message->weaponframe = cl.stats[0][STAT_WEAPONFRAME]; #endif cl.simangles[plnum][ROLL] = 0; // FIXME @@@ diff --git a/engine/common/bspfile.h b/engine/common/bspfile.h index 3012df18..6bc763d9 100644 --- a/engine/common/bspfile.h +++ b/engine/common/bspfile.h @@ -30,10 +30,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define MAX_MAP_ENTITIES 1024 #define MAX_MAP_ENTSTRING 65536 -#define MAX_MAP_PLANES 8192 -#define MAX_MAP_NODES 32767 // because negative shorts are contents -#define MAX_MAP_CLIPNODES 32767 // -#define MAX_MAP_LEAFS 32767 // +#define MAX_MAP_PLANES 65636*2 +#define MAX_MAP_NODES 65535 // q2/q3 uses more than q1. :( +#define MAX_MAP_CLIPNODES 65535 // +#define MAX_MAP_LEAFS 65535 // #define MAX_MAP_VERTS 65535 #define MAX_MAP_FACES 65535 #define MAX_MAP_MARKSURFACES 65535 @@ -348,12 +348,10 @@ typedef struct q2miptex_s #define MAX_Q2MAP_AREAS 256 #define MAX_Q2MAP_AREAPORTALS 1024 -#define MAX_Q2MAP_PLANES 0x00040000 -#define MAX_Q2MAP_NODES 65536 +#define MAX_Q2MAP_PLANES MAX_MAP_PLANES #define MAX_Q2MAP_BRUSHSIDES 0x40000 -#define MAX_Q2MAP_LEAFS 65536 -#define MAX_Q2MAP_VERTS 65536 -#define MAX_Q2MAP_FACES 65536 +#define MAX_Q2MAP_VERTS MAX_MAP_VERTS +#define MAX_Q2MAP_FACES MAX_MAP_FACES #define MAX_Q2MAP_LEAFFACES 65536 #define MAX_Q2MAP_LEAFBRUSHES 65536 #define MAX_Q2MAP_PORTALS 65536 diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 1b87819e..0d0241fd 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -1714,8 +1714,8 @@ void Cmd_ExecuteString (char *text, int level) return; #endif #ifdef Q2CLIENT - if (cls.q2server) - { + if (cls.protocol == CP_QUAKE2) + { //q2 servers convert unknown commands to text. Cmd_ForwardToServer(); return; } diff --git a/engine/common/common.c b/engine/common/common.c index 37d870b2..e24d1cd2 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -67,6 +67,7 @@ static char *safeargvs[NUM_SAFE_ARGVS] = {"-stdvid", "-nolan", "-nosound", "-nocdaudio", "-nojoy", "-nomouse"}; cvar_t registered = {"registered","0"}; +cvar_t com_gamename = {"com_gamename", ""}; qboolean com_modified; // set true if using non-id files @@ -748,7 +749,7 @@ void MSG_WriteDeltaUsercmd (sizebuf_t *buf, usercmd_t *from, usercmd_t *cmd) // bits = 0; #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) { if (cmd->angles[0] != from->angles[0]) bits |= Q2CM_ANGLE1; @@ -4065,7 +4066,7 @@ char *COM_GetPathInfo (int i, int *crc) #ifdef WEBSERVER if (httpserver.value) - protocol = va("http://%s/", NET_AdrToString (net_local_ipadr)); + protocol = va("http://%s/", NET_AdrToString (net_local_sv_ipadr)); else #endif protocol = "qw://"; @@ -4205,6 +4206,39 @@ potentialgamepath_t pgp[] = { {"%s/baseq3/pak0.pk3", "%s/baseq3"}, //quake3 {"%s/base/assets0.pk3", "%s/base"} //jk2 }; + + +typedef struct { + char *gamename; //sent to the master server when this is the current gamemode. + char *exename; //used if the exe name contains this + char *argname; //used if this was used as a parameter. + char *auniquefile; //used if this file is relative from the gamedir + + char *dir1; + char *dir2; + char *dir3; + char *dir4; +} gamemode_info_t; +gamemode_info_t gamemode_info[] = { +//note that there is no basic 'fte' gamemode, this is because we aim for network compatability. Darkplaces-Quake is the closest we get. +//this is to avoid having too many gamemodes anyway. + {"Darkplaces-Hipnotic", "hipnotic", "-hipnotic", "hipnotic/pak0.pak","id1", "qw", "hipnotic", "fte"}, + {"Darkplaces-Rogue", "rogue", "-rogue", "rogue/pak0.pak", "id1", "qw", "rogue", "fte"}, + {"Nexuiz", "nexuiz", "-nexuiz", "data/data.pk3", "id1", "qw", "data", "fte"}, + + {"Darkplaces-Quake", "darkplaces", "-quake", "id1/pak0.pak", "id1", "qw", "fte"}, + + //supported commercial mods (some are currently only partially supported) + {"FTE-Hexen2", "hexen", "-hexen2", "data1/pak0.pak", "data1", "fte"}, + {"FTE-Quake2", "q2", "-q2", "baseq2/pak0.pak", "baseq2", "fte"}, + {"FTE-Quake3", "q3", "-q3", "baseq3/pak0.pk3", "baseq3", "fte"}, + + {"FTE-JK2", "jk2", "-jk2", "base/assets0.pk3", "base", "fte"}, + + {NULL} +}; + + /* ================ COM_InitFilesystem @@ -4218,6 +4252,9 @@ void COM_InitFilesystem (void) char *ev; + int gamenum=-1; + char *check; + // // -basedir // Overrides the system supplied base directory (under id1) @@ -4228,6 +4265,44 @@ void COM_InitFilesystem (void) else strcpy (com_quakedir, host_parms.basedir); + + + Cvar_Register(&com_gamename, "evil hacks"); + //identify the game from a telling file + for (i = 0; gamemode_info[i].gamename; i++) + { + f = fopen(va("%s/%s", com_quakedir, gamemode_info[i].auniquefile), "rb"); + if (f) + { + fclose(f); + gamenum = i; + break; + } + } + //use the game based on an exe name over the filesystem one. + for (i = 0; gamemode_info[i].gamename; i++) + { + if (strstr(com_argv[0], gamemode_info[i].exename)) + gamenum = i; + } + //use the game based on an parameter over all else. + for (i = 0; gamemode_info[i].gamename; i++) + { + if (COM_CheckParm(gamemode_info[i].argname)) + gamenum = i; + } + + if (gamenum<0) + { + for (i = 0; gamemode_info[i].gamename; i++) + { + if (!strcmp(gamemode_info[i].argname, "-quake")) + gamenum = i; + } + } + Cvar_Set(&com_gamename, gamemode_info[gamenum].gamename); + + #ifdef _WIN32 { //win32 sucks. ev = getenv("HOMEDRIVE"); @@ -4281,23 +4356,16 @@ void COM_InitFilesystem (void) } else { - for (i = 0; i < sizeof(pgp)/sizeof(pgp[0]); i++) - { - f = fopen(va(pgp[i].file, com_quakedir), "rb"); - if (f) - { - fclose(f); - COM_AddGameDirectory (va(pgp[i].path, com_quakedir)); - break; - } - } - if (i == sizeof(pgp)/sizeof(pgp[0])) - COM_AddGameDirectory (va(pgp[0].path, com_quakedir)); //just use the first. The assumption is that they unpacked thier data and deleted the pak files. + if (gamemode_info[gamenum].dir1) + COM_AddGameDirectory (va("%s/%s", com_quakedir, gamemode_info[gamenum].dir1)); + if (gamemode_info[gamenum].dir2) + COM_AddGameDirectory (va("%s/%s", com_quakedir, gamemode_info[gamenum].dir2)); + if (gamemode_info[gamenum].dir3) + COM_AddGameDirectory (va("%s/%s", com_quakedir, gamemode_info[gamenum].dir3)); + if (gamemode_info[gamenum].dir4) + COM_AddGameDirectory (va("%s/%s", com_quakedir, gamemode_info[gamenum].dir4)); } - COM_AddGameDirectory (va("%s/qw", com_quakedir) ); - COM_AddGameDirectory (va("%s/fte", com_quakedir) ); - if (*com_homedir) COM_AddGameDirectory (va("%s/fte", com_homedir) ); @@ -4315,8 +4383,6 @@ void COM_InitFilesystem (void) } } - - /* ===================================================================== diff --git a/engine/common/cvar.c b/engine/common/cvar.c index 3bff21f6..351d8200 100644 --- a/engine/common/cvar.c +++ b/engine/common/cvar.c @@ -238,7 +238,7 @@ cvar_t *Cvar_SetCore (cvar_t *var, const char *value, qboolean force) if (cls.state >= ca_connected) { #ifdef Q2CLIENT - if (cls.q2server) //q2 just resends the lot. Kinda bad... + if (cls.protocol == CP_QUAKE2) //q2 just resends the lot. Kinda bad... { cls.resendinfo = true; } diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 6d4f2e1d..0d792f68 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -269,10 +269,10 @@ int numplanes; mplane_t map_planes[MAX_Q2MAP_PLANES+6]; // extra for box hull int numnodes; -mnode_t map_nodes[MAX_Q2MAP_NODES+6]; // extra for box hull +mnode_t map_nodes[MAX_MAP_NODES+6]; // extra for box hull int numleafs = 1; // allow leaf funcs to be called without a map -mleaf_t map_leafs[MAX_Q2MAP_LEAFS]; +mleaf_t map_leafs[MAX_MAP_LEAFS]; int emptyleaf; int numleafbrushes; @@ -1433,7 +1433,7 @@ void CMod_LoadNodes (lump_t *l) if (count < 1) Host_Error ("Map has no nodes"); - if (count > MAX_Q2MAP_NODES) + if (count > MAX_MAP_NODES) Host_Error ("Map has too many nodes"); out = map_nodes; @@ -2173,6 +2173,33 @@ void CModQ3_LoadFogs (lump_t *l) if (count) GL_InitFogTexture(); } + +mfog_t *CM_FogForOrigin(vec3_t org) +{ + int i, j; + mfog_t *ret = map_fogs; + float dot; + if (!cl.worldmodel || cl.worldmodel->fromgame != fg_quake3) + return NULL; + + for ( i=0 ; inumplanes) + continue; + for (j = 0; j < ret->numplanes; j++) + { + dot = DotProduct(ret->planes[j]->normal, org); + if (dot - ret->planes[j]->dist > 0) + break; + } + if (j == ret->numplanes) + { + return ret; + } + } + + return NULL; +} #endif //Convert a patch in to a list of glpolys @@ -2352,6 +2379,32 @@ mesh_t *GL_CreateMeshForPatch (model_t *mod, int patchwidth, int patchheight, in #endif +void CModQ3_SortShaders(void) +{ + texture_t *textemp; + int i, j; + //sort loadmodel->textures + //correct pointers in loadmodel->texinfo +/* + for (i = 0; i < numtexinfo; i++) + { + for (j = i+1; j < numtexinfo; j++) + { + if (!loadmodel->textures[i]->shader || (loadmodel->textures[j]->shader && loadmodel->textures[j]->shader->sort > loadmodel->textures[i]->shader->sort)) + { + textemp = loadmodel->textures[j]; + loadmodel->textures[j] = loadmodel->textures[i]; + loadmodel->textures[i] = textemp; + + textemp = loadmodel->texinfo[j].texture; + loadmodel->texinfo[j].texture = loadmodel->texinfo[i].texture; + loadmodel->texinfo[i].texture = textemp; + } + } + } + */ +} + mesh_t nullmesh; void CModQ3_LoadRFaces (lump_t *l, qboolean useshaders) { @@ -2492,6 +2545,9 @@ continue; out->dlightbits = (unsigned int)COLOR_RGB ( r, g, b ); */ } } + + if (useshaders) + CModQ3_SortShaders(); } void CModRBSP_LoadRFaces (lump_t *l, qboolean useshaders) @@ -2629,6 +2685,9 @@ continue; out->dlightbits = (unsigned int)COLOR_RGB ( r, g, b ); */ } } + + if (useshaders) + CModQ3_SortShaders(); } #endif @@ -2758,11 +2817,9 @@ void CModQ3_LoadLeafs (lump_t *l) if (count < 1) Host_Error ("Map with no leafs"); // need to save space for box planes - if (count > MAX_Q2MAP_PLANES) - Host_Error ("Map has too many planes"); if (count > MAX_MAP_LEAFS) - Host_Error("Too many nodes on map"); + Host_Error("Too many leaves on map"); out = map_leafs; numleafs = count; @@ -2842,6 +2899,9 @@ void CModQ3_LoadPlanes (lump_t *l) count = l->filelen / sizeof(*in); out = map_planes;//Hunk_AllocName ( count*2*sizeof(*out), loadname); + if (count > MAX_MAP_PLANES) + Host_Error("Too many planes on map"); + numplanes = count; loadmodel->planes = out; @@ -2872,7 +2932,7 @@ void CModQ3_LoadLeafBrushes (lump_t *l) count = l->filelen / sizeof(*in); if (count < 1) - Host_Error ("Map with no planes"); + Host_Error ("Map with no leafbrushes"); // need to save space for box planes if (count > MAX_Q2MAP_LEAFBRUSHES) Host_Error ("Map has too many leafbrushes"); @@ -2948,16 +3008,34 @@ void CModRBSP_LoadBrushSides (lump_t *l) void CModQ3_LoadVisibility (lump_t *l) { - numvisibility = l->filelen; - if (l->filelen > MAX_Q2MAP_VISIBILITY+sizeof(int)*2) - Host_Error ("Map has too large visibility lump"); + if (l->filelen == 0) + { + int i; + numclusters = 0; + for (i = 0; i < loadmodel->numleafs; i++) + if (numclusters <= loadmodel->leafs[i].cluster) + numclusters = loadmodel->leafs[i].cluster+1; - loadmodel->vis = (q2dvis_t *)map_q3pvs; + numclusters++; - memcpy (map_visibility, cmod_base + l->fileofs, l->filelen); + memset (map_visibility, 0xff, sizeof(map_visibility)); + map_q3pvs->numclusters = numclusters; + numvisibility = 0; + map_q3pvs->rowsize = (map_q3pvs->numclusters+7)/8; + } + else + { + numvisibility = l->filelen; + if (l->filelen > MAX_Q2MAP_VISIBILITY) + Host_Error ("Map has too large visibility lump"); - numclusters = map_q3pvs->numclusters = LittleLong (map_q3pvs->numclusters); - map_q3pvs->rowsize = LittleLong (map_q3pvs->rowsize); + loadmodel->vis = (q2dvis_t *)map_q3pvs; + + memcpy (map_visibility, cmod_base + l->fileofs, l->filelen); + + numclusters = map_q3pvs->numclusters = LittleLong (map_q3pvs->numclusters); + map_q3pvs->rowsize = LittleLong (map_q3pvs->rowsize); + } } #ifndef SERVERONLY @@ -3767,7 +3845,7 @@ int CM_NumClusters (void) int CM_ClusterSize (void) { - return map_q3pvs->rowsize ? map_q3pvs->rowsize : MAX_Q2MAP_LEAFS / 8; + return map_q3pvs->rowsize ? map_q3pvs->rowsize : MAX_MAP_LEAFS / 8; } int CM_NumInlineModels (void) @@ -3841,7 +3919,7 @@ void CM_InitBoxHull (void) box_headnode = numnodes; box_planes = &map_planes[numplanes]; - if (numnodes+6 > MAX_Q2MAP_NODES + if (numnodes+6 > MAX_MAP_NODES || numbrushes+1 > MAX_Q2MAP_BRUSHES || numleafbrushes+1 > MAX_Q2MAP_LEAFBRUSHES || numbrushsides+6 > MAX_Q2MAP_BRUSHSIDES @@ -4948,17 +5026,17 @@ trace_t CM_TransformedBoxTrace (vec3_t start, vec3_t end, trace.plane.normal[0] = DotProduct (temp, forward); trace.plane.normal[1] = -DotProduct (temp, right); trace.plane.normal[2] = DotProduct (temp, up); + } - if (trace.fraction == 1) - { - VectorCopy(end, trace.endpos); - } - else - { - trace.endpos[0] = start[0] + trace.fraction * (end[0] - start[0]); - trace.endpos[1] = start[1] + trace.fraction * (end[1] - start[1]); - trace.endpos[2] = start[2] + trace.fraction * (end[2] - start[2]); - } + if (trace.fraction == 1) + { + VectorCopy(end, trace.endpos); + } + else + { + trace.endpos[0] = start[0] + trace.fraction * (end[0] - start[0]); + trace.endpos[1] = start[1] + trace.fraction * (end[1] - start[1]); + trace.endpos[2] = start[2] + trace.fraction * (end[2] - start[2]); } return trace; @@ -5077,8 +5155,8 @@ void CM_DecompressVis (qbyte *in, qbyte *out) } while (out_p - out < row); } -qbyte pvsrow[MAX_Q2MAP_LEAFS/8]; -qbyte phsrow[MAX_Q2MAP_LEAFS/8]; +qbyte pvsrow[MAX_MAP_LEAFS/8]; +qbyte phsrow[MAX_MAP_LEAFS/8]; diff --git a/engine/common/mathlib.c b/engine/common/mathlib.c index 50a30143..4a236105 100644 --- a/engine/common/mathlib.c +++ b/engine/common/mathlib.c @@ -897,7 +897,7 @@ void ML_ProjectionMatrix(float *proj, float wdivh, float fovy) } //screen->3d -/* + void ML_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, float wdivh, float fovy) { float modelview[16]; @@ -924,7 +924,7 @@ void ML_UnProject(vec3_t in, vec3_t out, vec3_t viewangles, vec3_t vieworg, floa out[1] = (1+v[1])/2; out[2] = (1+v[2])/2; } -}*/ +} //returns fractions of screen. //uses GL style rotations and translations and stuff. diff --git a/engine/common/net.h b/engine/common/net.h index 1fb7f079..8f7bff3b 100644 --- a/engine/common/net.h +++ b/engine/common/net.h @@ -51,7 +51,8 @@ struct sockaddr_qstorage }; -extern netadr_t net_local_ipadr; +extern netadr_t net_local_sv_ipadr; +extern netadr_t net_local_cl_ipadr; extern netadr_t net_from; // address of who sent the packet extern sizebuf_t net_message; //#define MAX_UDP_PACKET (MAX_MSGLEN*2) // one more than msg + header @@ -112,12 +113,14 @@ typedef struct // double rate; // seconds / qbyte // sequencing variables + int incoming_unreliable; //dictated by the other end. int incoming_sequence; int incoming_acknowledged; int incoming_reliable_acknowledged; // single bit int incoming_reliable_sequence; // single bit, maintained local + int outgoing_unreliable; int outgoing_sequence; int reliable_sequence; // single bit int last_reliable_sequence; // sequence number of last send @@ -126,7 +129,9 @@ typedef struct sizebuf_t message; // writing buffer to send to server qbyte message_buf[MAX_OVERALLMSGLEN]; + //nq has message truncation. int reliable_length; + int reliable_start; qbyte reliable_buf[MAX_OVERALLMSGLEN]; // unacked reliable message // time and size data to calculate bandwidth @@ -134,16 +139,10 @@ typedef struct double outgoing_time[MAX_LATENT]; qboolean compress; -#ifdef Q3CLIENT - int inLength; - char inBuffer[MAX_UDP_PACKET]; - int inFragmentSequence; - - qboolean outFragment; - int outLength; - int outStart; - char outBuffer[MAX_UDP_PACKET]; -#endif + //nq servers must recieve truncated packets. + int in_reliable_length; + char in_reliable_buf[MAX_OVERALLMSGLEN]; + int in_reliable_start; } netchan_t; extern int net_drop; // packets dropped before this one @@ -168,7 +167,31 @@ int Huff_GetByte(qbyte *buffer, int *count); #endif #ifdef NQPROT -#include "../nqnet/nqnet.h" +//taken from nq's net.h +//refer to that for usage info. :) + +#define NETFLAG_LENGTH_MASK 0x0000ffff +#define NETFLAG_DATA 0x00010000 +#define NETFLAG_ACK 0x00020000 +#define NETFLAG_NAK 0x00040000 +#define NETFLAG_EOM 0x00080000 +#define NETFLAG_UNRELIABLE 0x00100000 +#define NETFLAG_CTL 0x80000000 + +#define NET_GAMENAME_NQ "QUAKE" +#define NET_PROTOCOL_VERSION 3 + + +#define CCREQ_CONNECT 0x01 +#define CCREQ_SERVER_INFO 0x02 +#define CCREQ_PLAYER_INFO 0x03 +#define CCREQ_RULE_INFO 0x04 + +#define CCREP_ACCEPT 0x81 +#define CCREP_REJECT 0x82 +#define CCREP_SERVER_INFO 0x83 +#define CCREP_PLAYER_INFO 0x84 +#define CCREP_RULE_INFO 0x85 #endif int UDP_OpenSocket (int port, qboolean bcast); diff --git a/engine/common/net_chan.c b/engine/common/net_chan.c index 066f4dd7..f185094b 100644 --- a/engine/common/net_chan.c +++ b/engine/common/net_chan.c @@ -231,6 +231,104 @@ qboolean Netchan_CanReliable (netchan_t *chan, int rate) qboolean ServerPaused(void); #endif +#ifdef NQPROT +qboolean NQNetChan_Process(netchan_t *chan) +{ + int header; + int sequence; + int drop; + + MSG_BeginReading (); + + header = BigLong(MSG_ReadLong()); + if (net_message.cursize != (header & NETFLAG_LENGTH_MASK)) + return false; //size was wrong, couldn't have been ours. + + if (header & NETFLAG_CTL) + return false; //huh? + + sequence = BigLong(MSG_ReadLong()); + + if (header & NETFLAG_ACK) + { + if (sequence == chan->reliable_sequence) + { + chan->reliable_start += MAX_NQDATAGRAM; + if (chan->reliable_start >= chan->reliable_length) + { + chan->reliable_length = 0; //they got the entire message + chan->reliable_start = 0; + } + chan->incoming_reliable_acknowledged = chan->reliable_sequence; + chan->reliable_sequence++; + + chan->last_received = realtime; + } + else if (sequence < chan->reliable_sequence) + Con_DPrintf("Stale ack recieved\n"); + else if (sequence > chan->reliable_sequence) + Con_Printf("Future ack recieved\n"); + + return false; //don't try execing the 'payload'. I hate ack packets. + } + + if (header & NETFLAG_UNRELIABLE) + { + if (sequence < chan->incoming_unreliable) + { + Con_DPrintf("Stale datagram recieved\n"); + return false; + } + drop = sequence - chan->incoming_unreliable - 1; + if (drop > 0) + Con_DPrintf("Dropped %i datagrams\n", drop); + chan->incoming_unreliable = sequence; + + chan->last_received = realtime; + + chan->incoming_acknowledged++; + return 1; + } + if (header & NETFLAG_DATA) + { + int runt[2]; + //always reply. a stale sequence probably means our ack got lost. + runt[0] = BigLong(NETFLAG_ACK | 8); + runt[1] = BigLong(sequence); + NET_SendPacket (chan->sock, 8, runt, net_from); + + chan->last_received = realtime; + if (sequence == chan->incoming_reliable_sequence) + { + chan->incoming_reliable_sequence++; + + if (chan->in_reliable_length + net_message.cursize-8 >= sizeof(chan->in_reliable_buf)) + { + chan->fatal_error = true; + return false; + } + + memcpy(chan->in_reliable_buf + chan->in_reliable_length, net_message.data+8, net_message.cursize-8); + chan->in_reliable_length += net_message.cursize-8; + + if (header & NETFLAG_EOM) + { + SZ_Clear(&net_message); + SZ_Write(&net_message, chan->in_reliable_buf, chan->in_reliable_length); + chan->in_reliable_length = 0; + MSG_BeginReading(); + return 2; //we can read it now + } + } + else + Con_DPrintf("Stale reliable (%i)\n", sequence); + return false; + } + + return false; //not supported. +} +#endif + /* =============== Netchan_Transmit @@ -250,34 +348,62 @@ void Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate) int i; #ifdef NQPROT - if (chan->qsocket && !chan->qsocket->qwprotocol) + if (chan->isnqprotocol) { - if (!NET_CanSendMessage (chan->qsocket)) - return; - if (!chan->reliable_length && chan->message.cursize) - { - memcpy (chan->reliable_buf, chan->message_buf, chan->message.cursize); - chan->reliable_length = chan->message.cursize; - chan->message.cursize = 0; - chan->reliable_sequence ^= 1; - send_reliable = true; - } - send.data = send_buf; send.maxsize = MAX_NQMSGLEN + PACKET_HEADER; send.cursize = 0; - chan->outgoing_sequence++; - chan->last_reliable_sequence = chan->outgoing_sequence; + //send out the unreliable + if (length) + { + MSG_WriteLong(&send, 0); + MSG_WriteLong(&send, BigLong(chan->outgoing_unreliable)); + chan->outgoing_unreliable++; - SZ_Write (&send, chan->reliable_buf, chan->reliable_length); + SZ_Write (&send, data, length); - SZ_Write (&send, data, length); + *(int*)send_buf = BigLong(NETFLAG_UNRELIABLE | send.cursize); + NET_SendPacket (chan->sock, send.cursize, send.data, chan->remote_address); - NET_SendMessage(chan->qsocket, &send); + if (chan->cleartime < realtime) + chan->cleartime = realtime + send.cursize/(float)rate; + else + chan->cleartime += send.cursize/(float)rate; - chan->message.cursize = 0; - chan->reliable_length = 0; + send.cursize = 0; + } + + if (!chan->reliable_length && chan->message.cursize) + { + memcpy (chan->reliable_buf, chan->message_buf, chan->message.cursize); + chan->reliable_length = chan->message.cursize; + chan->reliable_start = 0; + chan->message.cursize = 0; + } + + i = chan->reliable_length - chan->reliable_start; + if (i>0) + { + MSG_WriteLong(&send, 0); + MSG_WriteLong(&send, BigLong(chan->reliable_sequence)); + if (i > MAX_NQDATAGRAM) + i = MAX_NQDATAGRAM; + + SZ_Write (&send, chan->reliable_buf+chan->reliable_start, i); + + + if (chan->reliable_start+i == chan->reliable_length) + *(int*)send_buf = BigLong(NETFLAG_DATA | NETFLAG_EOM | send.cursize); + else + *(int*)send_buf = BigLong(NETFLAG_DATA | send.cursize); + NET_SendPacket (chan->sock, send.cursize, send.data, chan->remote_address); + + if (chan->cleartime < realtime) + chan->cleartime = realtime + send.cursize/(float)rate; + else + chan->cleartime += send.cursize/(float)rate; + } return; } #endif @@ -358,12 +484,7 @@ void Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate) if (!cls.demoplayback) #endif { -#ifdef NQPROT - if (chan->qsocket) - NET_SendUnreliableMessage(chan->qsocket, &send); //qw protocol adds it's own reliability. - else -#endif - NET_SendPacket (chan->sock, send.cursize, send.data, chan->remote_address); + NET_SendPacket (chan->sock, send.cursize, send.data, chan->remote_address); } if (chan->cleartime < realtime) diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index 938c7ff8..9178f400 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -77,8 +77,12 @@ struct sockaddr; #define qerrno errno //linux and single threaded oses are happy with errno as a global #endif -netadr_t net_local_ipadr; -netadr_t net_local_ip6adr; +netadr_t net_local_cl_ipadr; +netadr_t net_local_cl_ip6adr; +netadr_t net_local_cl_ipxadr; +netadr_t net_local_sv_ipadr; +netadr_t net_local_sv_ip6adr; +netadr_t net_local_sv_ipxadr; netadr_t net_from; sizebuf_t net_message; @@ -1049,31 +1053,7 @@ qboolean NET_Sleep(int msec, qboolean stdinissocket) } #endif -void NET_GetLocalIP6Address (int socket) -{ -// char buff[512]; - struct sockaddr_qstorage address; - int namelen; -// netadr_t adr; - -// gethostname(buff, 512); -// buff[512-1] = 0; - -// NET_StringToAdr (buff, &adr); - - namelen = sizeof(address); - memset(&address, 0, sizeof(address)); - if (getsockname (socket, (struct sockaddr *)&address, &namelen) == -1) - Sys_Error ("NET_Init: getsockname:", strerror(qerrno)); - - SockadrToNetadr(&address, &net_local_ip6adr); -/* if (!*(int*)net_local_ip6adr.ip) //socket was set to auto - *(int *)net_local_ip6adr.ip = *(int *)adr.ip; //change it to what the machine says it is, rather than the socket. -*/ - Con_TPrintf(TL_IPADDRESSIS, NET_AdrToString (net_local_ip6adr) ); -} - -void NET_GetLocalIPAddress (int socket) +void NET_GetLocalAddress (int socket, netadr_t *out) { char buff[512]; struct sockaddr_qstorage address; @@ -1089,39 +1069,11 @@ void NET_GetLocalIPAddress (int socket) if (getsockname (socket, (struct sockaddr *)&address, &namelen) == -1) Sys_Error ("NET_Init: getsockname:", strerror(qerrno)); - SockadrToNetadr(&address, &net_local_ipadr); - if (!*(int*)net_local_ipadr.ip) //socket was set to auto - *(int *)net_local_ipadr.ip = *(int *)adr.ip; //change it to what the machine says it is, rather than the socket. + SockadrToNetadr(&address, out); + if (!*(int*)out->ip) //socket was set to auto + *(int *)out->ip = *(int *)adr.ip; //change it to what the machine says it is, rather than the socket. - Con_TPrintf(TL_IPADDRESSIS, NET_AdrToString (net_local_ipadr) ); -} - -void NET_GetLocalIPXAddress (int socket) -{ - //we don't really care... this is for lans -/* char buff[512]; - struct sockaddr address; - int namelen; - netadr_t adr; - - gethostname(buff, 512); - buff[512-1] = 0; - - NET_StringToAdr (buff, &adr); - - namelen = sizeof(address); - if (getsockname (socket, (struct sockaddr *)&address, &namelen) == -1) - Sys_Error ("NET_Init: getsockname:", strerror(qerrno)); - - SockadrToNetadr(&address, &net_local_adr); - if (!*(int*)net_local_ipadr.ip) - *(int *)net_local_ipadr.ip = *(int *)adr.ip; - - if (net_local_adr.type == NA_IP) - Con_TPrintf(TL_IPADDRESSIS, NET_AdrToString (net_local_adr) ); - else - Con_Printf("IPX Address: %s\n", NET_AdrToString (net_local_adr) ); - */ + Con_TPrintf(TL_IPADDRESSIS, NET_AdrToString (*out) ); } /* @@ -1172,10 +1124,6 @@ void NET_Init (void) svs.socketip6 = INVALID_SOCKET; svs.socketipx = INVALID_SOCKET; #endif - -#ifdef NQPROT - NQ_NET_Init(); -#endif } #ifndef SERVERONLY void NET_InitClient(void) @@ -1208,7 +1156,7 @@ void NET_InitClient(void) // // determine my name & address // - NET_GetLocalIPAddress (cls.socketip); + NET_GetLocalAddress (cls.socketip, &net_local_cl_ipadr); Con_TPrintf(TL_CLIENTPORTINITED); } @@ -1237,7 +1185,9 @@ void NET_CloseServer(void) } #endif - net_local_ipadr.type = NA_LOOPBACK; + net_local_sv_ipadr.type = NA_LOOPBACK; + net_local_sv_ip6adr.type = NA_LOOPBACK; + net_local_sv_ipxadr.type = NA_LOOPBACK; } void NET_InitServer(void) @@ -1266,22 +1216,23 @@ void NET_InitServer(void) if (svs.socketip == INVALID_SOCKET) { svs.socketip = UDP_OpenSocket (port, false); - if (svs.socketip6 != INVALID_SOCKET) - NET_GetLocalIPAddress (svs.socketip); + if (svs.socketip != INVALID_SOCKET) + NET_GetLocalAddress (svs.socketip, &net_local_sv_ipadr); } #ifdef IPPROTO_IPV6 if (svs.socketip6 == INVALID_SOCKET) { svs.socketip6 = UDP6_OpenSocket (port, false); if (svs.socketip6 != INVALID_SOCKET) - NET_GetLocalIP6Address (svs.socketip6); + NET_GetLocalAddress (svs.socketip6, &net_local_sv_ip6adr); } #endif #ifdef USEIPX if (svs.socketipx == INVALID_SOCKET) { svs.socketipx = IPX_OpenSocket (port, false); - NET_GetLocalIPXAddress (svs.socketipx); + if (svs.socketipx != INVALID_SOCKET) + NET_GetLocalAddress (svs.socketipx, &net_local_sv_ipxadr); } #endif } @@ -1314,9 +1265,6 @@ void NET_Shutdown (void) IPX_CloseSocket (cls.socketipx); #endif #endif -#ifdef NQPROT - NQ_NET_Shutdown(); -#endif #ifdef _WIN32 #ifdef SERVERTONLY if (!serverthreadID) //running as subsystem of client. Don't close all of it's sockets too. diff --git a/engine/common/plugin.c b/engine/common/plugin.c index 4323021b..bbb95df7 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -177,8 +177,8 @@ plugin_t *Plug_Load(char *file) newplug->next = plugs; plugs = newplug; - argarray = 0; - VM_Call(newplug->vm, 0, Plug_FindBuiltin("Plug_GetEngineFunction", ~0, &argarray)); + argarray = 4; + VM_Call(newplug->vm, 0, Plug_FindBuiltin("Plug_GetEngineFunction"-4, ~0, &argarray)); if (newplug->reschange) VM_Call(newplug->vm, newplug->reschange, vid.width, vid.height); diff --git a/engine/common/protocol.h b/engine/common/protocol.h index d1dbbf8c..6a8f2c37 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -195,6 +195,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define svcnq_effect2 53 // [vector] org [short] modelindex [short] startframe [byte] framecount [byte] framerate #define svc_updatepl 53 // [qbyte] [qbyte] +#define svcdp_precache 54 // [short] precacheindex [string] filename, precacheindex is + 0 for modelindex and +32768 for soundindex #define svc_nails2 54 //qwe - [qbyte] num [52 bits] nxyzpy 8 12 12 12 4 8 @@ -243,6 +244,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define svc_csqcentities 76 //entity lump for csqc #endif +#define svc_precache 77 + #define svc_invalid 256 @@ -603,6 +606,7 @@ enum { #define DPTE_BLOOD 50 #define DPTE_SPARK 51 #define DPTE_BLOODSHOWER 52 +#define DPTE_PARTICLECUBE 54 #define DPTE_SMALLFLASH 72 #define DPTE_CUSTOMFLASH 73 #define DPTE_FLAMEJET 74 diff --git a/engine/ftequake/ftequake.dsp b/engine/ftequake/ftequake.dsp index bc139e06..988fb16b 100644 --- a/engine/ftequake/ftequake.dsp +++ b/engine/ftequake/ftequake.dsp @@ -274,7 +274,8 @@ LINK32=link.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /D "MINIMAL" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c -# ADD CPP /nologo /G6 /ML /W3 /WX /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SERVERONLY" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c +# ADD CPP /nologo /G6 /ML /W3 /Gm /Gi /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "SERVERONLY" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c +# SUBTRACT CPP /WX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" @@ -4938,10 +4939,14 @@ SOURCE=..\nqnet\net_dgrm.c !ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" +# PROP Exclude_From_Build 1 + !ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" !ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" +# PROP Exclude_From_Build 1 + !ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" @@ -4971,10 +4976,14 @@ SOURCE=..\nqnet\net_loop.c !ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" +# PROP Exclude_From_Build 1 + !ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" !ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" +# PROP Exclude_From_Build 1 + !ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" @@ -5004,10 +5013,14 @@ SOURCE=..\nqnet\net_main.c !ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" +# PROP Exclude_From_Build 1 + !ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" !ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" +# PROP Exclude_From_Build 1 + !ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" @@ -5037,10 +5050,14 @@ SOURCE=..\nqnet\net_win.c !ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" +# PROP Exclude_From_Build 1 + !ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" !ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" +# PROP Exclude_From_Build 1 + !ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" @@ -5070,10 +5087,14 @@ SOURCE=..\nqnet\net_wipx.c !ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" +# PROP Exclude_From_Build 1 + !ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" !ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" +# PROP Exclude_From_Build 1 + !ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" !ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" @@ -5092,6 +5113,37 @@ SOURCE=..\nqnet\net_wipx.c # Begin Source File SOURCE=..\nqnet\nqnet.h + +!IF "$(CFG)" == "ftequake - Win32 Release" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug" + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebug" + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLRelease" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLRelease" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Debug Dedicated Server" + +!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server" + +!ELSEIF "$(CFG)" == "ftequake - Win32 MinSW" + +!ELSEIF "$(CFG)" == "ftequake - Win32 GLDebugQ3" + +!ENDIF + # End Source File # End Group # Begin Group "common" diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 5650d768..dea6af56 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -1017,15 +1017,11 @@ void GL_DrawAliasMesh_Sketch (mesh_t *mesh) else qglDisableClientState( GL_COLOR_ARRAY ); - qglEnableClientState( GL_TEXTURE_COORD_ARRAY ); - qglTexCoordPointer(2, GL_FLOAT, 0, mesh->st_array); - qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_UNSIGNED_INT, mesh->indexes); qglDisableClientState( GL_VERTEX_ARRAY ); qglDisableClientState( GL_COLOR_ARRAY ); qglDisableClientState( GL_NORMAL_ARRAY ); - qglDisableClientState( GL_TEXTURE_COORD_ARRAY ); qglColor3f(0, 0, 0); qglBegin(GL_LINES); @@ -1150,6 +1146,11 @@ void R_DrawGAliasModel (entity_t *e) float entScale; vec3_t lightdir; + vec3_t saveorg; +#ifdef Q3SHADERS + mfog_t *fog; +#endif + float tmatrix[3][4]; currententity = e; @@ -1458,6 +1459,16 @@ void R_DrawGAliasModel (entity_t *e) if (qglPNTrianglesfATI && gl_ati_truform.value) qglEnable(GL_PN_TRIANGLES_ATI); + if (e->flags & Q2RF_WEAPONMODEL) + { + VectorCopy(currententity->origin, saveorg); + VectorCopy(r_refdef.vieworg, currententity->origin); + } + +#ifdef Q3SHADERS + fog = CM_FogForOrigin(currententity->origin); +#endif + memset(&mesh, 0, sizeof(mesh)); for(; inf; ((inf->nextsurf)?(inf = (galiasinfo_t*)((char *)inf + inf->nextsurf)):(inf=NULL))) { @@ -1480,7 +1491,7 @@ void R_DrawGAliasModel (entity_t *e) mb.entity = &r_worldentity; mb.shader = currententity->forcedshader; - mb.fog = NULL; + mb.fog = fog; mb.mesh = &mesh; mb.infokey = currententity->keynum; mb.dlightbits = 0; @@ -1497,7 +1508,6 @@ void R_DrawGAliasModel (entity_t *e) if (!skin) { - qglEnable(GL_TEXTURE_2D); GL_DrawAliasMesh_Sketch(&mesh); } #ifdef Q3SHADERS @@ -1513,7 +1523,7 @@ void R_DrawGAliasModel (entity_t *e) mb.entity = &r_worldentity; mb.shader = skin->shader; - mb.fog = NULL; + mb.fog = fog; mb.mesh = &mesh; mb.infokey = currententity->keynum; mb.dlightbits = 0; @@ -1549,6 +1559,9 @@ void R_DrawGAliasModel (entity_t *e) } } + if (e->flags & Q2RF_WEAPONMODEL) + VectorCopy(saveorg, currententity->origin); + if (qglPNTrianglesfATI && gl_ati_truform.value) qglDisable(GL_PN_TRIANGLES_ATI); @@ -2226,6 +2239,12 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha) outskin->ofstexnums = (char *)texnums - (char *)outskin; +#ifdef Q3SHADERS + sprintf(skinname, "%s_%i", loadname, i); + texnums->shader = R_RegisterSkin(skinname); +#endif + + texnums->base = texture; texnums->fullbright = fbtexture; @@ -2298,6 +2317,11 @@ static void *Q1_LoadSkins (daliasskintype_t *pskintype, qboolean alpha) if (t != 0) //only keep the first. BZ_Free(saved); } + + sprintf(skinname, "%s_%i_%i", loadname, i, t); +#ifdef Q3SHADERS + texnums->shader = R_RegisterSkin(skinname); +#endif texnums->base = texture; texnums->fullbright = fbtexture; } diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index e93ac76e..fc37e46d 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -1733,15 +1733,11 @@ void R_RenderMeshMultitextured ( meshbuffer_t *mb, shaderpass_t *pass ) r_numUnits = pass->numMergedPasses; - R_SetShaderpassState ( pass, true ); - R_ModifyColor ( mb, pass ); - R_ModifyTextureCoords ( pass, 0 ); - GL_SelectTexture( mtexid0 ); - if ( pass->blendmode == GL_REPLACE ) - GL_TexEnv( GL_REPLACE ); - else - GL_TexEnv( GL_MODULATE ); + GL_TexEnv( pass->blendmode ); + R_SetShaderpassState ( pass, true ); + R_ModifyTextureCoords ( pass, 0 ); + R_ModifyColor ( mb, pass ); for ( i = 1, pass++; i < r_numUnits; i++, pass++ ) { @@ -2027,6 +2023,7 @@ void R_RenderFogOnMesh ( shader_t *shader, struct mfog_s *fog ) GL_Bind( r_fogtexture ); qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + GL_TexEnv(GL_MODULATE); if ( !shader->numpasses || shader->fog_dist || (shader->flags & SHADER_SKY) ) { @@ -2173,7 +2170,7 @@ void R_FinishMeshBuffer ( meshbuffer_t *mb ) qglEnable ( GL_BLEND ); qglDisable ( GL_ALPHA_TEST ); -// qglDepthMask ( GL_FALSE ); + qglDepthMask ( GL_FALSE ); //FIZME // if ( dlight ) { diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index 1647e48d..c59409bc 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -634,7 +634,7 @@ typedef struct //q3 based typedef struct { - vec3_t gridBounds; + int gridBounds[4]; //3 = 0*1 vec3_t gridMins; vec3_t gridSize; int numlightgridelems; diff --git a/engine/gl/gl_rlight.c b/engine/gl/gl_rlight.c index a870e1a8..1bd80f9f 100644 --- a/engine/gl/gl_rlight.c +++ b/engine/gl/gl_rlight.c @@ -400,7 +400,7 @@ vec3_t lightspot; void GLQ3_LightGrid(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir) { q3lightgridinfo_t *lg = (q3lightgridinfo_t *)cl.worldmodel->lightgrid; - int index[4]; + int index[8]; int vi[3]; int i, j; float t[8], direction_uv[3]; @@ -414,7 +414,7 @@ void GLQ3_LightGrid(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir[2] = 0.1; } -// if (!lg) + if (!lg || !lg->lightgrid) { if(res_ambient) { @@ -438,7 +438,7 @@ void GLQ3_LightGrid(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t for ( i = 0; i < 3; i++ ) { vf[i] = (point[i] - lg->gridMins[i]) / lg->gridSize[i]; - vi[i] = (int)vf[i]; + vi[i] = (int)(vf[i]); vf[i] = vf[i] - floor(vf[i]); vf2[i] = 1.0f - vf[i]; } @@ -448,9 +448,33 @@ void GLQ3_LightGrid(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t index[2] = index[0] + lg->gridBounds[3]; index[3] = index[2] + lg->gridBounds[0]; - for ( i = 0; i < 4; i++ ) + index[4] = index[0]+(index[0]<(lg->numlightgridelems-1)); + index[5] = index[1]+(index[1]<(lg->numlightgridelems-1)); + index[6] = index[2]+(index[2]<(lg->numlightgridelems-1)); + index[7] = index[3]+(index[3]<(lg->numlightgridelems-1)); +/* + qglDisable(GL_TEXTURE_2D); + qglDisable(GL_DEPTH_TEST); + qglDisable(GL_CULL_FACE); + qglColor4f(1,1,1,1); + qglBegin(GL_QUADS); + for ( i = 0; i < 8; i++ ) { - if ( index[i] < 0 || index[i] >= (lg->numlightgridelems-1) ) + vec3_t pos; + for(j=0;j<3;j++) + pos[j] = (vi[j] + +((i&1)/1*(j==0)) + +((i&2)/2*(j==1)) + +((i&4)/4*(j==2)) + + )*lg->gridSize[j] + lg->gridMins[j]; + qglVertex3fv(pos); + } + qglEnd(); +*/ + for ( i = 0; i < 8; i++ ) + { + if ( index[i] < 0 || index[i] >= (lg->numlightgridelems) ) { res_ambient[0] = 255; //out of the map res_ambient[1] = 255; @@ -475,11 +499,11 @@ void GLQ3_LightGrid(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t for ( i = 0; i < 4; i++ ) { - ambient[j] += t[i*2] * lg->lightgrid[ index[i] ].ambient[j]; - ambient[j] += t[i*2+1] * lg->lightgrid[ index[i] + 1 ].ambient[j]; + ambient[j] += t[i*2] * lg->lightgrid[ index[i]].ambient[j]; + ambient[j] += t[i*2+1] * lg->lightgrid[ index[i+4]].ambient[j]; - diffuse[j] += t[i*2] * lg->lightgrid[ index[i] ].diffuse[j]; - diffuse[j] += t[i*2+1] * lg->lightgrid[ index[i] + 1 ].diffuse[j]; + diffuse[j] += t[i*2] * lg->lightgrid[ index[i]].diffuse[j]; + diffuse[j] += t[i*2+1] * lg->lightgrid[ index[i+4]].diffuse[j]; } } @@ -489,8 +513,8 @@ void GLQ3_LightGrid(vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t for ( i = 0; i < 4; i++ ) { - direction_uv[j] += t[i*2] * lg->lightgrid[ index[i] ].direction[j]; - direction_uv[j] += t[i*2+1] * lg->lightgrid[ index[i] + 1 ].direction[j]; + direction_uv[j] += t[i*2] * lg->lightgrid[ index[i]].direction[j]; + direction_uv[j] += t[i*2+1] * lg->lightgrid[ index[i+4]].direction[j]; } direction_uv[j] = anglemod ( direction_uv[j] ); diff --git a/engine/gl/gl_rsurf.c b/engine/gl/gl_rsurf.c index f34bb9cd..d599e8a3 100644 --- a/engine/gl/gl_rsurf.c +++ b/engine/gl/gl_rsurf.c @@ -3166,7 +3166,7 @@ void R_DrawWorld (void) int leafnum; int clientarea; int CM_WriteAreaBits (qbyte *buffer, int area); - if (cls.q2server) //we can get server sent info + if (cls.protocol == CP_QUAKE2) //we can get server sent info memcpy(areabits, cl.q2frame.areabits, sizeof(areabits)); else { //generate the info each frame. diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 94f676ec..9bd511c9 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -486,6 +486,15 @@ static void Shader_FogParms ( shader_t *shader, shaderpass_t *pass, char **ptr ) shader->fog_dist = 1.0f / shader->fog_dist; } +static void Shader_SurfaceParm ( shader_t *shader, shaderpass_t *pass, char **ptr ) +{ + char *token; + + token = Shader_ParseString ( ptr ); + if ( !Q_stricmp( token, "nodraw" ) ) + shader->flags = SHADER_NODRAW; +} + static void Shader_Sort ( shader_t *shader, shaderpass_t *pass, char **ptr ) { char *token; @@ -531,6 +540,7 @@ static shaderkey_t shaderkeys[] = {"cull", Shader_Cull }, {"skyparms", Shader_SkyParms }, {"fogparms", Shader_FogParms }, + {"surfaceparm", Shader_SurfaceParm }, {"nomipmaps", Shader_NoMipMaps }, {"nopicmip", Shader_NoPicMip }, {"polygonoffset", Shader_PolygonOffset }, @@ -1263,7 +1273,7 @@ void Shader_SetPassFlush ( shaderpass_t *pass, shaderpass_t *pass2 ) return; // check if we can use R_RenderMeshCombined -/* + if ( gl_config.tex_env_combine || gl_config.nv_tex_env_combine4 ) { if ( pass->blendmode == GL_REPLACE ) @@ -1285,9 +1295,7 @@ void Shader_SetPassFlush ( shaderpass_t *pass, shaderpass_t *pass2 ) pass->flush = R_RenderMeshCombined; } } - else - */ - if ( qglMTexCoord2fSGIS ) + else if ( qglMTexCoord2fSGIS ) { // check if we can use R_RenderMeshMultitextured if ( pass->blendmode == GL_REPLACE ) @@ -1311,7 +1319,7 @@ void Shader_SetPassFlush ( shaderpass_t *pass, shaderpass_t *pass2 ) else if ( pass->blendmode == GL_ADD && pass2->blendmode == GL_ADD && gl_config.env_add ) { -// pass->flush = R_RenderMeshCombined; + pass->flush = R_RenderMeshCombined; } } @@ -1396,6 +1404,22 @@ void Shader_Finish ( shader_t *s ) s->flags |= SHADER_FLARE; } + if (!s->numpasses && !(s->flags & (SHADER_NODRAW|SHADER_SKY))) + { + pass = &s->passes[s->numpasses++]; + pass = &s->passes[0]; + pass->tcgen = TC_GEN_BASE; + pass->anim_frames[0] = Mod_LoadHiResTexture(s->name, NULL, true, false, true);//GL_FindImage (shortname, 0); + pass->depthfunc = GL_LEQUAL; + pass->flags = SHADER_PASS_DEPTHWRITE; + pass->rgbgen = RGB_GEN_VERTEX; + pass->alphagen = ALPHA_GEN_IDENTITY; + pass->blendmode = GL_MODULATE; + pass->numMergedPasses = 1; + pass->flush = R_RenderMeshGeneric; + Con_Printf("Shader %s with no passes and no surfaceparm nodraw, inserting pass\n", s->name); + } + if ( !s->numpasses && !s->sort ) { s->sort = SHADER_SORT_ADDITIVE; return; @@ -1707,13 +1731,13 @@ void Shader_DefaultBSP(char *shortname, shader_t *s) pass->rgbgen = RGB_GEN_IDENTITY; pass->numMergedPasses = 2; -/* if ( qglMTexCoord2fSGIS ) + if ( qglMTexCoord2fSGIS ) { pass->numMergedPasses = 2; pass->flush = R_RenderMeshMultitextured; } else -*/ { + { pass->numMergedPasses = 1; pass->flush = R_RenderMeshGeneric; } @@ -1823,7 +1847,7 @@ void Shader_DefaultSkin(char *shortname, shader_t *s) s->numpasses = 1; s->numdeforms = 0; - s->flags = SHADER_PASS_BLEND|SHADER_DEPTHWRITE|SHADER_CULL_FRONT; + s->flags = SHADER_BLEND|SHADER_DEPTHWRITE|SHADER_CULL_FRONT; s->features = MF_STCOORDS|MF_NORMALS; s->sort = SHADER_SORT_OPAQUE; s->registration_sequence = 1;//fizme: registration_sequence; diff --git a/engine/gl/gl_warp.c b/engine/gl/gl_warp.c index 4ee1333d..749ccc94 100644 --- a/engine/gl/gl_warp.c +++ b/engine/gl/gl_warp.c @@ -193,7 +193,7 @@ void R_DrawSkyChain (msurface_t *s) msurface_t *fa; GL_DisableMultitexture(); - +#ifdef Q3SHADERS if (!solidskytexture&&!usingskybox) { int i; @@ -201,6 +201,7 @@ void R_DrawSkyChain (msurface_t *s) for (i = 0; i < 6; i++) skyboxtex[i] = s->texinfo->texture->shader->skydome->farbox_textures[i]; } +#endif if (r_fastsky.value||(!solidskytexture&&!usingskybox)) //this is for visability only... we'd otherwise not stoop this low (and this IS low) { diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 4125a45d..eb970892 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -210,7 +210,8 @@ typedef struct shader_s { SHADER_VIDEOMAP = 1 << 10, SHADER_DEPTHWRITE = 1 << 11, SHADER_AGEN_PORTAL = 1 << 12, - SHADER_BLEND = 1 << 13 //blend or alphatest (not 100% opaque). + SHADER_BLEND = 1 << 13, //blend or alphatest (not 100% opaque). + SHADER_NODRAW = 1 << 14 //parsed only to pee off developers when they forget it on no-pass shaders. } flags; shaderpass_t passes[SHADER_PASS_MAX]; diff --git a/engine/http/ftpclient.c b/engine/http/ftpclient.c index 3bac6cc0..ce710659 100644 --- a/engine/http/ftpclient.c +++ b/engine/http/ftpclient.c @@ -62,6 +62,9 @@ typedef struct FTPclientconn_s{ IWEBFILE *f; struct FTPclientconn_s *next; + + void (*NotifyFunction)(char *localfile, qboolean sucess); //called when failed or succeeded, and only if it got a connection in the first place. + //ftp doesn't guarentee it for anything other than getting though. :( } FTPclientconn_t; FTPclientconn_t *FTPclientconn; @@ -504,6 +507,12 @@ iwboolean FTP_ClientConnThink (FTPclientconn_t *con) //true to kill con closesocket(con->datasock); con->datasock = INVALID_SOCKET; + if (con->NotifyFunction) + { + con->NotifyFunction(con->localfile, false); + con->NotifyFunction = NULL; + } + if (con->transfersize != -1 && con->transfered != con->transfersize) { IWebPrintf("Transfer corrupt\nTransfered %i of %i bytes\n", con->transfered, con->transfersize); @@ -652,6 +661,9 @@ void FTP_ClientThink (void) { if (FTP_ClientConnThink(con)) { + if (con->NotifyFunction) + con->NotifyFunction(con->localfile, false); + if (cls.downloadmethod == DL_FTP && !strcmp(cls.downloadname, con->localfile)) { //this was us cls.downloadmethod = DL_NONE; @@ -691,7 +703,7 @@ FTPclientconn_t *FTP_FindControl(void) } return NULL; } -void FTP_Client_Command (char *cmd) +qboolean FTP_Client_Command (char *cmd, void (*NotifyFunction)(char *localfile, qboolean sucess)) { char command[64]; char server[MAX_OSPATH]; @@ -716,10 +728,14 @@ void FTP_Client_Command (char *cmd) if (cmd) Q_strncpyz(con->pwd, command, sizeof(con->pwd)); } + + return true; } else Con_Printf("FTP connect failed\n"); } + + return false; } else if (!stricmp(command, "download")) { @@ -728,8 +744,9 @@ void FTP_Client_Command (char *cmd) if (!con) { Con_Printf("FTP: Couldn't connect\n"); - return; + return false; } + con->NotifyFunction = NotifyFunction; *con->server = '\0'; con->type = ftp_getting; cmd = COM_ParseOut(cmd, server, sizeof(server)); @@ -738,6 +755,8 @@ void FTP_Client_Command (char *cmd) if ((cmd = COM_ParseOut(cmd, server, sizeof(server)))) Q_strncpyz(con->localfile, server, sizeof(con->localfile)); + + return true; } else if (!stricmp(command, "quit")) { @@ -753,6 +772,8 @@ void FTP_Client_Command (char *cmd) } else Con_Printf("No main FTP connection\n"); + + return true; } else if (!stricmp(command, "list")) { @@ -760,16 +781,18 @@ void FTP_Client_Command (char *cmd) if (!con) { Con_Printf("Not connected\n"); - return; + return false; } new = FTP_DuplicateConnection(con); if (!new) { Con_Printf("Failed duplicate connection\n"); - return; + return false; } new->type = ftp_listing; + new->NotifyFunction = NotifyFunction; + return true; } else if (!stricmp(command, "get")) { @@ -777,25 +800,27 @@ void FTP_Client_Command (char *cmd) if (!con) { Con_Printf("Not connected\n"); - return; + return false; } cmd = COM_ParseOut(cmd, command, sizeof(command)); if (!cmd) { Con_Printf("No file specified\n"); - return; + return false; } new = FTP_DuplicateConnection(con); if (!new) { Con_Printf("Failed duplicate connection\n"); - return; + return false; } + new->NotifyFunction = NotifyFunction; new->type = ftp_getting; sprintf(new->file, command); sprintf(new->localfile, "%s%s", new->path, command); + return true; } else if (!stricmp(command, "put")) { @@ -803,25 +828,28 @@ void FTP_Client_Command (char *cmd) if (!con) { Con_Printf("Not connected\n"); - return; + return false; } cmd = COM_ParseOut(cmd, command, sizeof(command)); if (!cmd) { Con_Printf("No file specified\n"); - return; + return false; } new = FTP_DuplicateConnection(con); if (!new) { Con_Printf("Failed duplicate connection\n"); - return; + return false; } + new->NotifyFunction = NotifyFunction; new->type = ftp_putting; sprintf(new->file, command); sprintf(new->localfile, "%s%s", new->path, command); + + return true; } else if (!stricmp(command, "cwd")) { @@ -829,9 +857,10 @@ void FTP_Client_Command (char *cmd) if (!con) { Con_Printf("Not connected\n"); - return; + return false; } Con_Printf("%s\n", con->path); + return true; } else if (!stricmp(command, "cd")) { @@ -840,7 +869,7 @@ void FTP_Client_Command (char *cmd) if (!con) { Con_Printf("Not connected\n"); - return; + return false; } cmd = COM_ParseOut(cmd, command, sizeof(command)); @@ -854,7 +883,8 @@ void FTP_Client_Command (char *cmd) } msg = va("CWD %s%s\r\n", con->pathprefix, con->path); - send(con->controlsock, msg, strlen(msg), 0); + if (send(con->controlsock, msg, strlen(msg), 0)==strlen(msg)) + return true; } else Con_Printf("Unrecognised FTP command\n"); @@ -863,6 +893,8 @@ void FTP_Client_Command (char *cmd) com = COM_ParseOut(com, command, sizeof(command)); com = COM_ParseOut(com, command, sizeof(command)); */ + + return false; } #endif diff --git a/engine/http/httpclient.c b/engine/http/httpclient.c index 48a2a402..11129a38 100644 --- a/engine/http/httpclient.c +++ b/engine/http/httpclient.c @@ -67,8 +67,6 @@ It doesn't use persistant connections. */ -qboolean HTTP_CL_Get(char *url, char *localfile); - typedef struct { int sock; @@ -85,6 +83,9 @@ typedef struct { int contentlength; + IWEBFILE *file; + + void (*NotifyFunction)(char *localfile, qboolean sucess); //called when failed or succeeded, and only if it got a connection in the first place. } http_con_t; static http_con_t *httpcl; @@ -213,7 +214,7 @@ static qboolean HTTP_CL_Run(http_con_t *con) if (!*Location) Con_Printf("Server redirected to null location\n"); else - HTTP_CL_Get(Location, con->filename); + HTTP_CL_Get(Location, con->filename, con->NotifyFunction); return false; } @@ -230,7 +231,22 @@ static qboolean HTTP_CL_Run(http_con_t *con) } con->bufferused -= ammount; - memmove(con->buffer, con->buffer+ammount, con->bufferused); + + con->file = IWebFOpenWrite(con->filename, false); + if (!con->file) + { + Con_Printf("HTTP: Couldn't open file %s\n", con->filename); + return false; + } + + if (!con->file) + { + IWebFWrite(con->buffer+ammount, con->bufferused, 1, con->file); + con->bufferused = 0; + } + else + memmove(con->buffer, con->buffer+ammount, con->bufferused); + con->state = HC_GETTING; @@ -291,6 +307,24 @@ static qboolean HTTP_CL_Run(http_con_t *con) con->bufferused -= trim; } } + + + if (con->file && con->chunked) //we've got a chunk in the buffer + { //write it + IWebFWrite(con->buffer, con->chunked, 1, con->file); + //and move the unparsed chunk to the front. + con->bufferused -= con->chunked; + memmove(con->buffer, con->buffer+con->chunked, con->bufferused); + con->chunked = 0; + } + } + else + { + if (con->file) //we've got a chunk in the buffer + { //write it + IWebFWrite(con->buffer, con->chunked, 1, con->file); + con->bufferused = 0; + } } if (!ammount) @@ -300,9 +334,19 @@ static qboolean HTTP_CL_Run(http_con_t *con) else if (con->bufferused != con->contentlength) Con_Printf("Recieved file isn't the correct length - must be corrupt - %s\n", con->filename); Con_Printf("Retrieved %s\n", con->filename); - snprintf(Location, sizeof(Location)-1, "%s/%s", com_gamedir, con->filename); - COM_CreatePath(Location); - COM_WriteFile(con->filename, con->buffer, con->bufferused); + if (con->file) + IWebFClose(con->file); + else + { + snprintf(Location, sizeof(Location)-1, "%s/%s", com_gamedir, con->filename); + COM_CreatePath(Location); + COM_WriteFile(con->filename, con->buffer, con->bufferused); + } + if (con->NotifyFunction) + { + con->NotifyFunction(con->filename, true); + con->NotifyFunction = NULL; + } return false; } @@ -319,6 +363,9 @@ void HTTP_CL_Think(void) { if (!HTTP_CL_Run(con)) { + if (con->NotifyFunction) + con->NotifyFunction(con->filename, false); + if (cls.downloadmethod == DL_HTTP) cls.downloadmethod = DL_NONE; closesocket(con->sock); @@ -358,7 +405,7 @@ void HTTP_CL_Think(void) } } -qboolean HTTP_CL_Get(char *url, char *localfile) +qboolean HTTP_CL_Get(char *url, char *localfile, void (*NotifyFunction)(char *localfile, qboolean sucess)) { unsigned long _true = true; struct sockaddr_qstorage from; @@ -393,8 +440,7 @@ qboolean HTTP_CL_Get(char *url, char *localfile) if (!localfile) localfile = uri+1; - FTP_Client_Command(va("download %s \"%s\" \"%s\"", server, uri+1, localfile)); - return true; + return FTP_Client_Command(va("download %s \"%s\" \"%s\"", server, uri+1, localfile), NotifyFunction); } else { @@ -458,6 +504,7 @@ qboolean HTTP_CL_Get(char *url, char *localfile) sprintf(con->buffer, "GET %s HTTP/1.1\r\n" "Host: %s\r\n" "Connection: close\r\n" "User-Agent: FTE\r\n" "\r\n", uri, server); con->bufferused = strlen(con->buffer); con->contentlength = -1; + con->NotifyFunction = NotifyFunction; strcpy(con->filename, localfile); /* slash = strchr(con->filename, '?'); diff --git a/engine/http/iweb.h b/engine/http/iweb.h index 88158662..3eecfec3 100644 --- a/engine/http/iweb.h +++ b/engine/http/iweb.h @@ -143,14 +143,14 @@ iwboolean FTP_ServerRun(iwboolean ftpserverwanted); qboolean HTTP_ServerPoll(qboolean httpserverwanted); void HTTP_CL_Think(void); -qboolean HTTP_CL_Get(char *url, char *localfile); +qboolean HTTP_CL_Get(char *url, char *localfile, void (*NotifyFunction)(char *localfile, qboolean sucess)); //server interface called from main server routines. void IWebInit(void); void IWebRun(void); void IWebShutdown(void); -void FTP_Client_Command (char *cmd); +qboolean FTP_Client_Command (char *cmd, void (*NotifyFunction)(char *localfile, qboolean sucess)); void IRC_Command(char *imsg); void FTP_ClientThink (void); void IRC_Frame(void); diff --git a/engine/nqnet/net_dgrm.c b/engine/nqnet/net_dgrm.c deleted file mode 100644 index e6214aaa..00000000 --- a/engine/nqnet/net_dgrm.c +++ /dev/null @@ -1,1717 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_dgrm.c - -#include "quakedef.h" - - -#ifdef NQPROT - -#define NET_GAMENAME_NQ "QUAKE" -#define NET_GAMENAME_QW "QUAKEWORLD" - -// This is enables a simple IP banning mechanism -//#define BAN_TEST - -#ifdef BAN_TEST -#if defined(_WIN32) -#include -#elif defined (NeXT) -#include -#include -#else -#define AF_INET 2 /* internet */ -struct in_addr -{ - union - { - struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b; - struct { unsigned short s_w1,s_w2; } S_un_w; - unsigned long S_addr; - } S_un; -}; -#define s_addr S_un.S_addr /* can be used for most tcp & ip code */ -struct sockaddr_in -{ - short sin_family; - unsigned short sin_port; - struct in_addr sin_addr; - char sin_zero[8]; -}; -char *inet_ntoa(struct in_addr in); -unsigned long inet_addr(const char *cp); -#endif -#endif // BAN_TEST - - -#include "net_dgrm.h" - -// these two macros are to make the code more readable -#define sfunc net_landrivers[sock->landriver] -#define dfunc net_landrivers[net_landriverlevel] - -static int net_landriverlevel; - -/* statistic counters */ -int packetsSent = 0; -int packetsReSent = 0; -int packetsReceived = 0; -int receivedDuplicateCount = 0; -int shortPacketCount = 0; -int droppedDatagrams; - -static int myDriverLevel; - -struct -{ - unsigned int length; - unsigned int sequence; - qbyte data[MAX_OVERALLDATAGRAM]; -} packetBuffer; - -#ifndef SERVERONLY -extern int m_return_state; -extern qboolean m_return_onerror; -extern char m_return_reason[32]; -#endif - -#ifdef DEBUG -char *StrAddr (struct qsockaddr *addr) -{ - static char buf[34]; - qbyte *p = (qbyte *)addr; - int n; - - for (n = 0; n < 16; n++) - sprintf (buf + n * 2, "%02x", *p++); - return buf; -} -#endif - - -#ifdef BAN_TEST -unsigned long banAddr = 0x00000000; -unsigned long banMask = 0xffffffff; - -void NET_Ban_f (void) -{ - char addrStr [32]; - char maskStr [32]; - - switch (Cmd_Argc ()) - { - case 1: - if (((struct in_addr *)&banAddr)->s_addr) - { - Q_strcpy(addrStr, inet_ntoa(*(struct in_addr *)&banAddr)); - Q_strcpy(maskStr, inet_ntoa(*(struct in_addr *)&banMask)); - Con_Printf("Banning %s [%s]\n", addrStr, maskStr); - } - else - Con_Printf("Banning not active\n"); - break; - - case 2: - if (Q_strcasecmp(Cmd_Argv(1), "off") == 0) - banAddr = 0x00000000; - else - banAddr = inet_addr(Cmd_Argv(1)); - banMask = 0xffffffff; - break; - - case 3: - banAddr = inet_addr(Cmd_Argv(1)); - banMask = inet_addr(Cmd_Argv(2)); - break; - - default: - Con_Printf("BAN ip_address [mask]\n"); - break; - } -} -#endif - - -int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data) -{ - unsigned int packetLen; - unsigned int dataLen; - unsigned int eom; - -#ifdef DEBUG - if (data->cursize == 0) - Sys_Error("Datagram_SendMessage: zero length message\n"); - - if (data->cursize > NET_MAXMESSAGE) - Sys_Error("Datagram_SendMessage: message too big %u\n", data->cursize); - - if (sock->canSend == false) - Sys_Error("SendMessage: called with canSend == false\n"); -#endif - - Q_memcpy(sock->sendMessage, data->data, data->cursize); - sock->sendMessageLength = data->cursize; - - if (data->cursize <= MAX_NQDATAGRAM) - { - dataLen = data->cursize; - eom = NETFLAG_EOM; - } - else - { - dataLen = MAX_NQDATAGRAM; - eom = 0; - } - packetLen = NET_HEADERSIZE + dataLen; - - packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom)); - packetBuffer.sequence = BigLong(sock->sendSequence++); - Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen); - - sock->canSend = false; - - if (sfunc.Write (sock->socket, (qbyte *)&packetBuffer, packetLen, &sock->addr) == -1) - return -1; - - sock->lastSendTime = net_time; - packetsSent++; - return 1; -} - - -int SendMessageNext (qsocket_t *sock) -{ - unsigned int packetLen; - unsigned int dataLen; - unsigned int eom; - - if (sock->sendMessageLength <= MAX_NQDATAGRAM) - { - dataLen = sock->sendMessageLength; - eom = NETFLAG_EOM; - } - else - { - dataLen = MAX_NQDATAGRAM; - eom = 0; - } - packetLen = NET_HEADERSIZE + dataLen; - - packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom)); - packetBuffer.sequence = BigLong(sock->sendSequence++); - Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen); - - sock->sendNext = false; - - if (sfunc.Write (sock->socket, (qbyte *)&packetBuffer, packetLen, &sock->addr) == -1) - return -1; - - sock->lastSendTime = net_time; - packetsSent++; - return 1; -} - - -int ReSendMessage (qsocket_t *sock) -{ - unsigned int packetLen; - unsigned int dataLen; - unsigned int eom; - - if (sock->sendMessageLength <= MAX_NQDATAGRAM) - { - dataLen = sock->sendMessageLength; - eom = NETFLAG_EOM; - } - else - { - dataLen = MAX_NQDATAGRAM; - eom = 0; - } - packetLen = NET_HEADERSIZE + dataLen; - - packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom)); - packetBuffer.sequence = BigLong(sock->sendSequence - 1); - Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen); - - sock->sendNext = false; - - if (sfunc.Write (sock->socket, (qbyte *)&packetBuffer, packetLen, &sock->addr) == -1) - return -1; - - sock->lastSendTime = net_time; - packetsReSent++; - return 1; -} - - -qboolean Datagram_CanSendMessage (qsocket_t *sock) -{ - if (sock->sendNext) - SendMessageNext (sock); - - return sock->canSend; -} - - -qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock) -{ - return true; -} - - -int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) -{ - int packetLen; - -#ifdef DEBUG - if (data->cursize == 0) - Sys_Error("Datagram_SendUnreliableMessage: zero length message\n"); - - if (data->cursize > MAX_NQDATAGRAM) - Sys_Error("Datagram_SendUnreliableMessage: message too big %u\n", data->cursize); -#endif - - packetLen = NET_HEADERSIZE + data->cursize; - - packetBuffer.length = BigLong(packetLen | NETFLAG_UNRELIABLE); - packetBuffer.sequence = BigLong(sock->unreliableSendSequence++); - Q_memcpy (packetBuffer.data, data->data, data->cursize); - - if (sfunc.Write (sock->socket, (qbyte *)&packetBuffer, packetLen, &sock->addr) == -1) - return -1; - - packetsSent++; - return 1; -} - - -int Datagram_GetMessage (qsocket_t *sock) -{ - unsigned int length; - unsigned int flags; - int ret = 0; - struct sockaddr_qstorage readaddr; - unsigned int sequence; - unsigned int count; - - if (!sock->canSend) - if ((net_time - sock->lastSendTime) > 1.0) - ReSendMessage (sock); - - for(;;) - { - length = sfunc.Read (sock->socket, (qbyte *)&packetBuffer, NET_DATAGRAMSIZE, &readaddr); - -// if ((rand() & 255) > 220) -// continue; - - if (length == 0) - break; - - if (length == -1) - { - Con_Printf("Read error\n"); - return -1; - } - - if (sfunc.AddrCompare(&readaddr, &sock->addr) != 0) - { -#ifdef DEBUG - Con_DPrintf("Forged packet received\n"); - Con_DPrintf("Expected: %s\n", StrAddr (&sock->addr)); - Con_DPrintf("Received: %s\n", StrAddr (&readaddr)); -#endif - continue; - } - - if (length < NET_HEADERSIZE) - { - shortPacketCount++; - continue; - } - - length = BigLong(packetBuffer.length); - flags = length & (~NETFLAG_LENGTH_MASK); - length &= NETFLAG_LENGTH_MASK; - - if (flags & NETFLAG_CTL) - continue; - - sequence = BigLong(packetBuffer.sequence); - packetsReceived++; - - if (flags & NETFLAG_UNRELIABLE) - { - if (sequence < sock->unreliableReceiveSequence) - { - Con_DPrintf("Got a stale datagram\n"); - ret = 0; - break; - } - if (sequence != sock->unreliableReceiveSequence) - { - count = sequence - sock->unreliableReceiveSequence; - droppedDatagrams += count; - Con_DPrintf("Dropped %u datagram(s)\n", count); - } - sock->unreliableReceiveSequence = sequence + 1; - - length -= NET_HEADERSIZE; - - SZ_Clear (&net_message); - SZ_Write (&net_message, packetBuffer.data, length); - - ret = 2; - break; - } - - if (flags & NETFLAG_ACK) - { - if (sequence != (sock->sendSequence - 1)) - { - Con_DPrintf("Stale ACK received\n"); - continue; - } - if (sequence == sock->ackSequence) - { - sock->ackSequence++; - if (sock->ackSequence != sock->sendSequence) - Con_DPrintf("ack sequencing error\n"); - } - else - { - Con_DPrintf("Duplicate ACK received\n"); - continue; - } - sock->sendMessageLength -= MAX_NQDATAGRAM; - if (sock->sendMessageLength > 0) - { - Q_memcpy(sock->sendMessage, sock->sendMessage+MAX_NQDATAGRAM, sock->sendMessageLength); - sock->sendNext = true; - } - else - { - sock->sendMessageLength = 0; - sock->canSend = true; - } - continue; - } - - if (flags & NETFLAG_DATA) - { - packetBuffer.length = BigLong(NET_HEADERSIZE | NETFLAG_ACK); - packetBuffer.sequence = BigLong(sequence); - sfunc.Write (sock->socket, (qbyte *)&packetBuffer, NET_HEADERSIZE, &readaddr); - - if (sequence != sock->receiveSequence) - { - receivedDuplicateCount++; - continue; - } - sock->receiveSequence++; - - length -= NET_HEADERSIZE; - - if (flags & NETFLAG_EOM) - { - SZ_Clear(&net_message); - SZ_Write(&net_message, sock->receiveMessage, sock->receiveMessageLength); - SZ_Write(&net_message, packetBuffer.data, length); - sock->receiveMessageLength = 0; - - ret = 1; - break; - } - - Q_memcpy(sock->receiveMessage + sock->receiveMessageLength, packetBuffer.data, length); - sock->receiveMessageLength += length; - continue; - } - } - - if (sock->sendNext) - SendMessageNext (sock); - - return ret; -} - - -void PrintStats(qsocket_t *s) -{ - Con_Printf("canSend = %4u \n", s->canSend); - Con_Printf("sendSeq = %4u ", s->sendSequence); - Con_Printf("recvSeq = %4u \n", s->receiveSequence); - Con_Printf("\n"); -} - -void NET_Stats_f (void) -{ - qsocket_t *s; - - if (Cmd_Argc () == 1) - { - Con_Printf("unreliable messages sent = %i\n", unreliableMessagesSent); - Con_Printf("unreliable messages recv = %i\n", unreliableMessagesReceived); - Con_Printf("reliable messages sent = %i\n", messagesSent); - Con_Printf("reliable messages received = %i\n", messagesReceived); - Con_Printf("packetsSent = %i\n", packetsSent); - Con_Printf("packetsReSent = %i\n", packetsReSent); - Con_Printf("packetsReceived = %i\n", packetsReceived); - Con_Printf("receivedDuplicateCount = %i\n", receivedDuplicateCount); - Con_Printf("shortPacketCount = %i\n", shortPacketCount); - Con_Printf("droppedDatagrams = %i\n", droppedDatagrams); - } - else if (Q_strcmp(Cmd_Argv(1), "*") == 0) - { - for (s = net_activeSockets; s; s = s->next) - PrintStats(s); - for (s = net_freeSockets; s; s = s->next) - PrintStats(s); - } - else - { - for (s = net_activeSockets; s; s = s->next) - if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0) - break; - if (s == NULL) - for (s = net_freeSockets; s; s = s->next) - if (Q_strcasecmp(Cmd_Argv(1), s->address) == 0) - break; - if (s == NULL) - return; - PrintStats(s); - } -} - -/* -static qboolean testInProgress = false; -static int testPollCount; -static int testDriver; -static int testSocket; - -static void Test_Poll(void *arg); -PollProcedure testPollProcedure = {NULL, 0.0, Test_Poll}; - -static void Test_Poll(void *arg) -{ - struct qsockaddr clientaddr; - int control; - int len; - char name[32]; - char address[64]; - int colors; - int frags; - int connectTime; - qbyte playerNumber; - - net_landriverlevel = testDriver; - - while (1) - { - len = dfunc.Read (testSocket, net_message.data, net_message.maxsize, &clientaddr); - if (len < sizeof(int)) - break; - - net_message.cursize = len; - - MSG_BeginReading (); - control = BigLong(*((int *)net_message.data)); - MSG_ReadLong(); - if (control == -1) - break; - if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) - break; - if ((control & NETFLAG_LENGTH_MASK) != len) - break; - - if (MSG_ReadByte() != CCREP_PLAYER_INFO) - Sys_Error("Unexpected repsonse to Player Info request\n"); - - playerNumber = MSG_ReadByte(); - Q_strcpy(name, MSG_ReadString()); - colors = MSG_ReadLong(); - frags = MSG_ReadLong(); - connectTime = MSG_ReadLong(); - Q_strcpy(address, MSG_ReadString()); - - Con_Printf("%s\n frags:%3i colors:%u %u time:%u\n %s\n", name, frags, colors >> 4, colors & 0x0f, connectTime / 60, address); - } - - testPollCount--; - if (testPollCount) - { - SchedulePollProcedure(&testPollProcedure, 0.1); - } - else - { - dfunc.CloseSocket(testSocket); - testInProgress = false; - } -} - -static void Test_f (void) -{ - char *host; - int n; - int max = MAX_SCOREBOARD; - struct qsockaddr sendaddr; - - if (testInProgress) - return; - - host = Cmd_Argv (1); - - if (host && hostCacheCount) - { - for (n = 0; n < hostCacheCount; n++) - if (Q_strcasecmp (host, hostcache[n].name) == 0) - { - if (hostcache[n].driver != myDriverLevel) - continue; - net_landriverlevel = hostcache[n].ldriver; - max = hostcache[n].maxusers; - Q_memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr)); - break; - } - if (n < hostCacheCount) - goto JustDoIt; - } - - for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) - { - if (!net_landrivers[net_landriverlevel].initialized) - continue; - - // see if we can resolve the host name - if (dfunc.GetAddrFromName(host, &sendaddr) != -1) - break; - } - if (net_landriverlevel == net_numlandrivers) - return; - -JustDoIt: - testSocket = dfunc.OpenSocket(0); - if (testSocket == -1) - return; - - testInProgress = true; - testPollCount = 20; - testDriver = net_landriverlevel; - - for (n = 0; n < max; n++) - { - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREQ_PLAYER_INFO); - MSG_WriteByte(&net_message, n); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (testSocket, net_message.data, net_message.cursize, &sendaddr); - } - SZ_Clear(&net_message); - SchedulePollProcedure(&testPollProcedure, 0.1); -} - - -static qboolean test2InProgress = false; -static int test2Driver; -static int test2Socket; - -static void Test2_Poll(void *arg); -PollProcedure test2PollProcedure = {NULL, 0.0, Test2_Poll}; - -static void Test2_Poll(void *arg) -{ - struct qsockaddr clientaddr; - int control; - int len; - char name[256]; - char value[256]; - - net_landriverlevel = test2Driver; - name[0] = 0; - - len = dfunc.Read (test2Socket, net_message.data, net_message.maxsize, &clientaddr); - if (len < sizeof(int)) - goto Reschedule; - - net_message.cursize = len; - - MSG_BeginReading (); - control = BigLong(*((int *)net_message.data)); - MSG_ReadLong(); - if (control == -1) - goto Error; - if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) - goto Error; - if ((control & NETFLAG_LENGTH_MASK) != len) - goto Error; - - if (MSG_ReadByte() != CCREP_RULE_INFO) - goto Error; - - Q_strcpy(name, MSG_ReadString()); - if (name[0] == 0) - goto Done; - Q_strcpy(value, MSG_ReadString()); - - Con_Printf("%-16.16s %-16.16s\n", name, value); - - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREQ_RULE_INFO); - MSG_WriteString(&net_message, name); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (test2Socket, net_message.data, net_message.cursize, &clientaddr); - SZ_Clear(&net_message); - -Reschedule: - SchedulePollProcedure(&test2PollProcedure, 0.05); - return; - -Error: - Con_Printf("Unexpected repsonse to Rule Info request\n"); -Done: - dfunc.CloseSocket(test2Socket); - test2InProgress = false; - return; -} - -static void Test2_f (void) -{ - char *host; - int n; - struct qsockaddr sendaddr; - - if (test2InProgress) - return; - - host = Cmd_Argv (1); - - if (host && hostCacheCount) - { - for (n = 0; n < hostCacheCount; n++) - if (Q_strcasecmp (host, hostcache[n].name) == 0) - { - if (hostcache[n].driver != myDriverLevel) - continue; - net_landriverlevel = hostcache[n].ldriver; - Q_memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr)); - break; - } - if (n < hostCacheCount) - goto JustDoIt; - } - - for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) - { - if (!net_landrivers[net_landriverlevel].initialized) - continue; - - // see if we can resolve the host name - if (dfunc.GetAddrFromName(host, &sendaddr) != -1) - break; - } - if (net_landriverlevel == net_numlandrivers) - return; - -JustDoIt: - test2Socket = dfunc.OpenSocket(0); - if (test2Socket == -1) - return; - - test2InProgress = true; - test2Driver = net_landriverlevel; - - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREQ_RULE_INFO); - MSG_WriteString(&net_message, ""); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (test2Socket, net_message.data, net_message.cursize, &sendaddr); - SZ_Clear(&net_message); - SchedulePollProcedure(&test2PollProcedure, 0.05); -} -*/ - -int Datagram_Init (void) -{ - int i; - int csock; - - myDriverLevel = net_driverlevel; - Cmd_AddCommand ("net_stats", NET_Stats_f); - - if (COM_CheckParm("-nolan")) - return -1; - - for (i = 0; i < net_numlandrivers; i++) - { - csock = net_landrivers[i].Init (); - if (csock == -1) - continue; - net_landrivers[i].initialized = true; - net_landrivers[i].controlSock = csock; - } - -#ifdef BAN_TEST - Cmd_AddCommand ("ban", NET_Ban_f); -#endif -// Cmd_AddCommand ("test", Test_f); -// Cmd_AddCommand ("test2", Test2_f); - - return 0; -} - - -void Datagram_Shutdown (void) -{ - int i; - -// -// shutdown the lan drivers -// - for (i = 0; i < net_numlandrivers; i++) - { - if (net_landrivers[i].initialized) - { - net_landrivers[i].Shutdown (); - net_landrivers[i].initialized = false; - } - } -} - - -void Datagram_Close (qsocket_t *sock) -{ - sfunc.CloseSocket(sock->socket); -} - - -void Datagram_Listen (qboolean state) -{ -#ifndef CLIENTONLY - int i; - - for (i = 0; i < net_numlandrivers; i++) - if (net_landrivers[i].initialized) - net_landrivers[i].Listen (state); -#endif -} - -#ifndef CLIENTONLY -static qsocket_t *_Datagram_CheckNewConnections (void) -{ - struct sockaddr_qstorage clientaddr; - struct sockaddr_qstorage newaddr; - int newsock; - int acceptsock; - qsocket_t *sock; - qsocket_t *s; - int len; - int command; - int control; - int ret; -#ifdef NET_GAMENAME_QW - char *gname; -#endif - - acceptsock = dfunc.CheckNewConnections(); - if (acceptsock == -1) - return NULL; - - SZ_Clear(&net_message); - - len = dfunc.Read (acceptsock, net_message.data, net_message.maxsize, &clientaddr); - if (len < sizeof(int)) - return NULL; - net_message.cursize = len; - - MSG_BeginReading (); - control = BigLong(*((int *)net_message.data)); - MSG_ReadLong(); - if (control == -1) - return NULL; - if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) - return NULL; - if ((control & NETFLAG_LENGTH_MASK) != len) - return NULL; - - command = MSG_ReadByte(); - if (command == CCREQ_SERVER_INFO) - { - int numcl; - -#ifdef NET_GAMENAME_QW - gname = MSG_ReadString(); - if (Q_strcmp(gname, NET_GAMENAME_QW)) - if (Q_strcmp(gname, NET_GAMENAME_NQ) ) - return NULL; -#else - if (Q_strcmp(MSG_ReadString(), NET_GAMENAME_NQ) != 0) - return NULL; -#endif - - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREP_SERVER_INFO); - dfunc.GetSocketAddr(acceptsock, &newaddr); - MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr)); - MSG_WriteString(&net_message, hostname.string); - MSG_WriteString(&net_message, sv.name); - numcl = 0; - for (len = 0; len < MAX_CLIENTS; len++) - { - if(svs.clients[len].state>cs_zombie || *svs.clients[len].name) //client or bot. - numcl++; - } - MSG_WriteByte(&net_message, numcl); - MSG_WriteByte(&net_message, sv.allocated_client_slots); - MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); - SZ_Clear(&net_message); - return NULL; - } - - if (command == CCREQ_PLAYER_INFO) - { - int playerNumber; - int activeNumber; - int clientNumber; - client_t *client; - - playerNumber = MSG_ReadByte(); - activeNumber = -1; - for (clientNumber = 0, client = svs.clients; clientNumber < sv.allocated_client_slots; clientNumber++, client++) - { - if (client->state>cs_zombie || *svs.clients[len].name) - { - activeNumber++; - if (activeNumber == playerNumber) - break; - } - } - if (clientNumber == sv.allocated_client_slots) - return NULL; - - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREP_PLAYER_INFO); - MSG_WriteByte(&net_message, playerNumber); - MSG_WriteString(&net_message, client->name); - MSG_WriteLong(&net_message, 0); - MSG_WriteLong(&net_message, (int)client->old_frags); - MSG_WriteLong(&net_message, (int)(net_time - client->connection_started)); - MSG_WriteString(&net_message, "WITHHELD"); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); - SZ_Clear(&net_message); - - return NULL; - } - - if (command == CCREQ_RULE_INFO) - { - extern cvar_group_t cvargroup_serverinfo; - char *prevCvarName; - cvar_t *var; - - // find the search start location - prevCvarName = MSG_ReadString(); - if (*prevCvarName) - { - var = Cvar_FindVar (prevCvarName); - if (!var) - return NULL; - var = var->next; - } - else - var = cvargroup_serverinfo.cvars; - - // search for the next server cvar - while (var) - { - if (var->flags&CVAR_SERVERINFO) - break; - var = var->next; - } - - // send the response - - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREP_RULE_INFO); - if (var) - { - MSG_WriteString(&net_message, var->name); - MSG_WriteString(&net_message, var->string); - } - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); - SZ_Clear(&net_message); - - return NULL; - } - - if (command != CCREQ_CONNECT) - return NULL; - -#ifdef NET_GAMENAME_QW - gname = MSG_ReadString(); - if (Q_strcmp(gname, NET_GAMENAME_QW)) - if (Q_strcmp(gname, NET_GAMENAME_NQ) ) - return NULL; -#else - if (Q_strcmp(MSG_ReadString(), NET_GAMENAME_NQ) != 0) - return NULL; -#endif - - if (MSG_ReadByte() != NET_PROTOCOL_VERSION) - { - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREP_REJECT); - MSG_WriteString(&net_message, "Incompatible version.\n"); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); - SZ_Clear(&net_message); - return NULL; - } - -#ifdef BAN_TEST - // check for a ban - if (((struct sockaddr_in*)clientaddr).sa_family == AF_INET) - { - unsigned long testAddr; - testAddr = ((struct sockaddr_in *)&clientaddr)->sin_addr.s_addr; - if ((testAddr & banMask) == banAddr) - { - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREP_REJECT); - MSG_WriteString(&net_message, "You have been banned.\n"); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); - SZ_Clear(&net_message); - return NULL; - } - } -#endif - - // see if this guy is already connected - for (s = net_activeSockets; s; s = s->next) - { - if (s->driver != net_driverlevel) - continue; - ret = dfunc.AddrCompare(&clientaddr, &s->addr); - if (ret >= 0) - { - // is this a duplicate connection reqeust? - if (ret == 0 && net_time - s->connecttime < 2.0) - { - // yes, so send a duplicate reply - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREP_ACCEPT); - dfunc.GetSocketAddr(s->socket, &newaddr); - MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr)); - MSG_WriteString(&net_message, gname); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); - SZ_Clear(&net_message); - return NULL; - } - // it's somebody coming back in from a crash/disconnect - // so close the old qsocket and let their retry get them back in - NET_Close(s); - return NULL; - } - } - - // allocate a QSocket - sock = NET_NewQSocket (); - if (sock == NULL) - { - // no room; try to let him know - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREP_REJECT); - MSG_WriteString(&net_message, "Server is full.\n"); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); - SZ_Clear(&net_message); - return NULL; - } - - if (!Q_strcmp(gname, NET_GAMENAME_QW)) - sock->qwprotocol = true; - - // allocate a network socket - newsock = dfunc.OpenSocket(0); - if (newsock == -1) - { - NET_FreeQSocket(sock); - return NULL; - } - - // connect to the client - if (dfunc.Connect (newsock, &clientaddr) == -1) - { - dfunc.CloseSocket(newsock); - NET_FreeQSocket(sock); - return NULL; - } - - // everything is allocated, just fill in the details - sock->socket = newsock; - sock->landriver = net_landriverlevel; - sock->addr = clientaddr; - Q_strcpy(sock->address, dfunc.AddrToString(&clientaddr)); - - // send him back the info about the server connection he has been allocated - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREP_ACCEPT); - dfunc.GetSocketAddr(newsock, &newaddr); - MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr)); - MSG_WriteString(&net_message, gname); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); - SZ_Clear(&net_message); - - return sock; -} - -qsocket_t *Datagram_CheckNewConnections (void) -{ - qsocket_t *ret = NULL; - - for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) - if (net_landrivers[net_landriverlevel].initialized) - if ((ret = _Datagram_CheckNewConnections ()) != NULL) - break; - return ret; -} -#else -qsocket_t *Datagram_CheckNewConnections (void) -{ - return NULL; //client only can't. -} -#endif - -static void _Datagram_SearchForHosts (qboolean xmit) -{ - int ret; - int n; - int i; - struct sockaddr_qstorage readaddr; - struct sockaddr_qstorage myaddr; - int control; - - dfunc.GetSocketAddr (dfunc.controlSock, &myaddr); - if (xmit) - { - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREQ_SERVER_INFO); - MSG_WriteString(&net_message, NET_GAMENAME_QW); - MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Broadcast(dfunc.controlSock, net_message.data, net_message.cursize); - SZ_Clear(&net_message); - - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREQ_SERVER_INFO); - MSG_WriteString(&net_message, NET_GAMENAME_NQ); //look for either sort of server - MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Broadcast(dfunc.controlSock, net_message.data, net_message.cursize); - SZ_Clear(&net_message); - } - - while ((ret = dfunc.Read (dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0) - { - if (ret < sizeof(int)) - continue; - net_message.cursize = ret; - - // don't answer our own query -// if (dfunc.AddrCompare(&readaddr, &myaddr) >= 0) -// continue; - - // is the cache full? - if (hostCacheCount == HOSTCACHESIZE) - continue; - - MSG_BeginReading (); - control = BigLong(*((int *)net_message.data)); - MSG_ReadLong(); - if (control == -1) - continue; - if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) - continue; - if ((control & NETFLAG_LENGTH_MASK) != ret) - continue; - - if (MSG_ReadByte() != CCREP_SERVER_INFO) - continue; - - dfunc.GetAddrFromName(MSG_ReadString(), &readaddr); - // search the cache for this server - for (n = 0; n < hostCacheCount; n++) - if (dfunc.AddrCompare(&readaddr, &hostcache[n].addr) == 0) - break; - - // is it already there? - if (n < hostCacheCount) - continue; - - // add it - hostCacheCount++; - Q_strncpyz(hostcache[n].name, MSG_ReadString(), sizeof(hostcache[n].name)); - Q_strncpyz(hostcache[n].map, MSG_ReadString(), sizeof(hostcache[n].map)); - hostcache[n].users = MSG_ReadByte(); - hostcache[n].maxusers = MSG_ReadByte(); - if (MSG_ReadByte() != NET_PROTOCOL_VERSION) - { - Q_strcpy(hostcache[n].cname, hostcache[n].name); - hostcache[n].cname[14] = 0; - Q_strcpy(hostcache[n].name, "*"); - Q_strcat(hostcache[n].name, hostcache[n].cname); - } - Q_memcpy(&hostcache[n].addr, &readaddr, sizeof(struct sockaddr_qstorage)); - hostcache[n].driver = net_driverlevel; - hostcache[n].ldriver = net_landriverlevel; - Q_strcpy(hostcache[n].cname, dfunc.AddrToString(&readaddr)); - - // check for a name conflict - for (i = 0; i < hostCacheCount; i++) - { - if (i == n) - continue; - if (Q_strcasecmp (hostcache[n].name, hostcache[i].name) == 0) - { - i = Q_strlen(hostcache[n].name); - if (i < 15 && hostcache[n].name[i-1] > '8') - { - hostcache[n].name[i] = '0'; - hostcache[n].name[i+1] = 0; - } - else - hostcache[n].name[i-1]++; - i = -1; - } - } - } -} - -void Datagram_SearchForHosts (qboolean xmit) -{ - for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) - { - if (hostCacheCount == HOSTCACHESIZE) - break; - if (net_landrivers[net_landriverlevel].initialized) - _Datagram_SearchForHosts (xmit); - } -} - -#ifndef SERVERONLY -qsocket_t *Datagram_ConnectToDarkPlacesServer(netadr_t *nadr) -{ //QuakeWorld connection hit upon a DP server. - struct sockaddr_qstorage sendaddr; - qsocket_t *sock; - int newsock; - - net_driverlevel = 1; - net_landriverlevel = 0; - - //hrm. the server uses out port as well as ip... we connected with the qw port... so we need to swap them over - newsock = cls.socketip; - cls.socketip = dfunc.OpenSocket(0); - if (newsock == -1) - { - cls.socketip = newsock; - Con_Printf("Failed to initialse NQ transports\n"); - return NULL; - } - - sock = NET_NewQSocket (); - if (sock == NULL) - { - Con_Printf("Failed to initialse NQ transports\n"); - dfunc.CloseSocket(newsock); - return NULL; - } - - sock->socket = newsock; - sock->landriver = net_landriverlevel; - - NetadrToSockadr(nadr, &sendaddr); - - if (dfunc.Connect(newsock, &sendaddr) == -1) - { - Con_Printf("Failed to initialse NQ transports\n"); - NET_FreeQSocket(sock); - dfunc.CloseSocket(newsock); - return NULL; - } - - Q_memcpy(&sock->addr, &sendaddr, sizeof(struct sockaddr_qstorage)); - - dfunc.GetNameFromAddr (&sendaddr, sock->address); - Con_Printf ("Connection accepted\n"); - sock->lastMessageTime = SetNetTime(); - - return sock; -} - -static qsocket_t *_Datagram_Connect (char *host) -{ - struct sockaddr_qstorage sendaddr; - struct sockaddr_qstorage readaddr; - qsocket_t *sock; - int newsock; - int ret=0; - int reps; - double start_time; - int control; - char *reason; - - // see if we can resolve the host name - if (dfunc.GetAddrFromName(host, &sendaddr) == -1) - return NULL; - - newsock = dfunc.OpenSocket (0); - if (newsock == -1) - return NULL; - - sock = NET_NewQSocket (); - if (sock == NULL) - goto ErrorReturn2; - sock->socket = newsock; - sock->landriver = net_landriverlevel; - - // connect to the host - if (dfunc.Connect (newsock, &sendaddr) == -1) - goto ErrorReturn; - - // send the connection request - Con_Printf("trying...\n"); SCR_UpdateScreen (); - start_time = net_time; - - for (reps = 0; reps < 3; reps++) - { - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREQ_CONNECT); - MSG_WriteString(&net_message, NET_GAMENAME_QW); - MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (newsock, net_message.data, net_message.cursize, &sendaddr); - SZ_Clear(&net_message); - - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREQ_CONNECT); - MSG_WriteString(&net_message, NET_GAMENAME_NQ); //eitehr will do - MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (newsock, net_message.data, net_message.cursize, &sendaddr); - SZ_Clear(&net_message); - -/* { - int s = sock->landriver, d = net_landriverlevel; - SVNQ_CheckForNewClients(); - net_landriverlevel = d; - sock->landriver = s; - } -*/ - do - { - ret = dfunc.Read (newsock, net_message.data, net_message.maxsize, &readaddr); - // if we got something, validate it - if (ret > 0) - { - // is it from the right place? - if (sfunc.AddrCompare(&readaddr, &sendaddr) != 0) - { -#ifdef DEBUG - Con_Printf("wrong reply address\n"); - Con_Printf("Expected: %s\n", StrAddr (&sendaddr)); - Con_Printf("Received: %s\n", StrAddr (&readaddr)); - SCR_UpdateScreen (); -#endif - ret = 0; - continue; - } - - if (ret < sizeof(int)) - { - ret = 0; - continue; - } - - net_message.cursize = ret; - MSG_BeginReading (); - - control = BigLong(*((int *)net_message.data)); - MSG_ReadLong(); - if (control == -1) - { - ret = 0; - continue; - } - if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) - { - ret = 0; - continue; - } - if ((control & NETFLAG_LENGTH_MASK) != ret) - { - ret = 0; - continue; - } - } - } - while (ret == 0 && (SetNetTime() - start_time) < 2.5); - if (ret) - break; - Con_Printf("still trying...\n"); SCR_UpdateScreen (); - start_time = SetNetTime(); - } - - if (ret == 0) - { - reason = "No Response"; - Con_Printf("%s\n", reason); - Q_strcpy(m_return_reason, reason); - goto ErrorReturn; - } - - if (ret == -1) - { - reason = "Network Error"; - Con_Printf("%s\n", reason); - Q_strcpy(m_return_reason, reason); - goto ErrorReturn; - } - - ret = MSG_ReadByte(); - if (ret == CCREP_REJECT) - { - reason = MSG_ReadString(); - Con_Printf(reason); - Q_strncpyz(m_return_reason, reason, sizeof(m_return_reason)); - goto ErrorReturn; - } - - if (ret == CCREP_ACCEPT) - { - Q_memcpy(&sock->addr, &sendaddr, sizeof(struct sockaddr_qstorage)); - dfunc.SetSocketPort (&sock->addr, MSG_ReadLong()); - if (!Q_strcmp(NET_GAMENAME_QW, MSG_ReadString())) - sock->qwprotocol = true; - } - else - { - reason = "Bad Response"; - Con_Printf("%s\n", reason); - Q_strcpy(m_return_reason, reason); - goto ErrorReturn; - } - - dfunc.GetNameFromAddr (&sendaddr, sock->address); - - Con_Printf ("Connection accepted\n"); - sock->lastMessageTime = SetNetTime(); - - // switch the connection to the specified address - if (dfunc.Connect (newsock, &sock->addr) == -1) - { - reason = "Connect to Game failed"; - Con_Printf("%s\n", reason); - Q_strcpy(m_return_reason, reason); - goto ErrorReturn; - } - - m_return_onerror = false; - return sock; - -ErrorReturn: - NET_FreeQSocket(sock); -ErrorReturn2: - dfunc.CloseSocket(newsock); - if (m_return_onerror) - { - key_dest = key_menu; - m_state = m_return_state; - m_return_onerror = false; - } - return NULL; -} -static int newsock; -static qsocket_t *sock; -static qsocket_t *_Datagram_FailConnect (char *host) -{ - if (sock) - NET_Close(sock); -// NET_FreeQSocket(sock); - - if (!newsock) - return NULL; - - dfunc.CloseSocket(newsock); - if (m_return_onerror) - { - key_dest = key_menu; - m_state = m_return_state; - m_return_onerror = false; - } - - sock = NULL; - - return NULL; -} -static qsocket_t *_Datagram_ContinueConnect (char *host) -{ - struct sockaddr_qstorage sendaddr; - struct sockaddr_qstorage readaddr; - int ret; -// int reps; - int control; - char *reason; - - // see if we can resolve the host name - if (!sock || dfunc.GetAddrFromName(host, &sendaddr) == -1) - return NULL; - - - do - { - ret = dfunc.Read (newsock, net_message.data, net_message.maxsize, &readaddr); - // if we got something, validate it - if (ret > 0) - { - // is it from the right place? - if (sfunc.AddrCompare(&readaddr, &sendaddr) != 0) - { -#ifdef DEBUG - Con_Printf("wrong reply address\n"); - Con_Printf("Expected: %s\n", StrAddr (&sendaddr)); - Con_Printf("Received: %s\n", StrAddr (&readaddr)); - SCR_UpdateScreen (); -#endif - ret = 0; - continue; - } - - if (ret < sizeof(int)) - { - ret = 0; - continue; - } - - net_message.cursize = ret; - MSG_BeginReading (); - - control = BigLong(*((int *)net_message.data)); - MSG_ReadLong(); - if (control == -1) - { - ret = 0; - continue; - } - if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) - { - ret = 0; - continue; - } - if ((control & NETFLAG_LENGTH_MASK) != ret) - { - ret = 0; - continue; - } - break; - } - } - while (ret > 0); - - - if (ret == 0) - { - reason = "No Response"; -// Con_Printf("%s\n", reason); - Q_strcpy(m_return_reason, reason); - return NULL; - } - - if (ret == -1) - { - reason = "Network Error"; -// Con_Printf("%s\n", reason); - Q_strcpy(m_return_reason, reason); - return _Datagram_FailConnect(host); - } - - ret = MSG_ReadByte(); - if (ret == CCREP_REJECT) - { - reason = MSG_ReadString(); - Con_Printf(reason); - Q_strncpyz(m_return_reason, reason, sizeof(m_return_reason)); - return _Datagram_FailConnect(host); - } - - if (ret == CCREP_ACCEPT) - { - Q_memcpy(&sock->addr, &sendaddr, sizeof(struct sockaddr_qstorage)); - dfunc.SetSocketPort (&sock->addr, MSG_ReadLong()); - if (!Q_strcmp(NET_GAMENAME_QW, MSG_ReadString())) - sock->qwprotocol = true; - } - else - { - reason = "Bad Response"; - Con_Printf("%s\n", reason); - Q_strcpy(m_return_reason, reason); - return _Datagram_FailConnect(host); - } - - dfunc.GetNameFromAddr (&sendaddr, sock->address); - - Con_Printf ("Connection accepted\n"); - sock->lastMessageTime = SetNetTime(); - - // switch the connection to the specified address - if (dfunc.Connect (newsock, &sock->addr) == -1) - { - reason = "Connect to Game failed"; - Con_Printf("%s\n", reason); - Q_strcpy(m_return_reason, reason); - return _Datagram_FailConnect(host); - } - - m_return_onerror = false; - return sock; -} -static qsocket_t *_Datagram_BeginConnect (char *host) -{ - struct sockaddr_qstorage sendaddr; - double start_time; - - // see if we can resolve the host name - if (dfunc.GetAddrFromName(host, &sendaddr) == -1) - return NULL; - - sock = _Datagram_ContinueConnect(host); - if (sock) - return sock; - - newsock = dfunc.OpenSocket (0); - if (newsock == -1) - return _Datagram_FailConnect(host); - - sock = NET_NewQSocket (); - if (sock == NULL) - return _Datagram_FailConnect(host); - sock->socket = newsock; - sock->landriver = net_landriverlevel; - - // connect to the host - if (dfunc.Connect (newsock, &sendaddr) == -1) - { - return _Datagram_FailConnect(host); - } - - // send the connection request - Con_Printf("trying...\n"); - start_time = net_time; - - SZ_Clear(&net_message); - // save space for the header, filled in later - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREQ_CONNECT); - MSG_WriteString(&net_message, NET_GAMENAME_QW); - MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (newsock, net_message.data, net_message.cursize, &sendaddr); - SZ_Clear(&net_message); - - MSG_WriteLong(&net_message, 0); - MSG_WriteByte(&net_message, CCREQ_CONNECT); - MSG_WriteString(&net_message, NET_GAMENAME_NQ); //either will do - MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); - *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); - dfunc.Write (newsock, net_message.data, net_message.cursize, &sendaddr); - SZ_Clear(&net_message); - - return NULL; -} -#endif -qsocket_t *Datagram_BeginConnect (char *host) -{ - qsocket_t *ret = NULL; -#ifndef SERVERONLY - for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) - if (net_landrivers[net_landriverlevel].initialized) - if ((ret = _Datagram_BeginConnect (host)) != NULL) - break; -#endif - return ret; -} -qsocket_t *Datagram_ContinueConnect (char *host) -{ - qsocket_t *ret = NULL; -#ifndef SERVERONLY - for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) - if (net_landrivers[net_landriverlevel].initialized) - if ((ret = _Datagram_ContinueConnect (host)) != NULL) - break; -#endif - return ret; -} -qsocket_t *Datagram_Connect (char *host) -{ - qsocket_t *ret = NULL; -#ifndef SERVERONLY - for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) - if (net_landrivers[net_landriverlevel].initialized) - if ((ret = _Datagram_Connect (host)) != NULL) - break; -#endif - return ret; -} -#endif - diff --git a/engine/nqnet/net_dgrm.h b/engine/nqnet/net_dgrm.h deleted file mode 100644 index dde77a53..00000000 --- a/engine/nqnet/net_dgrm.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_dgrm.h - - -int Datagram_Init (void); -void Datagram_Listen (qboolean state); -void Datagram_SearchForHosts (qboolean xmit); -qsocket_t *Datagram_Connect (char *host); -qsocket_t *Datagram_CheckNewConnections (void); -int Datagram_GetMessage (qsocket_t *sock); -int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data); -int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data); -qboolean Datagram_CanSendMessage (qsocket_t *sock); -qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock); -void Datagram_Close (qsocket_t *sock); -void Datagram_Shutdown (void); - -qsocket_t *Datagram_BeginConnect (char *host); -qsocket_t *Datagram_ContinueConnect (char *host); diff --git a/engine/nqnet/net_loop.c b/engine/nqnet/net_loop.c deleted file mode 100644 index a03b2ccf..00000000 --- a/engine/nqnet/net_loop.c +++ /dev/null @@ -1,268 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_loop.c - -#include "quakedef.h" - -#if !(defined(CLIENTONLY) || defined(SERVERONLY)) -#ifdef NQPROT -#include "net_loop.h" - -qboolean localconnectpending = false; -qsocket_t *loop_client = NULL; -qsocket_t *loop_server = NULL; - -int Loop_Init (void) -{ - if (isDedicated) - return -1; -// if (cls.state == ca_dedicated) -// return -1; - return 0; -} - - -void Loop_Shutdown (void) -{ -} - - -void Loop_Listen (qboolean state) -{ -} - - -void Loop_SearchForHosts (qboolean xmit) -{ - if (!sv.active) - return; - - hostCacheCount = 1; - if (Q_strcmp(hostname.string, "UNNAMED") == 0) - Q_strcpy(hostcache[0].name, "local"); - else - Q_strcpy(hostcache[0].name, hostname.string); - Q_strcpy(hostcache[0].map, sv.name); - hostcache[0].users = net_activeconnections; - hostcache[0].maxusers = 32; - hostcache[0].driver = net_driverlevel; - Q_strcpy(hostcache[0].cname, "local"); -} - - -qsocket_t *Loop_Connect (char *host) -{ - if (Q_strcmp(host,"local") != 0) - return NULL; - - if (localconnectpending && loop_client && loop_server) - return loop_client; - - if (!loop_client) - { - if ((loop_client = NET_NewQSocket ()) == NULL) - { - Con_Printf("Loop_Connect: no qsocket available\n"); - return NULL; - } - Q_strcpy (loop_client->address, "localhost"); - } - else - loop_client->disconnected = false; - loop_client->receiveMessageLength = 0; - loop_client->sendMessageLength = 0; - loop_client->canSend = true; - - if (!loop_server) - { - if ((loop_server = NET_NewQSocket ()) == NULL) - { - Con_Printf("Loop_Connect: no qsocket available\n"); - return NULL; - } - Q_strcpy (loop_server->address, "LOCAL"); - } - else - loop_server->disconnected = false; - loop_server->receiveMessageLength = 0; - loop_server->sendMessageLength = 0; - loop_server->canSend = true; - - loop_client->driverdata = (void *)loop_server; - loop_server->driverdata = (void *)loop_client; - - loop_server->qwprotocol = loop_client->qwprotocol = true; - - localconnectpending = true; - - return loop_client; -} - - -qsocket_t *Loop_CheckNewConnections (void) -{ - if (!localconnectpending || !loop_server || !loop_client) - return NULL; - - localconnectpending = false; - loop_server->sendMessageLength = 0; - loop_server->receiveMessageLength = 0; - loop_server->canSend = true; - loop_client->sendMessageLength = 0; - loop_client->receiveMessageLength = 0; - loop_client->canSend = true; - return loop_server; -} - - -static int IntAlign(int value) -{ - return (value + (sizeof(int) - 1)) & (~(sizeof(int) - 1)); -} - - -int Loop_GetMessage (qsocket_t *sock) -{ - int ret; - int length; - - if (sock->receiveMessageLength == 0) - return 0; - - ret = sock->receiveMessage[0]; - length = sock->receiveMessage[1] + (sock->receiveMessage[2] << 8); - // alignment qbyte skipped here - SZ_Clear (&net_message); - SZ_Write (&net_message, &sock->receiveMessage[4], length); - - length = IntAlign(length + 4); - sock->receiveMessageLength -= length; - - if (sock->receiveMessageLength) - Q_memcpy(sock->receiveMessage, &sock->receiveMessage[length], sock->receiveMessageLength); - - if (sock->driverdata && ret == 1) - ((qsocket_t *)sock->driverdata)->canSend = true; - - return ret; -} - - -int Loop_SendMessage (qsocket_t *sock, sizebuf_t *data) -{ - qbyte *buffer; - int *bufferLength; - - if (!sock->driverdata) - return -1; - - bufferLength = &((qsocket_t *)sock->driverdata)->receiveMessageLength; - - if ((*bufferLength + data->cursize + 4) > NET_MAXMESSAGE) - Sys_Error("Loop_SendMessage: overflow\n"); - - buffer = ((qsocket_t *)sock->driverdata)->receiveMessage + *bufferLength; - - // message type - *buffer++ = 1; - - // length - *buffer++ = data->cursize & 0xff; - *buffer++ = data->cursize >> 8; - - // align - buffer++; - - // message - Q_memcpy(buffer, data->data, data->cursize); - *bufferLength = IntAlign(*bufferLength + data->cursize + 4); - - sock->canSend = false; - return 1; -} - - -int Loop_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) -{ - qbyte *buffer; - int *bufferLength; - - if (!sock->driverdata) - return -1; - - bufferLength = &((qsocket_t *)sock->driverdata)->receiveMessageLength; - - if ((*bufferLength + data->cursize + sizeof(qbyte) + sizeof(short)) > NET_MAXMESSAGE) - return 0; - - buffer = ((qsocket_t *)sock->driverdata)->receiveMessage + *bufferLength; - - // message type - *buffer++ = 2; - - // length - *buffer++ = data->cursize & 0xff; - *buffer++ = data->cursize >> 8; - - // align - buffer++; - - // message - Q_memcpy(buffer, data->data, data->cursize); - *bufferLength = IntAlign(*bufferLength + data->cursize + 4); - return 1; -} - - -qboolean Loop_CanSendMessage (qsocket_t *sock) -{ - if (!sock->driverdata) - return false; - return sock->canSend; -} - - -qboolean Loop_CanSendUnreliableMessage (qsocket_t *sock) -{ - return true; -} - - -void Loop_Close (qsocket_t *sock) -{ - localconnectpending = false; - - if (sock->driverdata) - ((qsocket_t *)sock->driverdata)->driverdata = NULL; - sock->receiveMessageLength = 0; - sock->sendMessageLength = 0; - sock->canSend = true; - if (sock == loop_client) - loop_client = NULL; - else - loop_server = NULL; - - if (loop_server) - loop_server->disconnected=2; - else if (loop_client) - loop_client->disconnected=2; -} -#endif -#endif diff --git a/engine/nqnet/net_loop.h b/engine/nqnet/net_loop.h deleted file mode 100644 index 1629f708..00000000 --- a/engine/nqnet/net_loop.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_loop.h - -#if !defined(SERVERONLY) && !defined(CLIENTONLY) - -int Loop_Init (void); -void Loop_Listen (qboolean state); -void Loop_SearchForHosts (qboolean xmit); -qsocket_t *Loop_Connect (char *host); -qsocket_t *Loop_CheckNewConnections (void); -int Loop_GetMessage (qsocket_t *sock); -int Loop_SendMessage (qsocket_t *sock, sizebuf_t *data); -int Loop_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data); -qboolean Loop_CanSendMessage (qsocket_t *sock); -qboolean Loop_CanSendUnreliableMessage (qsocket_t *sock); -void Loop_Close (qsocket_t *sock); -void Loop_Shutdown (void); - -#endif diff --git a/engine/nqnet/net_main.c b/engine/nqnet/net_main.c deleted file mode 100644 index 2c5b63a5..00000000 --- a/engine/nqnet/net_main.c +++ /dev/null @@ -1,1004 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_main.c - -#include "quakedef.h" - -#define NOCOM -#ifdef NQPROT - - -#define Sys_FloatTime Sys_DoubleTime - -qsocket_t *net_activeSockets = NULL; -qsocket_t *net_freeSockets = NULL; -int net_numsockets = 0; - -#ifndef NOCOM -qboolean serialAvailable = false; -#endif -qboolean ipxAvailable = false; -qboolean tcpipAvailable = false; - -int net_hostport; -int DEFAULTnet_hostport = 26000; - -char my_ipx_address[NET_NAMELEN]; -char my_tcpip_address[NET_NAMELEN]; - -#ifndef NOCOM -void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem); -void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem); -void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); -void (*SetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); -#endif - -static qboolean listening = false; - -qboolean slistInProgress = false; -qboolean slistSilent = false; -qboolean slistLocal = true; -static double slistStartTime; -static int slistLastShown; - -static void Slist_Send(void *arg); -static void Slist_Poll(void *arg); -PollProcedure slistSendProcedure = {NULL, 0.0, Slist_Send}; -PollProcedure slistPollProcedure = {NULL, 0.0, Slist_Poll}; - - -extern sizebuf_t net_message; -int net_activeconnections = 0; - -int messagesSent = 0; -int messagesReceived = 0; -int unreliableMessagesSent = 0; -int unreliableMessagesReceived = 0; - -cvar_t net_messagetimeout = {"net_messagetimeout","300"}; - -#ifndef NOCOM -qboolean configRestored = false; -cvar_t config_com_port = {"_config_com_port", "0x3f8", CVAR_ARCHIVE}; -cvar_t config_com_irq = {"_config_com_irq", "4", CVAR_ARCHIVE}; -cvar_t config_com_baud = {"_config_com_baud", "57600", CVAR_ARCHIVE}; -cvar_t config_com_modem = {"_config_com_modem", "1", CVAR_ARCHIVE}; -cvar_t config_modem_dialtype = {"_config_modem_dialtype", "T", CVAR_ARCHIVE}; -cvar_t config_modem_clear = {"_config_modem_clear", "ATZ", CVAR_ARCHIVE}; -cvar_t config_modem_init = {"_config_modem_init", "", CVAR_ARCHIVE}; -cvar_t config_modem_hangup = {"_config_modem_hangup", "AT H", CVAR_ARCHIVE}; -#endif - -#ifdef IDGODS -cvar_t idgods = {"idgods", "0"}; -#endif - -// these two macros are to make the code more readable -#define sfunc net_drivers[sock->driver] -#define dfunc net_drivers[net_driverlevel] - -int net_driverlevel; - - -double net_time; - -double SetNetTime(void) -{ - net_time = Sys_FloatTime(); - return net_time; -} - -#if defined(_WIN32) || defined(SERVERONLY) -int Sys_FileWrite (int handle, void *data, int count) -{ - return 0; -} -int Sys_FileRead (int handle, void *data, int count) -{ - return 0; -} -void Sys_FileClose (int handle) -{ - return; -} -#endif -/* -=================== -NET_NewQSocket - -Called by drivers when a new communications endpoint is required -The sequence and buffer fields will be filled in properly -=================== -*/ -qsocket_t *NET_NewQSocket (void) -{ - qsocket_t *sock; - - if (net_freeSockets == NULL) - return NULL; - - if (net_activeconnections >= 32) - return NULL; - - // get one from free list - sock = net_freeSockets; - net_freeSockets = sock->next; - - // add it to active list - sock->next = net_activeSockets; - net_activeSockets = sock; - - sock->disconnected = false; - sock->connecttime = net_time; - Q_strcpy (sock->address,"UNSET ADDRESS"); - sock->driver = net_driverlevel; - sock->socket = 0; - sock->driverdata = NULL; - sock->qwprotocol = false; - sock->canSend = true; - sock->sendNext = false; - sock->lastMessageTime = net_time; - sock->ackSequence = 0; - sock->sendSequence = 0; - sock->unreliableSendSequence = 0; - sock->sendMessageLength = 0; - sock->receiveSequence = 0; - sock->unreliableReceiveSequence = 0; - sock->receiveMessageLength = 0; - - return sock; -} - - -void NET_FreeQSocket(qsocket_t *sock) -{ - qsocket_t *s; - - // remove it from active list - if (sock == net_activeSockets) - net_activeSockets = net_activeSockets->next; - else - { - for (s = net_activeSockets; s; s = s->next) - if (s->next == sock) - { - s->next = sock->next; - break; - } - if (!s) - Sys_Error ("NET_FreeQSocket: not active\n"); - } - - // add it to free list - sock->next = net_freeSockets; - net_freeSockets = sock; - sock->disconnected = true; -} - - -static void NET_Listen_f (void) -{ - if (Cmd_Argc () != 2) - { - Con_Printf ("\"listen\" is \"%u\"\n", listening ? 1 : 0); - return; - } - - listening = Q_atoi(Cmd_Argv(1)) ? true : false; - - for (net_driverlevel=0 ; net_driverlevel 65534) - { - Con_Printf ("Bad value, must be between 1 and 65534\n"); - return; - } - - DEFAULTnet_hostport = n; - net_hostport = n; - - if (listening) - { - // force a change to the new port - Cbuf_AddText ("listen 0\n", RESTRICT_LOCAL); - Cbuf_AddText ("listen 1\n", RESTRICT_LOCAL); - } -} - - -static void PrintSlistHeader(void) -{ - Con_Printf("Server Map Users\n"); - Con_Printf("--------------- --------------- -----\n"); - slistLastShown = 0; -} - - -static void PrintSlist(void) -{ - int n; - - for (n = slistLastShown; n < hostCacheCount; n++) - { - if (hostcache[n].maxusers) - Con_Printf("%-15.15s %-15.15s %2u/%2u\n", hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers); - else - Con_Printf("%-15.15s %-15.15s\n", hostcache[n].name, hostcache[n].map); - } - slistLastShown = n; -} - - -static void PrintSlistTrailer(void) -{ - if (hostCacheCount) - Con_Printf("== end list ==\n\n"); - else - Con_Printf("No Quake servers found.\n\n"); -} - - -void NET_Slist_f (void) -{ - if (slistInProgress) - return; - - if (! slistSilent) - { - Con_Printf("Looking for Quake servers...\n"); - PrintSlistHeader(); - } - - slistInProgress = true; - slistStartTime = Sys_FloatTime(); - - SchedulePollProcedure(&slistSendProcedure, 0.0); - SchedulePollProcedure(&slistPollProcedure, 0.1); - - hostCacheCount = 0; -} - - -static void Slist_Send(void *arg) -{ - for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++) - { - if (!slistLocal && net_driverlevel == 0) - continue; - if (net_drivers[net_driverlevel].initialized == false) - continue; - dfunc.SearchForHosts (true); - } - - if ((Sys_FloatTime() - slistStartTime) < 0.5) - SchedulePollProcedure(&slistSendProcedure, 0.75); -} - - -static void Slist_Poll(void *arg) -{ - for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++) - { - if (!slistLocal && net_driverlevel == 0) - continue; - if (net_drivers[net_driverlevel].initialized == false) - continue; - dfunc.SearchForHosts (false); - } - - if (! slistSilent) - PrintSlist(); - - if ((Sys_FloatTime() - slistStartTime) < 1.5) - { - SchedulePollProcedure(&slistPollProcedure, 0.1); - return; - } - - if (! slistSilent) - PrintSlistTrailer(); - slistInProgress = false; - slistSilent = false; - slistLocal = true; -} - - -/* -=================== -NET_Connect -=================== -*/ - -int hostCacheCount = 0; -hostcache_t hostcache[HOSTCACHESIZE]; - -qsocket_t *NET_Connect (char *host, qboolean continuation) -{ - qsocket_t *ret; - int n; - int numdrivers = net_numdrivers; - - SetNetTime(); - - if (host && *host == 0) - host = NULL; - - if (host) - { - if (Q_strcasecmp (host, "local") == 0) - { - numdrivers = 1; - goto JustDoIt; - } - - if (continuation != 1) - { - slistSilent = host ? true : false; - NET_Slist_f (); - - while(slistInProgress) - NET_Poll(); - } - - if (hostCacheCount) - { - for (n = 0; n < hostCacheCount; n++) - if (Q_strcasecmp (host, hostcache[n].name) == 0) - { - host = hostcache[n].cname; - break; - } - if (n < hostCacheCount) - goto JustDoIt; - } - } - - if (host == NULL) - { - if (hostCacheCount != 1) - return NULL; - host = hostcache[0].cname; - Con_Printf("Connecting to...\n%s @ %s\n\n", hostcache[0].name, host); - } - - if (hostCacheCount) - for (n = 0; n < hostCacheCount; n++) - if (Q_strcasecmp (host, hostcache[n].name) == 0) - { - host = hostcache[n].cname; - break; - } - -JustDoIt: - for (net_driverlevel=0 ; net_driverleveldisconnected==true) - return; - - SetNetTime(); - - // call the driver_Close function - sfunc.Close (sock); - - NET_FreeQSocket(sock); -} - - -/* -================= -NET_GetMessage - -If there is a complete message, return it in net_message - -returns 0 if no data is waiting -returns 1 if a message was received -returns -1 if connection is invalid -================= -*/ - -extern void PrintStats(qsocket_t *s); - -int NET_GetMessage (qsocket_t *sock) -{ - int ret; - - if (!sock) - return -1; - - if (sock->disconnected) - { - Con_Printf("NET_GetMessage: disconnected socket\n"); - return -1; - } - - SetNetTime(); - - ret = sfunc.QGetMessage(sock); - - // see if this connection has timed out - if (ret == 0 && sock->driver) - { - if (net_time - sock->lastMessageTime > net_messagetimeout.value) - { - NET_Close(sock); - return -1; - } - } - - - if (ret > 0) - { - if (sock->driver) - { - sock->lastMessageTime = net_time; - if (ret == 1) - messagesReceived++; - else if (ret == 2) - unreliableMessagesReceived++; - } - } - - *(int *)net_from.ip = 0; - net_from.port = 0; - return ret; -} - - -/* -================== -NET_SendMessage - -Try to send a complete length+message unit over the reliable stream. -returns 0 if the message cannot be delivered reliably, but the connection - is still considered valid -returns 1 if the message was sent properly -returns -1 if the connection died -================== -*/ - -int NET_SendMessage (qsocket_t *sock, sizebuf_t *data) -{ - int r; - - if (!sock) - return -1; - - if (sock->disconnected) - { - Con_Printf("NET_SendMessage: disconnected socket\n"); - return -1; - } - - SetNetTime(); - r = sfunc.QSendMessage(sock, data); - if (r == 1 && sock->driver) - messagesSent++; - - return r; -} - - -int NET_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) -{ - int r; - - if (!sock) - return -1; - - if (sock->disconnected) - { - Con_Printf("NET_SendMessage: disconnected socket\n"); - return -1; - } - - SetNetTime(); - r = sfunc.SendUnreliableMessage(sock, data); - if (r == 1 && sock->driver) - unreliableMessagesSent++; - - return r; -} - - -/* -================== -NET_CanSendMessage - -Returns true or false if the given qsocket can currently accept a -message to be transmitted. -================== -*/ -qboolean NET_CanSendMessage (qsocket_t *sock) -{ - int r; - - if (!sock) - return false; - - if (sock->disconnected) - return false; - - SetNetTime(); - - r = sfunc.CanSendMessage(sock); - - return r; -} - - -int NET_SendToAll(sizebuf_t *data, int blocktime) -{ -#ifndef CLIENTONLY - double start; - int i; - int count = 0; - qboolean state1 [MAX_CLIENTS]; - qboolean state2 [MAX_CLIENTS]; - - for (i=0, host_client = svs.clients ; i<32 ; i++, host_client++) - { - if (!host_client->netchan.qsocket) - continue; - if (host_client->state > cs_zombie) - { - if (host_client->netchan.qsocket->driver == 0) - { - NET_SendMessage(host_client->netchan.qsocket, data); - state1[i] = true; - state2[i] = true; - continue; - } - count++; - state1[i] = false; - state2[i] = false; - } - else - { - state1[i] = true; - state2[i] = true; - } - } - - start = Sys_FloatTime(); - while (count) - { - count = 0; - for (i=0, host_client = svs.clients ; i<32 ; i++, host_client++) - { - if (! state1[i]) - { - if (NET_CanSendMessage (host_client->netchan.qsocket)) - { - state1[i] = true; - NET_SendMessage(host_client->netchan.qsocket, data); - } - else - { - NET_GetMessage (host_client->netchan.qsocket); - } - count++; - continue; - } - - if (! state2[i]) - { - if (NET_CanSendMessage (host_client->netchan.qsocket)) - { - state2[i] = true; - } - else - { - NET_GetMessage (host_client->netchan.qsocket); - } - count++; - continue; - } - } - if ((Sys_FloatTime() - start) > blocktime) - break; - } - return count; -#else - return 0; -#endif -} - - -//============================================================================= - -/* -==================== -NET_Init -==================== -*/ - -void NQ_NET_Init (void) -{ - int i; - int controlSocket; - qsocket_t *s; - - i = COM_CheckParm ("-nqport"); - if (!i) - i = COM_CheckParm ("-udpport"); - if (!i) - i = COM_CheckParm ("-ipxport"); - - if (i) - { - if (i < com_argc-1) - DEFAULTnet_hostport = Q_atoi (com_argv[i+1]); - else - Sys_Error ("NET_Init: you must specify a number after -port"); - } - net_hostport = DEFAULTnet_hostport; - -#ifndef CLIENTONLY -#ifndef SERVERONLY - if (COM_CheckParm("-listen") || isDedicated) -#endif - listening = true; - - net_numsockets = 32; -#ifndef SERVERONLY - if (!isDedicated) - net_numsockets++; -#endif - -#else - net_numsockets = 1; -#endif - - SetNetTime(); - - for (i = 0; i < net_numsockets; i++) - { - s = (qsocket_t *)Hunk_AllocName(sizeof(qsocket_t), "qsocket"); - s->next = net_freeSockets; - net_freeSockets = s; - s->disconnected = true; - } - - // allocate space for network message buffer - net_message.data = Z_Malloc(NET_MAXMESSAGE); - net_message.maxsize = NET_MAXMESSAGE; - - Cvar_Register (&net_messagetimeout, "Networking"); -// Cvar_RegisterVariable (&hostname); -#ifndef NOCOM - Cvar_RegisterVariable (&config_com_port); - Cvar_RegisterVariable (&config_com_irq); - Cvar_RegisterVariable (&config_com_baud); - Cvar_RegisterVariable (&config_com_modem); - Cvar_RegisterVariable (&config_modem_dialtype); - Cvar_RegisterVariable (&config_modem_clear); - Cvar_RegisterVariable (&config_modem_init); - Cvar_RegisterVariable (&config_modem_hangup); -#endif -#ifdef IDGODS - Cvar_RegisterVariable (&idgods); -#endif - - Cmd_AddCommand ("slist", NET_Slist_f); - Cmd_AddCommand ("listen", NET_Listen_f); - Cmd_AddCommand ("port", NET_Port_f); - - // initialize all the drivers - for (net_driverlevel=0 ; net_driverlevelnext) - NET_Close(sock); - -// -// shutdown the drivers -// - for (net_driverlevel = 0; net_driverlevel < net_numdrivers; net_driverlevel++) - { - if (net_drivers[net_driverlevel].initialized == true) - { - net_drivers[net_driverlevel].Shutdown (); - net_drivers[net_driverlevel].initialized = false; - } - } -} - - -static PollProcedure *pollProcedureList = NULL; - -void NET_Poll(void) -{ - PollProcedure *pp; -#ifndef NOCOM - qboolean useModem; - - if (!configRestored) - { - if (serialAvailable) - { - if (config_com_modem.value == 1.0) - useModem = true; - else - useModem = false; - SetComPortConfig (0, (int)config_com_port.value, (int)config_com_irq.value, (int)config_com_baud.value, useModem); - SetModemConfig (0, config_modem_dialtype.string, config_modem_clear.string, config_modem_init.string, config_modem_hangup.string); - } - configRestored = true; - } -#endif - - SetNetTime(); - - for (pp = pollProcedureList; pp; pp = pp->next) - { - if (pp->nextTime > net_time) - break; - pollProcedureList = pp->next; - pp->procedure(pp->arg); - } -} - - -void SchedulePollProcedure(PollProcedure *proc, double timeOffset) -{ - PollProcedure *pp, *prev; - - proc->nextTime = Sys_FloatTime() + timeOffset; - for (pp = pollProcedureList, prev = NULL; pp; pp = pp->next) - { - if (pp->nextTime >= proc->nextTime) - break; - prev = pp; - } - - if (prev == NULL) - { - proc->next = pollProcedureList; - pollProcedureList = proc; - return; - } - - proc->next = pp; - prev->next = proc; -} - - -#ifdef IDGODS -#define IDNET 0xc0f62800 - -qboolean IsID(struct qsockaddr *addr) -{ - if (idgods.value == 0.0) - return false; - - if (addr->sa_family != 2) - return false; - - if ((BigLong(*(int *)&addr->sa_data[2]) & 0xffffff00) == IDNET) - return true; - return false; -} -#endif - - -#ifndef SERVERONLY -void NQ_BeginConnect(char *to) -{ -netadr_t addr; - - if (cls.netcon) - { - if (cls.netcon->qwprotocol) - { - sizebuf_t msg; - char data[64]; - *(int*)data = -1; - strcpy(data+4, "getchallenge"); - msg.cursize = strlen(data); - msg.data = data; - NET_SendMessage(cls.netcon, &msg); - } - return; - } - - cls.netcon = NET_Connect(to, 0); - if (!cls.netcon) - { - Con_Printf ("CL_Connect: connect failed\n"); - return; - } - if (cls.netcon->qwprotocol) - { - extern double connect_time; - cls.netchan.qsocket = cls.netcon; - connect_time=-1; //a get chalenge is emulated by server. - } - else - { - SockadrToNetadr(&cls.netcon->addr, &addr); - Netchan_Setup(cls.netcon->socket, &cls.netchan, addr, cls.qport); - cls.netchan.qsocket = cls.netcon; - Con_DPrintf ("CL_EstablishConnection: connected to %s\n", cls.servername); - - cls.netchan.qsocket = cls.netcon; - - cls.demonum = -1; // not in the demo loop now - cls.state = ca_connected; - } - -// MSG_WriteByte(&cls.netchan.message, clc_stringcmd); -// MSG_WriteString(&cls.netchan.message, "new"); -} -void NQ_ContinueConnect(char *to) -{ -netadr_t addr; - if (cls.netcon) - return; //already got through - - cls.netcon = NET_Connect(to, 1); - if (!cls.netcon) - { - return; - } - if (cls.netcon->qwprotocol) - { - extern double connect_time; - cls.netchan.qsocket = cls.netcon; - connect_time=-1; //a get chalenge is emulated by server. - } - else - { - SockadrToNetadr(&cls.netcon->addr, &addr); - Netchan_Setup(cls.netcon->socket, &cls.netchan, addr, cls.qport); - cls.netchan.qsocket = cls.netcon; - Con_DPrintf ("CL_EstablishConnection: connected to %s\n", cls.servername); - - cls.netchan.qsocket = cls.netcon; - - cls.demonum = -1; // not in the demo loop now - cls.state = ca_connected; - } -// MSG_WriteByte(&cls.netchan.message, clc_stringcmd); -// MSG_WriteString(&cls.netchan.message, "new"); -} -void NQ_AbortConnect(char *to) -{ -} -#endif - - -#endif diff --git a/engine/nqnet/net_ser.h b/engine/nqnet/net_ser.h deleted file mode 100644 index 5885ab97..00000000 --- a/engine/nqnet/net_ser.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_ser.h - -int Serial_Init (void); -void Serial_Listen (qboolean state); -void Serial_SearchForHosts (qboolean xmit); -qsocket_t *Serial_Connect (char *host); -qsocket_t *Serial_CheckNewConnections (void); -int Serial_GetMessage (qsocket_t *sock); -int Serial_SendMessage (qsocket_t *sock, sizebuf_t *data); -int Serial_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data); -qboolean Serial_CanSendMessage (qsocket_t *sock); -qboolean Serial_CanSendUnreliableMessage (qsocket_t *sock); -void Serial_Close (qsocket_t *sock); -void Serial_Shutdown (void); diff --git a/engine/nqnet/net_udp.c b/engine/nqnet/net_udp.c deleted file mode 100644 index 06e3169d..00000000 --- a/engine/nqnet/net_udp.c +++ /dev/null @@ -1,429 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_udp.c - -#if 1 -#include "net_win.c" -#else - -#include "../client/quakedef.h" - -#ifdef NQPROT - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __sun__ -#include -#endif - -#ifdef NeXT -#include -#endif - -extern int gethostname (char *, int); -extern int close (int); - -extern cvar_t hostname; - -static int net_acceptsocket = -1; // socket for fielding new connections -static int net_controlsocket; -static int net_broadcastsocket = 0; -static struct qsockaddr broadcastaddr; - -static unsigned long myAddr; - -#include "net_udp.h" - -//============================================================================= - -int NQUDP_Init (void) -{ - struct hostent *local; - char buff[MAXHOSTNAMELEN]; - struct qsockaddr addr; - char *colon; - - if (COM_CheckParm ("-noudp")) - return -1; - - // determine my name & address - gethostname(buff, MAXHOSTNAMELEN); - local = gethostbyname(buff); - - if (!local) - { - Con_Printf("Failed to get net stuff working proper\n"); - return -1; - } - myAddr = *(int *)local->h_addr_list[0]; -#ifndef CLIENTONLY - // if the quake hostname isn't set, set it to the machine name - if (Q_strcmp(hostname.string, "UNNAMED") == 0) - { - buff[15] = 0; - Cvar_Set ("hostname", buff); - } -#endif - if ((net_controlsocket = NQUDP_OpenSocket (0)) == -1) - Sys_Error("UDP_Init: Unable to open control socket\n"); - - ((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET; - ((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST; - ((struct sockaddr_in *)&broadcastaddr)->sin_port = htons(net_hostport); - - NQUDP_GetSocketAddr (net_controlsocket, &addr); - Q_strcpy(my_tcpip_address, NQUDP_AddrToString (&addr)); - colon = Q_strrchr (my_tcpip_address, ':'); - if (colon) - *colon = 0; - - Con_Printf("UDP Initialized\n"); - tcpipAvailable = true; - - return net_controlsocket; -} - -//============================================================================= - -void NQUDP_Shutdown (void) -{ - NQUDP_Listen (false); - NQUDP_CloseSocket (net_controlsocket); -} - -//============================================================================= - -void NQUDP_Listen (qboolean state) -{ - // enable listening - if (state) - { - if (net_acceptsocket != -1) - return; - if ((net_acceptsocket = NQUDP_OpenSocket (net_hostport)) == -1) - Sys_Error ("UDP_Listen: Unable to open accept socket\n"); - return; - } - - // disable listening - if (net_acceptsocket == -1) - return; - NQUDP_CloseSocket (net_acceptsocket); - net_acceptsocket = -1; -} - -//============================================================================= - -int NQUDP_OpenSocket (int port) -{ - int newsocket; - struct sockaddr_in address; - qboolean _true = true; - - if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) - return -1; - - if (ioctl (newsocket, FIONBIO, (char *)&_true) == -1) - goto ErrorReturn; - - address.sin_family = AF_INET; - address.sin_addr.s_addr = INADDR_ANY; - address.sin_port = htons(port); - if( bind (newsocket, (void *)&address, sizeof(address)) == -1) - goto ErrorReturn; - - return newsocket; - -ErrorReturn: - close (newsocket); - return -1; -} - -//============================================================================= - -int NQUDP_CloseSocket (int socket) -{ - if (socket == net_broadcastsocket) - net_broadcastsocket = 0; - return close (socket); -} - - -//============================================================================= -/* -============ -PartialIPAddress - -this lets you type only as much of the net address as required, using -the local network components to fill in the rest -============ -*/ -static int NQPartialIPAddress (char *in, struct qsockaddr *hostaddr) -{ - char buff[256]; - char *b; - int addr; - int num; - int mask; - int run; - int port; - - buff[0] = '.'; - b = buff; - strcpy(buff+1, in); - if (buff[1] == '.') - b++; - - addr = 0; - mask=-1; - while (*b == '.') - { - b++; - num = 0; - run = 0; - while (!( *b < '0' || *b > '9')) - { - num = num*10 + *b++ - '0'; - if (++run > 3) - return -1; - } - if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0) - return -1; - if (num < 0 || num > 255) - return -1; - mask<<=8; - addr = (addr<<8) + num; - } - - if (*b++ == ':') - port = Q_atoi(b); - else - port = net_hostport; - - hostaddr->sa_family = AF_INET; - ((struct sockaddr_in *)hostaddr)->sin_port = htons((short)port); - ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr); - - return 0; -} -//============================================================================= - -int NQUDP_Connect (int socket, struct qsockaddr *addr) -{ - return 0; -} - -//============================================================================= - -int NQUDP_CheckNewConnections (void) -{ - unsigned long available; - - if (net_acceptsocket == -1) - return -1; - - if (ioctl (net_acceptsocket, FIONREAD, &available) == -1) - Sys_Error ("UDP: ioctlsocket (FIONREAD) failed\n"); - if (available) - return net_acceptsocket; - return -1; -} - -//============================================================================= - -int NQUDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr) -{ - int addrlen = sizeof (struct qsockaddr); - int ret; - - ret = recvfrom (socket, buf, len, 0, (struct sockaddr *)addr, &addrlen); - if (ret == -1 && (errno == EWOULDBLOCK || errno == ECONNREFUSED)) - return 0; - return ret; -} - -//============================================================================= - -int NQUDP_MakeSocketBroadcastCapable (int socket) -{ - int i = 1; - - // make this socket broadcast capable - if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0) - return -1; - net_broadcastsocket = socket; - - return 0; -} - -//============================================================================= - -int NQUDP_Broadcast (int socket, byte *buf, int len) -{ - int ret; - - if (socket != net_broadcastsocket) - { - if (net_broadcastsocket != 0) - Sys_Error("Attempted to use multiple broadcasts sockets\n"); - ret = NQUDP_MakeSocketBroadcastCapable (socket); - if (ret == -1) - { - Con_Printf("Unable to make socket broadcast capable\n"); - return ret; - } - } - - return NQUDP_Write (socket, buf, len, &broadcastaddr); -} - -//============================================================================= - -int NQUDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr) -{ - int ret; - - ret = sendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr)); - if (ret == -1 && errno == EWOULDBLOCK) - return 0; - return ret; -} - -//============================================================================= - -char *NQUDP_AddrToString (struct qsockaddr *addr) -{ - static char buffer[22]; - int haddr; - - haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr); - sprintf(buffer, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, ntohs(((struct sockaddr_in *)addr)->sin_port)); - return buffer; -} - -//============================================================================= - -int NQUDP_StringToAddr (char *string, struct qsockaddr *addr) -{ - int ha1, ha2, ha3, ha4, hp; - int ipaddr; - - sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp); - ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4; - - addr->sa_family = AF_INET; - ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr); - ((struct sockaddr_in *)addr)->sin_port = htons(hp); - return 0; -} - -//============================================================================= - -int NQUDP_GetSocketAddr (int socket, struct qsockaddr *addr) -{ - int addrlen = sizeof(struct qsockaddr); - unsigned int a; - - Q_memset(addr, 0, sizeof(struct qsockaddr)); - getsockname(socket, (struct sockaddr *)addr, &addrlen); - a = ((struct sockaddr_in *)addr)->sin_addr.s_addr; - if (a == 0 || a == inet_addr("127.0.0.1")) - ((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr; - - return 0; -} - -//============================================================================= - -int NQUDP_GetNameFromAddr (struct qsockaddr *addr, char *name) -{ - struct hostent *hostentry; - - hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET); - if (hostentry) - { - Q_strncpyz (name, (char *)hostentry->h_name, NET_NAMELEN); - return 0; - } - - Q_strcpy (name, NQUDP_AddrToString (addr)); - return 0; -} - -//============================================================================= - -int NQUDP_GetAddrFromName(char *name, struct qsockaddr *addr) -{ - struct hostent *hostentry; - - if (name[0] >= '0' && name[0] <= '9') - return NQPartialIPAddress (name, addr); - - hostentry = gethostbyname (name); - if (!hostentry) - return -1; - - addr->sa_family = AF_INET; - ((struct sockaddr_in *)addr)->sin_port = htons(net_hostport); - ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; - - return 0; -} - -//============================================================================= - -int NQUDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2) -{ - if (addr1->sa_family != addr2->sa_family) - return -1; - - if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr) - return -1; - - if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port) - return 1; - - return 0; -} - -//============================================================================= - -int NQUDP_GetSocketPort (struct qsockaddr *addr) -{ - return ntohs(((struct sockaddr_in *)addr)->sin_port); -} - - -int NQUDP_SetSocketPort (struct qsockaddr *addr, int port) -{ - ((struct sockaddr_in *)addr)->sin_port = htons(port); - return 0; -} - -//============================================================================= - -#endif -#endif diff --git a/engine/nqnet/net_vcr.c b/engine/nqnet/net_vcr.c deleted file mode 100644 index f387f4f7..00000000 --- a/engine/nqnet/net_vcr.c +++ /dev/null @@ -1,22 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_vcr.c - -#include "quakedef.h" diff --git a/engine/nqnet/net_vcr.h b/engine/nqnet/net_vcr.h deleted file mode 100644 index 95c2f34c..00000000 --- a/engine/nqnet/net_vcr.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_vcr.h - -#define VCR_OP_CONNECT 1 -#define VCR_OP_GETMESSAGE 2 -#define VCR_OP_SENDMESSAGE 3 -#define VCR_OP_CANSENDMESSAGE 4 -#define VCR_MAX_MESSAGE 4 - -int VCR_Init (void); -void VCR_Listen (qboolean state); -void VCR_SearchForHosts (qboolean xmit); -qsocket_t *VCR_Connect (char *host); -qsocket_t *VCR_CheckNewConnections (void); -int VCR_GetMessage (qsocket_t *sock); -int VCR_SendMessage (qsocket_t *sock, sizebuf_t *data); -qboolean VCR_CanSendMessage (qsocket_t *sock); -void VCR_Close (qsocket_t *sock); -void VCR_Shutdown (void); diff --git a/engine/nqnet/net_win.c b/engine/nqnet/net_win.c deleted file mode 100644 index efc28479..00000000 --- a/engine/nqnet/net_win.c +++ /dev/null @@ -1,765 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -#include "quakedef.h" -#ifdef NQPROT -#include "../client/winquake.h" - -#include "net_loop.h" -#include "net_dgrm.h" -#include "net_ser.h" - -#define Sys_FloatTime Sys_DoubleTime - -net_driver_t net_drivers[MAX_NET_DRIVERS] = -{ -#if !defined(SERVERONLY) && !defined(CLIENTONLY) - { - "Loopback", - false, - Loop_Init, - Loop_Listen, - Loop_SearchForHosts, - Loop_Connect, - Loop_CheckNewConnections, - Loop_GetMessage, - Loop_SendMessage, - Loop_SendUnreliableMessage, - Loop_CanSendMessage, - Loop_CanSendUnreliableMessage, - Loop_Close, - Loop_Shutdown - } - , -#endif - { - "Datagram", - false, - Datagram_Init, - Datagram_Listen, - Datagram_SearchForHosts, - Datagram_Connect, - Datagram_CheckNewConnections, - Datagram_GetMessage, - Datagram_SendMessage, - Datagram_SendUnreliableMessage, - Datagram_CanSendMessage, - Datagram_CanSendUnreliableMessage, - Datagram_Close, - Datagram_Shutdown, - - Datagram_BeginConnect, - Datagram_ContinueConnect - } -}; - -#if !defined(SERVERONLY) && !defined(CLIENTONLY) -int net_numdrivers = 2; -#else -int net_numdrivers = 1; -#endif - - -#include "net_wins.h" -#include "net_wipx.h" - -net_landriver_t net_landrivers[MAX_NET_DRIVERS] = -{ - { - "Winsock TCPIP", - false, - 0, - WINS_Init, - WINS_Shutdown, - WINS_Listen, - WINS_OpenSocket, - WINS_CloseSocket, - WINS_Connect, - WINS_CheckNewConnections, - WINS_Read, - WINS_Write, - WINS_Broadcast, - WINS_AddrToString, - WINS_StringToAddr, - WINS_GetSocketAddr, - WINS_GetNameFromAddr, - WINS_GetAddrFromName, - WINS_AddrCompare, - WINS_GetSocketPort, - WINS_SetSocketPort - } -#ifdef _WIN32 -, - { - "Winsock IPX", - false, - 0, - WIPX_Init, - WIPX_Shutdown, - WIPX_Listen, - WIPX_OpenSocket, - WIPX_CloseSocket, - WIPX_Connect, - WIPX_CheckNewConnections, - WIPX_Read, - WIPX_Write, - WIPX_Broadcast, - WIPX_AddrToString, - WIPX_StringToAddr, - WIPX_GetSocketAddr, - WIPX_GetNameFromAddr, - WIPX_GetAddrFromName, - WIPX_AddrCompare, - WIPX_GetSocketPort, - WIPX_SetSocketPort - } -#endif -}; - -#ifdef _WIN32 -int net_numlandrivers = 2; -#else -int net_numlandrivers = 1; -#endif - - - - - - - - - - - - - - - - - - - - - - -#ifndef CLIENTONLY -extern cvar_t hostname; -#endif - -#define MAXHOSTNAMELEN 256 - -static int net_acceptsocket = -1; // socket for fielding new connections -static int net_controlsocket; -static int net_broadcastsocket = 0; -static struct sockaddr_qstorage broadcastaddr; - -static unsigned long myAddr; - -#ifdef _WIN32 -qboolean winsock_lib_initialized; - -int (PASCAL *pWSAStartup)(WORD wVersionRequired, LPWSADATA lpWSAData); -int (PASCAL *pWSACleanup)(void); -int (PASCAL *pWSAGetLastError)(void); -SOCKET (PASCAL *psocket)(int af, int type, int protocol); -int (PASCAL *pioctlsocket)(SOCKET s, long cmd, u_long *argp); -int (PASCAL *psetsockopt)(SOCKET s, int level, int optname, - const char * optval, int optlen); -int (PASCAL *precvfrom)(SOCKET s, char * buf, int len, int flags, - struct sockaddr *from, int * fromlen); -int (PASCAL *psendto)(SOCKET s, const char * buf, int len, int flags, - const struct sockaddr *to, int tolen); -int (PASCAL *pclosesocket)(SOCKET s); -int (PASCAL *pgethostname)(char * name, int namelen); -struct hostent * (PASCAL *pgethostbyname)(const char * name); -struct hostent * (PASCAL *pgethostbyaddr)(const char * addr, - int len, int type); -int (PASCAL *pgetsockname)(SOCKET s, struct sockaddr *name, - int * namelen); - -int winsock_initialized = 0; -WSADATA winsockdata; -#define qerrno pWSAGetLastError() - -#define EWOULDBLOCK WSAEWOULDBLOCK -#define ECONNREFUSED WSAECONNREFUSED -#else -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#define SOCKET_ERROR -1 - -#define qerrno errno - -#define psocket socket -#define pgethostbyaddrpsocket gethostbyaddrpsocket -#define pgethostbyaddrpioctlsocket gethostbyaddrpioctlsocket -#define psetsockopt setsockopt -#define precvfrom recvfrom -#define psendto sendto -#define pclosesocket close -#define pgethostname gethostname -#define pgethostbyname gethostbyname -#define pgethostbyaddr gethostbyaddr -#define pgetsockname getsockname -#define pioctlsocket ioctl - -#endif - -#include "net_wins.h" - -//============================================================================= - -static double blocktime; -#ifdef _WIN32 -BOOL PASCAL BlockingHook(void) -{ - MSG msg; - BOOL ret; - - if ((Sys_FloatTime() - blocktime) > 2.0) - { - WSACancelBlockingCall(); - return FALSE; - } - - /* get the next message, if any */ - ret = (BOOL) PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); - - /* if we got one, process it */ - if (ret) { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - - /* TRUE if we got a message */ - return ret; -} -#endif - -void WINS_GetLocalAddress() -{ - struct hostent *local = NULL; - char buff[MAXHOSTNAMELEN]; - unsigned long addr; - - if (myAddr != INADDR_ANY) - return; - - if (pgethostname(buff, MAXHOSTNAMELEN) == SOCKET_ERROR) - return; - - blocktime = Sys_FloatTime(); -#ifdef _WIN32 - WSASetBlockingHook(BlockingHook); -#endif - local = pgethostbyname(buff); -#ifdef _WIN32 - WSAUnhookBlockingHook(); -#endif - if (local == NULL) - return; - - myAddr = *(int *)local->h_addr_list[0]; - - addr = ntohl(myAddr); - sprintf(my_tcpip_address, "%d.%d.%d.%d", (qbyte)((addr >> 24) & 0xff), (qbyte)((addr >> 16) & 0xff), (qbyte)((addr >> 8) & 0xff), (qbyte)(addr & 0xff)); -} - - -int WINS_Init (void) -{ - int i; - char buff[MAXHOSTNAMELEN]; - char *p; - -#ifdef _WIN32 - int r; - WORD wVersionRequested; - HINSTANCE hInst; - -// initialize the Winsock function vectors (we do this instead of statically linking -// so we can run on Win 3.1, where there isn't necessarily Winsock) - hInst = LoadLibrary("wsock32.dll"); - - if (hInst == NULL) - { - Con_Printf ("Failed to load winsock.dll\n"); - winsock_lib_initialized = false; - return -1; - } - - winsock_lib_initialized = true; - - pWSAStartup = (void *)GetProcAddress(hInst, "WSAStartup"); - pWSACleanup = (void *)GetProcAddress(hInst, "WSACleanup"); - pWSAGetLastError = (void *)GetProcAddress(hInst, "WSAGetLastError"); - psocket = (void *)GetProcAddress(hInst, "socket"); - pioctlsocket = (void *)GetProcAddress(hInst, "ioctlsocket"); - psetsockopt = (void *)GetProcAddress(hInst, "setsockopt"); - precvfrom = (void *)GetProcAddress(hInst, "recvfrom"); - psendto = (void *)GetProcAddress(hInst, "sendto"); - pclosesocket = (void *)GetProcAddress(hInst, "closesocket"); - pgethostname = (void *)GetProcAddress(hInst, "gethostname"); - pgethostbyname = (void *)GetProcAddress(hInst, "gethostbyname"); - pgethostbyaddr = (void *)GetProcAddress(hInst, "gethostbyaddr"); - pgetsockname = (void *)GetProcAddress(hInst, "getsockname"); - - if (!pWSAStartup || !pWSACleanup || !pWSAGetLastError || - !psocket || !pioctlsocket || !psetsockopt || - !precvfrom || !psendto || !pclosesocket || - !pgethostname || !pgethostbyname || !pgethostbyaddr || - !pgetsockname) - { - Con_Printf ("Couldn't GetProcAddress from winsock.dll\n"); - return -1; - } -#endif - - if (COM_CheckParm ("-noudp")) - return -1; - -#ifdef _WIN32 - if (winsock_initialized == 0) - { - wVersionRequested = MAKEWORD(1, 1); - - r = pWSAStartup (MAKEWORD(1, 1), &winsockdata); - - if (r) - { - Con_Printf ("Winsock initialization failed.\n"); - return -1; - } - } - winsock_initialized++; -#endif - - // determine my name - if (pgethostname(buff, MAXHOSTNAMELEN) == SOCKET_ERROR) - { -#ifdef _WIN32 - Con_DPrintf ("Winsock TCP/IP Initialization failed.\n"); - if (--winsock_initialized == 0) - pWSACleanup (); -#else - Con_DPrintf ("TCP/IP failed to get hostname.\n"); -#endif - return -1; - } -#ifndef CLIENTONLY - // if the quake hostname isn't set, set it to the machine name - if (Q_strcmp(hostname.string, "UNNAMED") == 0) - { - // see if it's a text IP address (well, close enough) - for (p = buff; *p; p++) - if ((*p < '0' || *p > '9') && *p != '.') - break; - - // if it is a real name, strip off the domain; we only want the host - if (*p) - { - for (i = 0; i < 15; i++) - if (buff[i] == '.') - break; - buff[i] = 0; - } - Cvar_Set (&hostname, buff); - } -#endif - i = COM_CheckParm ("-nqip"); - if (i) - { - if (i < com_argc-1) - { - myAddr = inet_addr(com_argv[i+1]); - if (myAddr == INADDR_NONE) - Sys_Error ("%s is not a valid IP address", com_argv[i+1]); - strcpy(my_tcpip_address, com_argv[i+1]); - } - else - { - Sys_Error ("NET_Init: you must specify an IP address after -ip"); - } - } - else - { - myAddr = INADDR_ANY; - strcpy(my_tcpip_address, "INADDR_ANY"); - } - - if ((net_controlsocket = WINS_OpenSocket (0)) == -1) - { - Con_Printf("WINS_Init: Unable to open control socket\n"); -#ifdef _WIN32 - if (--winsock_initialized == 0) - pWSACleanup (); -#endif - return -1; - } - - ((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET; - ((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST; - ((struct sockaddr_in *)&broadcastaddr)->sin_port = htons((unsigned short)net_hostport); - - Con_Printf("Winsock TCP/IP Initialized\n"); - tcpipAvailable = true; - - return net_controlsocket; -} - -//============================================================================= - -void WINS_Shutdown (void) -{ - WINS_Listen (false); - WINS_CloseSocket (net_controlsocket); -#ifdef _WIN32 - if (--winsock_initialized == 0) - pWSACleanup (); -#endif -} - -//============================================================================= - -void WINS_Listen (qboolean state) -{ - // enable listening - if (state) - { - if (net_acceptsocket != -1) - return; - WINS_GetLocalAddress(); - if ((net_acceptsocket = WINS_OpenSocket (net_hostport)) == -1) - Con_Printf ("WINS_Listen: Unable to open accept socket\n"); - return; - } - - // disable listening - if (net_acceptsocket == -1) - return; - WINS_CloseSocket (net_acceptsocket); - net_acceptsocket = -1; -} - -//============================================================================= - -int WINS_OpenSocket (int port) -{ - int newsocket; - struct sockaddr_in address; - u_long _true = 1; - - if ((newsocket = psocket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) - return -1; - - if (pioctlsocket (newsocket, FIONBIO, &_true) == -1) - goto ErrorReturn; - - address.sin_family = AF_INET; - address.sin_addr.s_addr = myAddr; - address.sin_port = htons((unsigned short)port); - if( bind (newsocket, (void *)&address, sizeof(address)) == 0) - return newsocket; - - Con_Printf ("Unable to bind to %s\n", WINS_AddrToString((struct sockaddr_qstorage *)&address)); -ErrorReturn: - pclosesocket (newsocket); - return -1; -} - -//============================================================================= - -int WINS_CloseSocket (int socket) -{ - if (socket == net_broadcastsocket) - net_broadcastsocket = 0; - return pclosesocket (socket); -} - - -//============================================================================= -/* -============ -PartialIPAddress - -this lets you type only as much of the net address as required, using -the local network components to fill in the rest -============ -*/ -static int PartialIPAddress (char *in, struct sockaddr_qstorage *hostaddr) -{ - char buff[256]; - char *b; - int addr; - int num; - int mask; - int run; - int port; - - buff[0] = '.'; - b = buff; - strcpy(buff+1, in); - if (buff[1] == '.') - b++; - - addr = 0; - mask=-1; - while (*b == '.') - { - b++; - num = 0; - run = 0; - while (!( *b < '0' || *b > '9')) - { - num = num*10 + *b++ - '0'; - if (++run > 3) - return -1; - } - if ((*b < '0' || *b > '9') && *b != '.' && *b != ':' && *b != 0) - return -1; - if (num < 0 || num > 255) - return -1; - mask<<=8; - addr = (addr<<8) + num; - } - - if (*b++ == ':') - port = Q_atoi(b); - else - port = net_hostport; - - ((struct sockaddr_in *)hostaddr)->sin_family = AF_INET; - ((struct sockaddr_in *)hostaddr)->sin_port = htons((short)port); - ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr); - - return 0; -} -//============================================================================= - -int WINS_Connect (int socket, struct sockaddr_qstorage *addr) -{ - return 0; -} - -//============================================================================= - -int WINS_CheckNewConnections (void) -{ - char buf[4096]; - - if (net_acceptsocket == -1) - return -1; - - if (precvfrom (net_acceptsocket, buf, sizeof(buf), MSG_PEEK, NULL, NULL) > 0) - { - return net_acceptsocket; - } - return -1; -} - -//============================================================================= - -int WINS_Read (int socket, qbyte *buf, int len, struct sockaddr_qstorage *addr) -{ - int addrlen = sizeof (struct sockaddr_qstorage); - int ret; - - ret = precvfrom (socket, buf, len, 0, (struct sockaddr *)addr, &addrlen); - if (ret == -1) - { - if (qerrno == EWOULDBLOCK || qerrno == ECONNREFUSED) - return 0; - - } - return ret; -} - -//============================================================================= - -int WINS_MakeSocketBroadcastCapable (int socket) -{ - int i = 1; - - // make this socket broadcast capable - if (psetsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0) - return -1; - net_broadcastsocket = socket; - - return 0; -} - -//============================================================================= - -int WINS_Broadcast (int socket, qbyte *buf, int len) -{ - int ret; - - if (socket != net_broadcastsocket) - { - if (net_broadcastsocket != 0) - Sys_Error("Attempted to use multiple broadcasts sockets\n"); - WINS_GetLocalAddress(); - ret = WINS_MakeSocketBroadcastCapable (socket); - if (ret == -1) - { - Con_Printf("Unable to make socket broadcast capable\n"); - return ret; - } - } - - return WINS_Write (socket, buf, len, &broadcastaddr); -} - -//============================================================================= - -int WINS_Write (int socket, qbyte *buf, int len, struct sockaddr_qstorage *addr) -{ - int ret; - - ret = psendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct sockaddr_qstorage)); - if (ret == -1) - if (qerrno == EWOULDBLOCK) - return 0; - - return ret; -} - -//============================================================================= - -char *WINS_AddrToString (struct sockaddr_qstorage *addr) -{ - static char buffer[22]; - int haddr; - - haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr); - sprintf(buffer, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, ntohs(((struct sockaddr_in *)addr)->sin_port)); - return buffer; -} - -//============================================================================= - -int WINS_StringToAddr (char *string, struct sockaddr_qstorage *addr) -{ - int ha1, ha2, ha3, ha4, hp; - int ipaddr; - - sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp); - ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4; - - ((struct sockaddr_in *)addr)->sin_family = AF_INET; - ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr); - ((struct sockaddr_in *)addr)->sin_port = htons((unsigned short)hp); - return 0; -} - -//============================================================================= - -int WINS_GetSocketAddr (int socket, struct sockaddr_qstorage *addr) -{ - int addrlen = sizeof(struct sockaddr_qstorage); - unsigned int a; - - Q_memset(addr, 0, sizeof(struct sockaddr_qstorage)); - pgetsockname(socket, (struct sockaddr *)addr, &addrlen); - a = ((struct sockaddr_in *)addr)->sin_addr.s_addr; - if (a == 0 || a == inet_addr("127.0.0.1")) - ((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr; - - return 0; -} - -//============================================================================= - -int WINS_GetNameFromAddr (struct sockaddr_qstorage *addr, char *name) -{ - struct hostent *hostentry; - - hostentry = pgethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET); - if (hostentry) - { - Q_strncpyz (name, (char *)hostentry->h_name, NET_NAMELEN); - return 0; - } - - Q_strcpy (name, WINS_AddrToString (addr)); - return 0; -} - -//============================================================================= - -int WINS_GetAddrFromName(char *name, struct sockaddr_qstorage *addr) -{ - struct hostent *hostentry; - - if (name[0] >= '0' && name[0] <= '9') - return PartialIPAddress (name, addr); - - hostentry = pgethostbyname (name); - if (!hostentry) - return -1; - - ((struct sockaddr_in *)addr)->sin_family = AF_INET; - ((struct sockaddr_in *)addr)->sin_port = htons((unsigned short)net_hostport); - ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; - - return 0; -} - -//============================================================================= - -int WINS_AddrCompare (struct sockaddr_qstorage *addr1, struct sockaddr_qstorage *addr2) -{ - if (((struct sockaddr_in *)addr1)->sin_family != ((struct sockaddr_in *)addr2)->sin_family) - return -1; - - if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr) - return -1; - - if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port) - return 1; - - return 0; -} - -//============================================================================= - -int WINS_GetSocketPort (struct sockaddr_qstorage *addr) -{ - return ntohs(((struct sockaddr_in *)addr)->sin_port); -} - - -int WINS_SetSocketPort (struct sockaddr_qstorage *addr, int port) -{ - ((struct sockaddr_in *)addr)->sin_port = htons((unsigned short)port); - return 0; -} - -//============================================================================= -#endif diff --git a/engine/nqnet/net_wins.h b/engine/nqnet/net_wins.h deleted file mode 100644 index 604fd35e..00000000 --- a/engine/nqnet/net_wins.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_wins.h - -int WINS_Init (void); -void WINS_Shutdown (void); -void WINS_Listen (qboolean state); -int WINS_OpenSocket (int port); -int WINS_CloseSocket (int socket); -int WINS_Connect (int socket, struct sockaddr_qstorage *addr); -int WINS_CheckNewConnections (void); -int WINS_Read (int socket, qbyte *buf, int len, struct sockaddr_qstorage *addr); -int WINS_Write (int socket, qbyte *buf, int len, struct sockaddr_qstorage *addr); -int WINS_Broadcast (int socket, qbyte *buf, int len); -char *WINS_AddrToString (struct sockaddr_qstorage *addr); -int WINS_StringToAddr (char *string, struct sockaddr_qstorage *addr); -int WINS_GetSocketAddr (int socket, struct sockaddr_qstorage *addr); -int WINS_GetNameFromAddr (struct sockaddr_qstorage *addr, char *name); -int WINS_GetAddrFromName (char *name, struct sockaddr_qstorage *addr); -int WINS_AddrCompare (struct sockaddr_qstorage *addr1, struct sockaddr_qstorage *addr2); -int WINS_GetSocketPort (struct sockaddr_qstorage *addr); -int WINS_SetSocketPort (struct sockaddr_qstorage *addr, int port); diff --git a/engine/nqnet/net_wipx.c b/engine/nqnet/net_wipx.c deleted file mode 100644 index 430899a7..00000000 --- a/engine/nqnet/net_wipx.c +++ /dev/null @@ -1,442 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_wipx.c - -#include "quakedef.h" -#ifdef _WIN32 -#ifdef NQPROT -#include "../client/winquake.h" -#include -#include "net_wipx.h" - -#ifndef CLIENTONLY -extern cvar_t hostname; -#endif - -#define MAXHOSTNAMELEN 256 - -static int net_acceptsocket = -1; // socket for fielding new connections -static int net_controlsocket; -static struct sockaddr_qstorage broadcastaddr; - -extern qboolean winsock_initialized; -extern WSADATA winsockdata; - -#define IPXSOCKETS 18 -static int ipxsocket[IPXSOCKETS]; -static int sequence[IPXSOCKETS]; - -#ifdef _WIN32 -#define qerrno pWSAGetLastError() -#else -#define qerrno errno -#endif - -//============================================================================= - -int WIPX_Init (void) -{ - int i; - char buff[MAXHOSTNAMELEN]; - struct sockaddr_qstorage addr; - char *p; - int r; - WORD wVersionRequested; - - if (COM_CheckParm ("-noipx")) - return -1; - -// make sure LoadLibrary has happened successfully - if (!winsock_lib_initialized) - return -1; - - if (winsock_initialized == 0) - { - wVersionRequested = MAKEWORD(1, 1); - - r = pWSAStartup (MAKEWORD(1, 1), &winsockdata); - - if (r) - { - Con_Printf ("Winsock initialization failed.\n"); - return -1; - } - } - winsock_initialized++; - - for (i = 0; i < IPXSOCKETS; i++) - ipxsocket[i] = 0; - -#ifndef CLIENTONLY - // determine my name & address - if (pgethostname(buff, MAXHOSTNAMELEN) == 0) - { - // if the quake hostname isn't set, set it to the machine name - if (Q_strcmp(hostname.string, "UNNAMED") == 0) - { - // see if it's a text IP address (well, close enough) - for (p = buff; *p; p++) - if ((*p < '0' || *p > '9') && *p != '.') - break; - - // if it is a real name, strip off the domain; we only want the host - if (*p) - { - for (i = 0; i < 15; i++) - if (buff[i] == '.') - break; - buff[i] = 0; - } - Cvar_Set (&hostname, buff); - } - } -#endif - - if ((net_controlsocket = WIPX_OpenSocket (0)) == -1) - { - Con_Printf("WIPX_Init: Unable to open control socket\n"); - if (--winsock_initialized == 0) - pWSACleanup (); - return -1; - } - - ((struct sockaddr_ipx *)&broadcastaddr)->sa_family = AF_IPX; - memset(((struct sockaddr_ipx *)&broadcastaddr)->sa_netnum, 0, 4); - memset(((struct sockaddr_ipx *)&broadcastaddr)->sa_nodenum, 0xff, 6); - ((struct sockaddr_ipx *)&broadcastaddr)->sa_socket = htons((unsigned short)net_hostport); - - WIPX_GetSocketAddr (net_controlsocket, &addr); - Q_strcpy(my_ipx_address, WIPX_AddrToString (&addr)); - p = Q_strrchr (my_ipx_address, ':'); - if (p) - *p = 0; - - Con_Printf("Winsock IPX Initialized\n"); - ipxAvailable = true; - - return net_controlsocket; -} - -//============================================================================= - -void WIPX_Shutdown (void) -{ - WIPX_Listen (false); - WIPX_CloseSocket (net_controlsocket); - if (--winsock_initialized == 0) - pWSACleanup (); -} - -//============================================================================= - -void WIPX_Listen (qboolean state) -{ - // enable listening - if (state) - { - if (net_acceptsocket != -1) - return; - if ((net_acceptsocket = WIPX_OpenSocket (net_hostport)) == -1) - Con_Printf ("WIPX_Listen: Unable to open accept socket\n"); - return; - } - - // disable listening - if (net_acceptsocket == -1) - return; - WIPX_CloseSocket (net_acceptsocket); - net_acceptsocket = -1; -} - -//============================================================================= - -int WIPX_OpenSocket (int port) -{ - int handle; - int newsocket; - struct sockaddr_ipx address; - u_long _true = 1; - - for (handle = 0; handle < IPXSOCKETS; handle++) - if (ipxsocket[handle] == 0) - break; - if (handle == IPXSOCKETS) - return -1; - - if ((newsocket = psocket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == INVALID_SOCKET) - return -1; - - if (pioctlsocket (newsocket, FIONBIO, &_true) == -1) - goto ErrorReturn; - - if (psetsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof(_true)) < 0) - goto ErrorReturn; - - address.sa_family = AF_IPX; - memset(address.sa_netnum, 0, 4); - memset(address.sa_nodenum, 0, 6);; - address.sa_socket = htons((unsigned short)port); - if( bind (newsocket, (void *)&address, sizeof(address)) == 0) - { - ipxsocket[handle] = newsocket; - sequence[handle] = 0; - return handle; - } - - Con_Printf ("Winsock IPX bind failed\n"); -ErrorReturn: - pclosesocket (newsocket); - return -1; -} - -//============================================================================= - -int WIPX_CloseSocket (int handle) -{ - int socket = ipxsocket[handle]; - int ret; - - ret = pclosesocket (socket); - ipxsocket[handle] = 0; - return ret; -} - - -//============================================================================= - -int WIPX_Connect (int handle, struct sockaddr_qstorage *addr) -{ - return 0; -} - -//============================================================================= - -int WIPX_CheckNewConnections (void) -{ - unsigned long available; - - if (net_acceptsocket == -1) - return -1; - - if (pioctlsocket (ipxsocket[net_acceptsocket], FIONREAD, &available) == -1) - Sys_Error ("WIPX: ioctlsocket (FIONREAD) failed\n"); - if (available) - return net_acceptsocket; - return -1; -} - -//============================================================================= - -static qbyte packetBuffer[NET_DATAGRAMSIZE + 4]; - -int WIPX_Read (int handle, qbyte *buf, int len, struct sockaddr_qstorage *addr) -{ - int addrlen = sizeof (struct sockaddr_qstorage); - int socket = ipxsocket[handle]; - int ret; - - ret = precvfrom (socket, packetBuffer, len+4, 0, (struct sockaddr *)addr, &addrlen); - if (ret == -1) - { - if (qerrno == WSAEWOULDBLOCK || qerrno == WSAECONNREFUSED) - return 0; - - } - - if (ret < 4) - return 0; - - // remove sequence number, it's only needed for DOS IPX - ret -= 4; - memcpy(buf, packetBuffer+4, ret); - - return ret; -} - -//============================================================================= - -int WIPX_Broadcast (int handle, qbyte *buf, int len) -{ - return WIPX_Write (handle, buf, len, &broadcastaddr); -} - -//============================================================================= - -int WIPX_Write (int handle, qbyte *buf, int len, struct sockaddr_qstorage *addr) -{ - int socket = ipxsocket[handle]; - int ret; - - // build packet with sequence number - *(int *)(&packetBuffer[0]) = sequence[handle]; - sequence[handle]++; - memcpy(&packetBuffer[4], buf, len); - len += 4; - - ret = psendto (socket, packetBuffer, len, 0, (struct sockaddr *)addr, sizeof(struct sockaddr_qstorage)); - if (ret == -1) - if (pWSAGetLastError() == WSAEWOULDBLOCK) - return 0; - - return ret; -} - -//============================================================================= - -char *WIPX_AddrToString (struct sockaddr_qstorage *addr) -{ - static char buf[28]; - - sprintf(buf, "%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%u", - ((struct sockaddr_ipx *)addr)->sa_netnum[0] & 0xff, - ((struct sockaddr_ipx *)addr)->sa_netnum[1] & 0xff, - ((struct sockaddr_ipx *)addr)->sa_netnum[2] & 0xff, - ((struct sockaddr_ipx *)addr)->sa_netnum[3] & 0xff, - ((struct sockaddr_ipx *)addr)->sa_nodenum[0] & 0xff, - ((struct sockaddr_ipx *)addr)->sa_nodenum[1] & 0xff, - ((struct sockaddr_ipx *)addr)->sa_nodenum[2] & 0xff, - ((struct sockaddr_ipx *)addr)->sa_nodenum[3] & 0xff, - ((struct sockaddr_ipx *)addr)->sa_nodenum[4] & 0xff, - ((struct sockaddr_ipx *)addr)->sa_nodenum[5] & 0xff, - ntohs(((struct sockaddr_ipx *)addr)->sa_socket) - ); - return buf; -} - -//============================================================================= - -int WIPX_StringToAddr (char *string, struct sockaddr_qstorage *addr) -{ - int val; - char buf[3]; - - buf[2] = 0; - Q_memset(addr, 0, sizeof(struct sockaddr_qstorage)); - ((struct sockaddr*)addr)->sa_family = AF_IPX; - -#define DO(src,dest) \ - buf[0] = string[src]; \ - buf[1] = string[src + 1]; \ - if (sscanf (buf, "%x", &val) != 1) \ - return -1; \ - ((struct sockaddr_ipx *)addr)->dest = val - - DO(0, sa_netnum[0]); - DO(2, sa_netnum[1]); - DO(4, sa_netnum[2]); - DO(6, sa_netnum[3]); - DO(9, sa_nodenum[0]); - DO(11, sa_nodenum[1]); - DO(13, sa_nodenum[2]); - DO(15, sa_nodenum[3]); - DO(17, sa_nodenum[4]); - DO(19, sa_nodenum[5]); -#undef DO - - sscanf (&string[22], "%u", &val); - ((struct sockaddr_ipx *)addr)->sa_socket = htons((unsigned short)val); - - return 0; -} - -//============================================================================= - -int WIPX_GetSocketAddr (int handle, struct sockaddr_qstorage *addr) -{ - int socket = ipxsocket[handle]; - int addrlen = sizeof(struct sockaddr_qstorage); - - Q_memset(addr, 0, sizeof(struct sockaddr_qstorage)); - if(pgetsockname(socket, (struct sockaddr *)addr, &addrlen) != 0) - { - } - - return 0; -} - -//============================================================================= - -int WIPX_GetNameFromAddr (struct sockaddr_qstorage *addr, char *name) -{ - Q_strcpy(name, WIPX_AddrToString(addr)); - return 0; -} - -//============================================================================= - -int WIPX_GetAddrFromName(char *name, struct sockaddr_qstorage *addr) -{ - int n; - char buf[32]; - - n = Q_strlen(name); - - if (n == 12) - { - sprintf(buf, "00000000:%s:%u", name, net_hostport); - return WIPX_StringToAddr (buf, addr); - } - if (n == 21) - { - sprintf(buf, "%s:%u", name, net_hostport); - return WIPX_StringToAddr (buf, addr); - } - if (n > 21 && n <= 27) - return WIPX_StringToAddr (name, addr); - - return -1; -} - -//============================================================================= - -int WIPX_AddrCompare (struct sockaddr_qstorage *addr1, struct sockaddr_qstorage *addr2) -{ - if (((struct sockaddr*)addr1)->sa_family != ((struct sockaddr*)addr2)->sa_family) - return -1; - - if (*((struct sockaddr_ipx *)addr1)->sa_netnum && *((struct sockaddr_ipx *)addr2)->sa_netnum) - if (memcmp(((struct sockaddr_ipx *)addr1)->sa_netnum, ((struct sockaddr_ipx *)addr2)->sa_netnum, 4) != 0) - return -1; - if (memcmp(((struct sockaddr_ipx *)addr1)->sa_nodenum, ((struct sockaddr_ipx *)addr2)->sa_nodenum, 6) != 0) - return -1; - - if (((struct sockaddr_ipx *)addr1)->sa_socket != ((struct sockaddr_ipx *)addr2)->sa_socket) - return 1; - - return 0; -} - -//============================================================================= - -int WIPX_GetSocketPort (struct sockaddr_qstorage *addr) -{ - return ntohs(((struct sockaddr_ipx *)addr)->sa_socket); -} - - -int WIPX_SetSocketPort (struct sockaddr_qstorage *addr, int port) -{ - ((struct sockaddr_ipx *)addr)->sa_socket = htons((unsigned short)port); - return 0; -} - -//============================================================================= -#endif -#endif diff --git a/engine/nqnet/net_wipx.h b/engine/nqnet/net_wipx.h deleted file mode 100644 index e3cc1d40..00000000 --- a/engine/nqnet/net_wipx.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net_wipx.h - -int WIPX_Init (void); -void WIPX_Shutdown (void); -void WIPX_Listen (qboolean state); -int WIPX_OpenSocket (int port); -int WIPX_CloseSocket (int socket); -int WIPX_Connect (int socket, struct sockaddr_qstorage *addr); -int WIPX_CheckNewConnections (void); -int WIPX_Read (int socket, qbyte *buf, int len, struct sockaddr_qstorage *addr); -int WIPX_Write (int socket, qbyte *buf, int len, struct sockaddr_qstorage *addr); -int WIPX_Broadcast (int socket, qbyte *buf, int len); -char *WIPX_AddrToString (struct sockaddr_qstorage *addr); -int WIPX_StringToAddr (char *string, struct sockaddr_qstorage *addr); -int WIPX_GetSocketAddr (int socket, struct sockaddr_qstorage *addr); -int WIPX_GetNameFromAddr (struct sockaddr_qstorage *addr, char *name); -int WIPX_GetAddrFromName (char *name, struct sockaddr_qstorage *addr); -int WIPX_AddrCompare (struct sockaddr_qstorage *addr1, struct sockaddr_qstorage *addr2); -int WIPX_GetSocketPort (struct sockaddr_qstorage *addr); -int WIPX_SetSocketPort (struct sockaddr_qstorage *addr, int port); diff --git a/engine/nqnet/nqnet.h b/engine/nqnet/nqnet.h deleted file mode 100644 index da62c707..00000000 --- a/engine/nqnet/nqnet.h +++ /dev/null @@ -1,331 +0,0 @@ -/* -Copyright (C) 1996-1997 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ -// net.h -- quake's interface to the networking layer - -#define NET_NAMELEN 64 - -#define NET_MAXMESSAGE 8192 -#define NET_HEADERSIZE (2 * sizeof(unsigned int)) -#define NET_DATAGRAMSIZE (MAX_DATAGRAM + NET_HEADERSIZE) - -// NetHeader flags -#define NETFLAG_LENGTH_MASK 0x0000ffff -#define NETFLAG_DATA 0x00010000 -#define NETFLAG_ACK 0x00020000 -#define NETFLAG_NAK 0x00040000 -#define NETFLAG_EOM 0x00080000 -#define NETFLAG_UNRELIABLE 0x00100000 -#define NETFLAG_CTL 0x80000000 - - -#define NET_PROTOCOL_VERSION 3 - -// This is the network info/connection protocol. It is used to find Quake -// servers, get info about them, and connect to them. Once connected, the -// Quake game protocol (documented elsewhere) is used. -// -// -// General notes: -// game_name is currently always "QUAKE", but is there so this same protocol -// can be used for future games as well; can you say Quake2? -// -// CCREQ_CONNECT -// string game_name "QUAKE" -// qbyte net_protocol_version NET_PROTOCOL_VERSION -// -// CCREQ_SERVER_INFO -// string game_name "QUAKE" -// qbyte net_protocol_version NET_PROTOCOL_VERSION -// -// CCREQ_PLAYER_INFO -// qbyte player_number -// -// CCREQ_RULE_INFO -// string rule -// -// -// -// CCREP_ACCEPT -// long port -// -// CCREP_REJECT -// string reason -// -// CCREP_SERVER_INFO -// string server_address -// string host_name -// string level_name -// qbyte current_players -// qbyte max_players -// qbyte protocol_version NET_PROTOCOL_VERSION -// -// CCREP_PLAYER_INFO -// qbyte player_number -// string name -// long colors -// long frags -// long connect_time -// string address -// -// CCREP_RULE_INFO -// string rule -// string value - -// note: -// There are two address forms used above. The short form is just a -// port number. The address that goes along with the port is defined as -// "whatever address you receive this reponse from". This lets us use -// the host OS to solve the problem of multiple host addresses (possibly -// with no routing between them); the host will use the right address -// when we reply to the inbound connection request. The long from is -// a full address and port in a string. It is used for returning the -// address of a server that is not running locally. - -#define CCREQ_CONNECT 0x01 -#define CCREQ_SERVER_INFO 0x02 -#define CCREQ_PLAYER_INFO 0x03 -#define CCREQ_RULE_INFO 0x04 - -#define CCREP_ACCEPT 0x81 -#define CCREP_REJECT 0x82 -#define CCREP_SERVER_INFO 0x83 -#define CCREP_PLAYER_INFO 0x84 -#define CCREP_RULE_INFO 0x85 - -typedef struct qsocket_s -{ - struct qsocket_s *next; - double connecttime; - double lastMessageTime; - double lastSendTime; - - qboolean disconnected; - qboolean canSend; - qboolean sendNext; - - int driver; - int landriver; - int socket; - void *driverdata; - - unsigned int ackSequence; - unsigned int sendSequence; - unsigned int unreliableSendSequence; - int sendMessageLength; - qbyte sendMessage [NET_MAXMESSAGE]; - - unsigned int receiveSequence; - unsigned int unreliableReceiveSequence; - int receiveMessageLength; - qbyte receiveMessage [NET_MAXMESSAGE]; - - struct sockaddr_qstorage addr; - char address[NET_NAMELEN]; - - int qwprotocol; - -} qsocket_t; - -extern qsocket_t *net_activeSockets; -extern qsocket_t *net_freeSockets; -extern int net_numsockets; - -typedef struct -{ - char *name; - qboolean initialized; - int controlSock; - int (*Init) (void); - void (*Shutdown) (void); - void (*Listen) (qboolean state); - int (*OpenSocket) (int port); - int (*CloseSocket) (int socket); - int (*Connect) (int socket, struct sockaddr_qstorage *addr); - int (*CheckNewConnections) (void); - int (*Read) (int socket, qbyte *buf, int len, struct sockaddr_qstorage *addr); - int (*Write) (int socket, qbyte *buf, int len, struct sockaddr_qstorage *addr); - int (*Broadcast) (int socket, qbyte *buf, int len); - char * (*AddrToString) (struct sockaddr_qstorage *addr); - int (*StringToAddr) (char *string, struct sockaddr_qstorage *addr); - int (*GetSocketAddr) (int socket, struct sockaddr_qstorage *addr); - int (*GetNameFromAddr) (struct sockaddr_qstorage *addr, char *name); - int (*GetAddrFromName) (char *name, struct sockaddr_qstorage *addr); - int (*AddrCompare) (struct sockaddr_qstorage *addr1, struct sockaddr_qstorage *addr2); - int (*GetSocketPort) (struct sockaddr_qstorage *addr); - int (*SetSocketPort) (struct sockaddr_qstorage *addr, int port); -} net_landriver_t; - -#define MAX_NET_DRIVERS 8 -extern int net_numlandrivers; -extern net_landriver_t net_landrivers[MAX_NET_DRIVERS]; - -typedef struct -{ - //basic setup - char *name; - qboolean initialized; - int (*Init) (void); - void (*Listen) (qboolean state); - void (*SearchForHosts) (qboolean xmit); - qsocket_t *(*Connect) (char *host); - qsocket_t *(*CheckNewConnections) (void); - int (*QGetMessage) (qsocket_t *sock); - int (*QSendMessage) (qsocket_t *sock, sizebuf_t *data); - int (*SendUnreliableMessage) (qsocket_t *sock, sizebuf_t *data); - qboolean (*CanSendMessage) (qsocket_t *sock); - qboolean (*CanSendUnreliableMessage) (qsocket_t *sock); - void (*Close) (qsocket_t *sock); - void (*Shutdown) (void); - - //extra setup - qsocket_t *(*BeginConnect) (char *host); - qsocket_t *(*ContinueConnect) (char *host); - qsocket_t *(*FailConnect) (char *host); - - //extra info - int controlSock; -} net_driver_t; - -extern int net_numdrivers; -extern net_driver_t net_drivers[MAX_NET_DRIVERS]; - -extern int DEFAULTnet_hostport; -extern int net_hostport; - -extern int net_driverlevel; -extern cvar_t hostname; -extern char playername[]; -extern int playercolor; - -extern int messagesSent; -extern int messagesReceived; -extern int unreliableMessagesSent; -extern int unreliableMessagesReceived; - -qsocket_t *NET_NewQSocket (void); -void NET_FreeQSocket(qsocket_t *); -double SetNetTime(void); - - -#define HOSTCACHESIZE 8 - -typedef struct -{ - char name[16]; - char map[16]; - char cname[32]; - int users; - int maxusers; - int driver; - int ldriver; - struct sockaddr_qstorage addr; - - qboolean isqwprotocol; -} hostcache_t; - -extern int hostCacheCount; -extern hostcache_t hostcache[HOSTCACHESIZE]; -#ifdef IDGODS -qboolean IsID(struct qsockaddr *addr); -#endif - -//============================================================================ -// -// public network functions -// -//============================================================================ - -extern double net_time; -extern sizebuf_t net_message; -extern int net_activeconnections; - -void NQ_NET_Init (void); -void NQ_NET_Shutdown (void); - -struct qsocket_s *NET_CheckNewConnections (void); -// returns a new connection number if there is one pending, else -1 - -void NQ_Connect(char *to); -struct qsocket_s *NET_Connect (char *host, qboolean continuation); -// called by client to connect to a host. Returns -1 if not able to - -qboolean NET_CanSendMessage (qsocket_t *sock); -// Returns true or false if the given qsocket can currently accept a -// message to be transmitted. - -int NET_GetMessage (struct qsocket_s *sock); -// returns data in net_message sizebuf -// returns 0 if no data is waiting -// returns 1 if a message was received -// returns 2 if an unreliable message was received -// returns -1 if the connection died - -int NET_SendMessage (struct qsocket_s *sock, sizebuf_t *data); -int NET_SendUnreliableMessage (struct qsocket_s *sock, sizebuf_t *data); -// returns 0 if the message connot be delivered reliably, but the connection -// is still considered valid -// returns 1 if the message was sent properly -// returns -1 if the connection died - -int NET_SendToAll(sizebuf_t *data, int blocktime); -// This is a reliable *blocking* send to all attached clients. - - -void NET_Close (struct qsocket_s *sock); -// if a dead connection is returned by a get or send function, this function -// should be called when it is convenient - -// Server calls when a client is kicked off for a game related misbehavior -// like an illegal protocal conversation. Client calls when disconnecting -// from a server. -// A netcon_t number will not be reused until this function is called for it - -//special case for DP servers, which use QW style connectionless commands to connect. -//this is called directly from the QW portions of code when they detect that the server is a DP server. -qsocket_t *Datagram_ConnectToDarkPlacesServer(netadr_t *nadr); - -void NET_Poll(void); - - -typedef struct _PollProcedure -{ - struct _PollProcedure *next; - double nextTime; - void (*procedure)(void *arg); - void *arg; -} PollProcedure; - -void SchedulePollProcedure(PollProcedure *pp, double timeOffset); - -extern qboolean serialAvailable; -extern qboolean ipxAvailable; -extern qboolean tcpipAvailable; -extern char my_ipx_address[NET_NAMELEN]; -extern char my_tcpip_address[NET_NAMELEN]; -extern void (*GetComPortConfig) (int portNumber, int *port, int *irq, int *baud, qboolean *useModem); -extern void (*SetComPortConfig) (int portNumber, int port, int irq, int baud, qboolean useModem); -extern void (*GetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); -extern void (*SetModemConfig) (int portNumber, char *dialType, char *clear, char *init, char *hangup); - -extern qboolean slistInProgress; -extern qboolean slistSilent; -extern qboolean slistLocal; - -void NET_Slist_f (void); diff --git a/engine/qclib/qccmain.c b/engine/qclib/qccmain.c index e80e7c83..9eb2580a 100644 --- a/engine/qclib/qccmain.c +++ b/engine/qclib/qccmain.c @@ -3356,8 +3356,8 @@ int main (int argc, char **argv) #endif return !sucess; } -#endif -#endif +#endif//usegui +#endif//qcconly -#endif +#endif//minimal diff --git a/engine/server/net_preparse.c b/engine/server/net_preparse.c index c15bf772..2dfbf512 100644 --- a/engine/server/net_preparse.c +++ b/engine/server/net_preparse.c @@ -93,11 +93,7 @@ void NPP_Flush(void) int i; for (i = 0, cl = svs.clients; i < sv.allocated_client_slots; i++, cl++) { - if (cl->state == cs_spawned -#ifdef NQPROT - && !cl->nqprot -#endif - ) + if (cl->state == cs_spawned && ISQWCLIENT(cl)) { if (cl->zquake_extensions & Z_EXT_SERVERTIME) { @@ -167,11 +163,7 @@ void NPP_Flush(void) if (cldest) { if (!requireextension || cldest->fteprotocolextensions & requireextension) -#ifdef NQPROT - if (bufferlen && !cldest->nqprot) -#else - if (bufferlen) -#endif + if (bufferlen && ISQWCLIENT(cldest)) { ClientReliableCheckBlock(cldest, bufferlen); ClientReliableWrite_SZ(cldest, buffer, bufferlen); @@ -257,7 +249,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw) #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && cl->nqprot) + if (cl && !ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(qbyte)); ClientReliableWrite_Byte(cl, data); @@ -516,7 +508,7 @@ NPP_CheckDest(dest); #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && cl->nqprot) + if (cl && !ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(short)); ClientReliableWrite_Short(cl, data); @@ -539,7 +531,7 @@ void NPP_NQWriteLong(int dest, long data) //replacement write func (nq to qw) #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && cl->nqprot) + if (cl && !ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(long)); ClientReliableWrite_Long(cl, data); @@ -563,7 +555,7 @@ NPP_CheckDest(dest); if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && cl->nqprot) + if (cl && !ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(char)); ClientReliableWrite_Angle(cl, in); @@ -587,7 +579,7 @@ NPP_CheckDest(dest); #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && cl->nqprot) + if (cl && !ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(float)); ClientReliableWrite_Coord(cl, in); @@ -617,7 +609,7 @@ NPP_CheckDest(dest); #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && cl->nqprot) + if (cl && !ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, strlen(data)+1); ClientReliableWrite_String(cl, data); @@ -655,7 +647,7 @@ NPP_CheckDest(dest); #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && cl->nqprot) + if (cl && !ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(short)); ClientReliableWrite_Short(cl, data); @@ -717,13 +709,13 @@ void NPP_QWFlush(void) break; //ignore these. case svc_intermission: - if (writedest == &sv.reliable_datagram) +// if (writedest == &sv.reliable_datagram) { client_t *cl; int i; for (i = 0, cl = svs.clients; i < sv.allocated_client_slots; i++, cl++) { - if (cl->state == cs_spawned && cl->nqprot) + if (cl->state == cs_spawned && !ISQWCLIENT(cl)) { vec3_t org, ang; @@ -748,8 +740,9 @@ void NPP_QWFlush(void) ang[2] = (*(qbyte*)&buffer[7+2])*360.0/255; //move nq players to origin + angle - VectorCopy(cl->edict->v->origin, org); - VectorCopy(cl->edict->v->angles, ang); + VectorCopy(org, cl->edict->v->origin); + VectorCopy(ang, cl->edict->v->angles); + cl->edict->v->angles[0]*=-1; } } } @@ -758,7 +751,7 @@ void NPP_QWFlush(void) writedest = NULL; // case svc_finale: // bufferlen = 0; -// break; + break; case svc_setview: requireextension = PEXT_SETVIEW; // bufferlen = 0; @@ -854,7 +847,7 @@ void NPP_QWFlush(void) if (cldest) { if (!requireextension || cldest->fteprotocolextensions & requireextension) - if (bufferlen && cldest->nqprot) + if (bufferlen && !ISQWCLIENT(cldest)) { ClientReliableCheckBlock(cldest, bufferlen); ClientReliableWrite_SZ(cldest, buffer, bufferlen); @@ -937,7 +930,7 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw) #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && !cl->nqprot) + if (cl && ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(qbyte)); ClientReliableWrite_Byte(cl, data); @@ -1085,7 +1078,7 @@ void NPP_QWWriteChar(int dest, char data) //replacement write func (nq to qw) #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && !cl->nqprot) + if (cl && ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(char)); ClientReliableWrite_Char(cl, data); @@ -1110,7 +1103,7 @@ NPP_QWCheckDest(dest); #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && !cl->nqprot) + if (cl && ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(short)); ClientReliableWrite_Short(cl, data); @@ -1133,7 +1126,7 @@ void NPP_QWWriteLong(int dest, long data) //replacement write func (nq to qw) #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && !cl->nqprot) + if (cl && ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(long)); ClientReliableWrite_Long(cl, data); @@ -1156,7 +1149,7 @@ NPP_QWCheckDest(dest); #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && !cl->nqprot) + if (cl && ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(char)); ClientReliableWrite_Angle(cl, in); @@ -1179,7 +1172,7 @@ void NPP_QWWriteCoord(int dest, float in) //replacement write func (nq to qw) #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && !cl->nqprot) + if (cl && ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(float)); ClientReliableWrite_Coord(cl, in); @@ -1209,7 +1202,7 @@ void NPP_QWWriteString(int dest, char *data) //replacement write func (nq to qw) #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && !cl->nqprot) + if (cl && ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, strlen(data)+1); ClientReliableWrite_String(cl, data); @@ -1232,7 +1225,7 @@ NPP_QWCheckDest(dest); #ifdef NQPROT if (dest == MSG_ONE) { client_t *cl = Write_GetClient(); - if (cl && !cl->nqprot) + if (cl && ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, sizeof(short)); ClientReliableWrite_Short(cl, data); diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index e04b50b4..a1ecca8f 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -813,6 +813,12 @@ void PR_BreakPoint_f(void) #ifdef _DEBUG void QCLibTest(void) { + int size = 1024*1024*8; + char *buffer = BZ_Malloc(size); + svprogfuncs->save_ents(svprogfuncs, buffer, &size, 3); + COM_WriteFile("ssqccore.txt", buffer, size); + BZ_Free(buffer); + PR_TestForWierdness(svprogfuncs); } #endif @@ -3408,6 +3414,19 @@ void PF_precache_sound (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (!*sv.sound_precache[i]) { strcpy(sv.sound_precache[i], s); + + + if (sv.state != ss_loading) + { + MSG_WriteByte(&sv.reliable_datagram, svc_precache); + MSG_WriteShort(&sv.reliable_datagram, i+32768); + MSG_WriteString(&sv.reliable_datagram, s); +#ifdef NQPROT + MSG_WriteByte(&sv.nqreliable_datagram, svcdp_precache); + MSG_WriteShort(&sv.nqreliable_datagram, i+32768); + MSG_WriteString(&sv.nqreliable_datagram, s); +#endif + } return; } if (!strcmp(sv.sound_precache[i], s)) @@ -3451,6 +3470,18 @@ void PF_precache_model (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (!strcmp(s + strlen(s) - 4, ".bsp")) sv.models[i] = Mod_FindName(sv.model_precache[i]); + if (sv.state != ss_loading) + { + MSG_WriteByte(&sv.reliable_datagram, svc_precache); + MSG_WriteShort(&sv.reliable_datagram, i); + MSG_WriteString(&sv.reliable_datagram, s); +#ifdef NQPROT + MSG_WriteByte(&sv.nqreliable_datagram, svcdp_precache); + MSG_WriteShort(&sv.nqreliable_datagram, i); + MSG_WriteString(&sv.nqreliable_datagram, s); +#endif + } + return; } if (!strcmp(sv.model_precache[i], s)) @@ -3582,16 +3613,16 @@ void PF_walkmove (progfuncs_t *prinst, struct globalvars_s *pr_globals) // oldf = pr_xfunction; oldself = pr_global_struct->self; - if (!dist) - { - G_FLOAT(OFS_RETURN) = !SV_TestEntityPosition(ent); - } - else if (!SV_TestEntityPosition(ent)) - { +// if (!dist) +// { +// G_FLOAT(OFS_RETURN) = !SV_TestEntityPosition(ent); +// } +// else if (!SV_TestEntityPosition(ent)) +// { G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true, false, settrace); - if (SV_TestEntityPosition(ent)) - Con_Printf("Entity became stuck\n"); - } +// if (SV_TestEntityPosition(ent)) +// Con_Printf("Entity became stuck\n"); +// } // restore program state @@ -4527,7 +4558,7 @@ void PF_WriteEntity (progfuncs_t *prinst, struct globalvars_s *pr_globals) void PF_WriteString2 (progfuncs_t *prinst, struct globalvars_s *pr_globals) { int old; - char *str = PF_VarString(prinst, 1, pr_globals); + char *str; if (G_FLOAT(OFS_PARM0) != MSG_CSQC && (qc_nonetaccess.value || sv.demofile)) return; @@ -6025,6 +6056,8 @@ lh_extension_t QSG_Extensions[] = { {"FTE_STRINGS", 18, NULL, {"stof", "strlen","strcat","substring","stov","strzone","strunzone", "strstrofs", "str2chr", "chr2str", "strconv", "infoadd", "infoget", "strncmp", "strcasecmp", "strncasecmp"}}, + {"HYDR_WRITESTRING2", 1, NULL, {"writestring2"}}, + {"KRIMZON_SV_PARSECLIENTCOMMAND", 3, NULL, {"clientcommand", "tokenize", "argv"}}, //very very similar to the mvdsv system. {"QSG_CVARSTRING", 1, NULL, {"cvar_string"}}, {"QW_ENGINE"}, //warning: interpretation of .skin on players can be dodgy, as can some other QW features that differ from NQ. @@ -7781,13 +7814,105 @@ void PF_te_customflash(progfuncs_t *prinst, struct globalvars_s *pr_globals) //#408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE) void PF_te_particlecube(progfuncs_t *prinst, struct globalvars_s *pr_globals) { -#pragma message("PF_te_particlecube not implemented yet.") + float *min = G_VECTOR(OFS_PARM0); + float *max = G_VECTOR(OFS_PARM1); + float *dir = G_VECTOR(OFS_PARM2); + float count = G_FLOAT(OFS_PARM3); + float color = G_FLOAT(OFS_PARM4); + float gravityflag = G_FLOAT(OFS_PARM5); + float randomveljitter = G_FLOAT(OFS_PARM6); + + vec3_t org; + + if (count < 1) + return; + + // [vector] min [vector] max [vector] dir [short] count [byte] color [byte] gravity [coord] randomvel + + MSG_WriteByte (&sv.multicast, svc_temp_entity); + MSG_WriteByte (&sv.multicast, DPTE_PARTICLECUBE); + MSG_WriteCoord(&sv.multicast, min[0]); + MSG_WriteCoord(&sv.multicast, min[1]); + MSG_WriteCoord(&sv.multicast, min[2]); + MSG_WriteCoord(&sv.multicast, max[0]); + MSG_WriteCoord(&sv.multicast, max[1]); + MSG_WriteCoord(&sv.multicast, max[2]); + MSG_WriteCoord(&sv.multicast, dir[0]); + MSG_WriteCoord(&sv.multicast, dir[1]); + MSG_WriteCoord(&sv.multicast, dir[2]); + MSG_WriteShort(&sv.multicast, bound(0, count, 65535)); + MSG_WriteByte (&sv.multicast, bound(0, color, 255)); + MSG_WriteByte (&sv.multicast, (int)gravityflag!=0); + MSG_WriteCoord(&sv.multicast, randomveljitter); + +#ifdef NQPROT + MSG_WriteByte (&sv.nqmulticast, svc_temp_entity); + MSG_WriteByte (&sv.nqmulticast, DPTE_PARTICLECUBE); + MSG_WriteCoord(&sv.nqmulticast, min[0]); + MSG_WriteCoord(&sv.nqmulticast, min[1]); + MSG_WriteCoord(&sv.nqmulticast, min[2]); + MSG_WriteCoord(&sv.nqmulticast, max[0]); + MSG_WriteCoord(&sv.nqmulticast, max[1]); + MSG_WriteCoord(&sv.nqmulticast, max[2]); + MSG_WriteCoord(&sv.nqmulticast, dir[0]); + MSG_WriteCoord(&sv.nqmulticast, dir[1]); + MSG_WriteCoord(&sv.nqmulticast, dir[2]); + MSG_WriteShort(&sv.nqmulticast, bound(0, count, 65535)); + MSG_WriteByte (&sv.nqmulticast, bound(0, color, 255)); + MSG_WriteByte (&sv.nqmulticast, (int)gravityflag!=0); + MSG_WriteCoord(&sv.nqmulticast, randomveljitter); +#endif + + VectorAdd(min, max, org); + VectorScale(org, 0.5, org); + SV_Multicast(org, MULTICAST_PVS); } // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER) void PF_te_bloodshower(progfuncs_t *prinst, struct globalvars_s *pr_globals) { -#pragma message("PF_te_bloodshower not implemented yet.") + // [vector] min [vector] max [coord] explosionspeed [short] count + float *min = G_VECTOR(OFS_PARM0); + float *max = G_VECTOR(OFS_PARM1); + float speed = G_FLOAT(OFS_PARM2); + float count = G_FLOAT(OFS_PARM3); + vec3_t org; + + MSG_WriteByte(&sv.multicast, svc_temp_entity); + MSG_WriteByte(&sv.multicast, DPTE_BLOODSHOWER); + // min + MSG_WriteCoord(&sv.multicast, min[0]); + MSG_WriteCoord(&sv.multicast, min[1]); + MSG_WriteCoord(&sv.multicast, min[2]); + // max + MSG_WriteCoord(&sv.multicast, max[0]); + MSG_WriteCoord(&sv.multicast, max[1]); + MSG_WriteCoord(&sv.multicast, max[2]); + // speed + MSG_WriteCoord(&sv.multicast, speed); + // count + MSG_WriteShort(&sv.multicast, bound(0, count, 65535)); + +#ifdef NQPROT + MSG_WriteByte(&sv.nqmulticast, svc_temp_entity); + MSG_WriteByte(&sv.nqmulticast, DPTE_BLOODSHOWER); + // min + MSG_WriteCoord(&sv.nqmulticast, min[0]); + MSG_WriteCoord(&sv.nqmulticast, min[1]); + MSG_WriteCoord(&sv.nqmulticast, min[2]); + // max + MSG_WriteCoord(&sv.nqmulticast, max[0]); + MSG_WriteCoord(&sv.nqmulticast, max[1]); + MSG_WriteCoord(&sv.nqmulticast, max[2]); + // speed + MSG_WriteCoord(&sv.nqmulticast, speed); + // count + MSG_WriteShort(&sv.nqmulticast, bound(0, count, 65535)); +#endif + + VectorAdd(min, max, org); + VectorScale(org, 0.5, org); + SV_Multicast(org, MULTICAST_PVS); //fixme: should this be phs instead? } //DP_SV_EFFECT diff --git a/engine/server/savegame.c b/engine/server/savegame.c index d3ae9fcb..2a3cd358 100644 --- a/engine/server/savegame.c +++ b/engine/server/savegame.c @@ -975,7 +975,7 @@ void SV_Loadgame_f (void) if (cl->state <= cs_zombie) continue; - if (cl->isq2client) + if (cl->protocol == SCP_QUAKE2) MSG_WriteByte (&cl->netchan.message, svcq2_stufftext); else MSG_WriteByte (&cl->netchan.message, svc_stufftext); diff --git a/engine/server/server.h b/engine/server/server.h index 0bafcfef..2ffa66bb 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -106,6 +106,7 @@ typedef struct qboolean csqcdebug; double time; + float physicstime; //nq clients do so much better with times sent with physics than real. int framenum; int lastcheck; // used by PF_checkclient @@ -397,10 +398,6 @@ typedef struct client_s int backbuf_size[MAX_BACK_BUFFERS]; qbyte backbuf_data[MAX_BACK_BUFFERS][MAX_BACKBUFLEN]; -#ifdef NQPROT - qboolean nqprot; -#endif - double connection_started; // or time of disconnect for zombies qboolean send_message; // set on frames a datagram arived on @@ -416,12 +413,12 @@ typedef struct client_s int stats[MAX_CL_STATS]; union{ //save space - client_frame_t *frames; // updates can be deltad from here + client_frame_t *frames; // updates can be deltad from here #ifdef Q2SERVER - q2client_frame_t *q2frames; + q2client_frame_t *q2frames; #endif #ifdef Q3SERVER - q3client_frame_t *q3frames; + q3client_frame_t *q3frames; #endif }; FILE *download; // file being downloaded @@ -490,7 +487,14 @@ typedef struct client_s unsigned long fteprotocolextensions; #endif unsigned long zquake_extensions; - int isq2client; //contains protocol version too. + + enum { + SCP_BAD, + SCP_QUAKEWORLD, + SCP_NETQUAKE, + SCP_DARKPLACES, + SCP_QUAKE2 + } protocol; //speed cheat testing int msecs; @@ -522,6 +526,10 @@ typedef struct client_s int drate; } client_t; +#define ISQWCLIENT(cl) ((cl)->protocol == SCP_QUAKEWORLD) +#define ISQ2CLIENT(cl) ((cl)->protocol == SCP_QUAKE2) +#define ISNQCLIENT(cl) ((cl)->protocol == SCP_NETQUAKE || (cl)->protocol == SCP_DARKPLACES) + // a client can leave the server in one of four ways: // dropping properly by quiting or disconnecting // timing out if no valid messages are received for timeout.value seconds diff --git a/engine/server/sv_ccmds.c b/engine/server/sv_ccmds.c index ab447050..1c8caa1e 100644 --- a/engine/server/sv_ccmds.c +++ b/engine/server/sv_ccmds.c @@ -141,31 +141,21 @@ Make a master server current */ void SV_SetMaster_f (void) { - char data[2]; int i; Cvar_Set(&sv_public, "1"); //go public. - memset (&master_adr, 0, sizeof(master_adr)); + Master_ClearAll(); + + if (!strcmp(Cmd_Argv(1), "none")) + { + Con_Printf ("Entering no-master mode\n"); + return; + } for (i=1 ; iisq2client) + if (cl->protocol == SCP_QUAKE2) ClientReliableWrite_Begin (cl, svcq2_stufftext, 3+strlen(str) + (key?strlen(key)+6:0)); else ClientReliableWrite_Begin (cl, svc_stufftext, 3+strlen(str) + (key?strlen(key)+6:0)); @@ -895,8 +885,8 @@ void SV_Status_f (void) if (!sv.state) { - if (net_local_ipadr.type != NA_LOOPBACK) - Con_Printf ("ip address : %s\n",NET_AdrToString (net_local_ipadr)); + if (net_local_sv_ipadr.type != NA_LOOPBACK) + Con_Printf ("ip address : %s\n",NET_AdrToString (net_local_sv_ipadr)); Con_Printf("Server is not running\n"); return; @@ -911,8 +901,8 @@ void SV_Status_f (void) avg = 1000*svs.stats.latched_active / STATFRAMES; pak = (float)svs.stats.latched_packets/ STATFRAMES; - if (net_local_ipadr.type != NA_LOOPBACK) - Con_Printf ("ip address : %s\n",NET_AdrToString (net_local_ipadr)); + if (net_local_sv_ipadr.type != NA_LOOPBACK) + Con_Printf ("ip address : %s\n",NET_AdrToString (net_local_sv_ipadr)); Con_Printf ("cpu utilization : %3i%%\n",(int)cpu); Con_Printf ("avg response time: %i ms\n",(int)avg); Con_Printf ("packets/frame : %5.2f\n", pak); //not relevent as a limit. diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index f392e00f..90108eda 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -1300,7 +1300,7 @@ void SV_WritePlayersToClient (client_t *client, edict_t *clent, qbyte *pvs, size #ifdef NQPROT - if (client->nqprot) + if (!ISQWCLIENT(client)) return; #endif @@ -1658,12 +1658,6 @@ unsigned int bits=0; int glowsize, glowcolor; - if (ent->v->modelindex >= 256) //as much as protocols can handle - return; - - if (entnum >= 768) //too many for a conventional nq client. - return; - for (i=0 ; i<3 ; i++) { miss = ent->v->origin[i] - ent->baseline.origin[i]; @@ -1697,14 +1691,14 @@ int glowsize, glowcolor; if ((ent->baseline.effects & 0x00ff) != ((int)eff & 0x00ff)) bits |= NQU_EFFECTS; - if (/*ent->baseline.modelindex !=*/ ent->v->modelindex) + if (ent->baseline.modelindex != ent->v->modelindex) bits |= NQU_MODEL; if (entnum >= 256) bits |= NQU_LONGENTITY; -// if (usedpextensions) + if (1) { if (ent->baseline.trans != ent->v->alpha) if (!(ent->baseline.trans == 1 && !ent->v->alpha)) @@ -1715,9 +1709,17 @@ int glowsize, glowcolor; bits |= DPU_SCALE; } + if (ent->v->modelindex >= 256) //as much as protocols can handle + bits |= DPU_MODEL2; + if ((ent->baseline.effects&0xff00) != ((int)eff & 0xff00)) bits |= DPU_EFFECTS2; + if (ent->v->exteriormodeltoclient == EDICT_TO_PROG(svprogfuncs, host_client->edict)) + bits |= DPU_EXTERIORMODEL; + if (ent->v->viewmodelforclient == EDICT_TO_PROG(svprogfuncs, host_client->edict)) + bits |= DPU_VIEWMODEL; + glowsize = ent->v->glow_size*0.25f; glowcolor = ent->v->glow_color; @@ -1727,14 +1729,21 @@ int glowsize, glowcolor; if (0 != glowcolor) bits |= DPU_GLOWCOLOR; } + else + { + if (ent->v->modelindex >= 256) //as much as protocols can handle + return; + if (entnum >= 768) //too many for a conventional nq client. + return; + } - if (bits & 0xFF00) - bits |= NQU_MOREBITS; - if (bits & 0xFF0000) - bits |= DPU_EXTEND1; if (bits & 0xFF000000) bits |= DPU_EXTEND2; + if (bits & 0xFF0000) + bits |= DPU_EXTEND1; + if (bits & 0xFF00) + bits |= NQU_MOREBITS; // @@ -1932,7 +1941,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore client_frame_t *frame; entity_state_t *state; #ifdef NQPROT - int nqprot = client->nqprot; + int nqprot = !ISQWCLIENT(client); #endif client_t *split; @@ -1988,6 +1997,8 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore pvs = fatpvs; + host_client = client; + // send over the players in the PVS SV_WritePlayersToClient (client, clent, pvs, msg); @@ -2146,10 +2157,14 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore } } -/* if (!ignorepvs) + if (!ignorepvs && ent != clent) { //branch out to the pvs testing. - if (ent->tagent) + if (ent->v->viewmodelforclient == EDICT_TO_PROG(svprogfuncs, client->edict)) + { + //unconditional + } + else if (ent->tagent) { edict_t *p = ent; int c = 10; @@ -2166,7 +2181,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore continue; } } -*/ + @@ -2205,7 +2220,9 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore #ifdef NQPROT if (nqprot) { - SVNQ_EmitEntity(msg, ent, e); + if (msg->cursize + 32 > msg->maxsize) + break; + SVNQ_EmitEntity(msg, ent, e); continue; } #endif diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 0d64fa26..1f737638 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -520,11 +520,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us for (i = 0; i < MAX_CLIENTS; i++) { - if (svs.clients[i].state -#ifdef NQPROT - && !svs.clients[i].nqprot -#endif - ) + if (svs.clients[i].state && ISQWCLIENT(&svs.clients[i])) ReloadRanking(&svs.clients[i], svs.clients[i].name); if (svs.clients[i].spawninfo) //don't remember this stuff. diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 27b0a805..5727bba7 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -43,7 +43,26 @@ double realtime; // without any filtering or bounding int host_hunklevel; -netadr_t master_adr[MAX_MASTERS]; // address of group servers +typedef struct { + qboolean isdp; + cvar_t cv; + netadr_t adr; +} sv_masterlist_t; +sv_masterlist_t sv_masterlist[] = { + {false, {"sv_master1", ""}}, + {false, {"sv_master2", ""}}, + {false, {"sv_master3", ""}}, + {false, {"sv_master4", ""}}, + {false, {"sv_master5", ""}}, + {false, {"sv_master6", ""}}, + {false, {"sv_master7", ""}}, + {false, {"sv_master8", ""}}, + + {true, {"sv_masterextra1", "ghdigital.com"}}, //69.59.212.88 + {true, {"sv_masterextra2", "dpmaster.deathmask.net"}}, //209.164.24.243 + {true, {"sv_masterextra3", "12.166.196.192"}}, //blaze.mindphukd.org (doesn't resolve currently but works as an ip) + {false, {NULL}} +}; client_t *host_client; // current client @@ -302,7 +321,19 @@ void SV_DropClient (client_t *drop) } // add the disconnect if (drop->state != cs_zombie) - MSG_WriteByte (&drop->netchan.message, drop->isq2client?svcq2_disconnect:svc_disconnect); + { + switch (drop->protocol) + { + case SCP_QUAKE2: + MSG_WriteByte (&drop->netchan.message, svcq2_disconnect); + break; + case SCP_QUAKEWORLD: + case SCP_NETQUAKE: + case SCP_DARKPLACES: + MSG_WriteByte (&drop->netchan.message, svc_disconnect); + break; + } + } #ifdef SVRANKING if (drop->state == cs_spawned) @@ -341,11 +372,9 @@ void SV_DropClient (client_t *drop) SV_WipeChat(drop); #endif #ifdef Q2SERVER - if (drop->isq2client==1) - if (ge) - ge->ClientDisconnect(drop->q2edict); + if (ge) + ge->ClientDisconnect(drop->q2edict); #endif - if (drop->isq2client == 0) if (svprogfuncs) { if (drop->state == cs_spawned) @@ -418,18 +447,7 @@ void SV_DropClient (client_t *drop) drop->name[0] = 0; memset (drop->userinfo, 0, sizeof(drop->userinfo)); -#ifdef Q2SERVER - if (drop->isq2client) - { - if (drop->q2frames) - { - Z_Free(drop->q2frames); - drop->q2frames = NULL; - } - } - else -#endif - if (drop->frames) + if (drop->frames) //union of the same sort of structure { Z_Free(drop->frames); drop->frames = NULL; @@ -442,13 +460,6 @@ void SV_DropClient (client_t *drop) SV_FullClientUpdate (drop, &sv.reliable_datagram); #ifdef NQPROT SVNQ_FullClientUpdate (drop, &sv.nqreliable_datagram); - - - if (drop->netchan.qsocket) - { - NET_Close(drop->netchan.qsocket); - drop->netchan.qsocket = NULL; - } #endif if (drop->controlled) @@ -474,24 +485,31 @@ int SV_CalcPing (client_t *cl) int count; register client_frame_t *frame; - if (!cl->frames || cl->isq2client) + if (!cl->frames) return 0; - ping = 0; - count = 0; - for (frame = cl->frames, i=0 ; iprotocol) { - if (frame->ping_time > 0) + case SCP_NETQUAKE: + case SCP_DARKPLACES: + case SCP_QUAKEWORLD: + ping = 0; + count = 0; + for (frame = cl->frames, i=0 ; iping_time; - count++; + if (frame->ping_time > 0) + { + ping += frame->ping_time; + count++; + } } - } - if (!count) - return 9999; - ping /= count; + if (!count) + return 9999; + ping /= count; - return ping*1000; + return ping*1000; + } + return 0; } /* @@ -610,7 +628,7 @@ Writes all update values to a client's reliable stream void SV_FullClientUpdateToClient (client_t *client, client_t *cl) { #ifdef NQPROT - if (cl->nqprot) + if (!ISQWCLIENT(cl)) { ClientReliableCheckBlock(cl, 24 + strlen(client->userinfo)); if (cl->num_backbuf) { @@ -704,6 +722,45 @@ void SVC_Status (void) SV_EndRedirect (); } +void SVC_GetInfo (char *challenge) +{ + //dpmaster support + + client_t *cl; + int numclients = 0; + int i; + char *resp; + + if (!*challenge) + challenge = NULL; + + for (i=0 ; istate == cs_connected || cl->state == cs_spawned || cl->name[0]) && !cl->spectator) + numclients++; + } + + + resp = va("\377\377\377\377infoResponse\x0A" + "\\gamename\\%s" + "\\protocol\\%i" + "\\clients\\%d" + "\\sv_maxclients\\%s\\mapname\\%s" + "%s" + "%s%s", + com_gamename.string, + NET_PROTOCOL_VERSION, + numclients, + maxclients.string, Info_ValueForKey(svs.info, "map"), + svs.info, + challenge ? "\\challenge\\" : "", challenge ? challenge : ""); + Info_RemoveKey(resp + 17, "maxclients"); + Info_RemoveKey(resp + 17, "map"); + + NET_SendPacket (NS_SERVER, strlen(resp), resp, net_from); +} + void SVC_InfoQ2 (void) { char string[64]; @@ -810,6 +867,36 @@ void SVC_Ping (void) NET_SendPacket (NS_SERVER, 1, &data, net_from); } +//from net_from +int SV_NewChallenge (void) +{ + int i; + int oldest; + int oldestTime; + + oldest = 0; + oldestTime = 0x7fffffff; + + // see if we already have a challenge for this ip + for (i = 0 ; i < MAX_CHALLENGES ; i++) + { + if (NET_CompareBaseAdr (net_from, svs.challenges[i].adr)) + return svs.challenges[i].challenge; + if (svs.challenges[i].time < oldestTime) + { + oldestTime = svs.challenges[i].time; + oldest = i; + } + } + + // overwrite the oldest + svs.challenges[oldest].challenge = (rand() << 16) ^ rand(); + svs.challenges[oldest].adr = net_from; + svs.challenges[oldest].time = realtime; + + return svs.challenges[oldest].challenge; +} + /* ================= SVC_GetChallenge @@ -904,113 +991,16 @@ void SVC_GetChallenge (void) } #endif } - Netchan_OutOfBand(NS_SERVER, net_from, strlen(buf)+1+4+4, buf); + Netchan_OutOfBand(NS_SERVER, net_from, over-buf, buf); + + + buf = va("challenge %i", svs.challenges[i].challenge); + Netchan_OutOfBand(NS_SERVER, net_from, strlen(buf)+1, buf); } // Netchan_OutOfBandPrint (net_from, "%c%i", S2C_CHALLENGE, // svs.challenges[i].challenge); } -#ifdef NQPROT -void SVC_GetChallengeQSocket (qsocket_t *sock) -{ - int i; - int oldest; - int oldestTime; - - oldest = 0; - oldestTime = 0x7fffffff; - - // see if we already have a challenge for this ip - for (i = 0 ; i < MAX_CHALLENGES ; i++) - { - if (NET_CompareBaseAdr (net_from, svs.challenges[i].adr)) - break; - if (svs.challenges[i].time < oldestTime) - { - oldestTime = svs.challenges[i].time; - oldest = i; - } - } - - if (i == MAX_CHALLENGES) - { - // overwrite the oldest - svs.challenges[oldest].challenge = (rand() << 16) ^ rand(); - svs.challenges[oldest].adr = net_from; - svs.challenges[oldest].time = realtime; - i = oldest; - } - - // send it back - { - char *buf; - int lng; - char *over; - buf = va(" %c%i", S2C_CHALLENGE, svs.challenges[i].challenge); - - over = buf + strlen(buf) + 1; -#ifdef PROTOCOL_VERSION_FTE - //tell the client what fte extensions we support - if (svs.fteprotocolextensions) - { - lng = LittleLong(PROTOCOL_VERSION_FTE); - memcpy(over, &lng, sizeof(int)); - over+=4; - - lng = LittleLong(svs.fteprotocolextensions); - memcpy(over, &lng, sizeof(long)); - over+=4; - } -#endif - - { - sizebuf_t msg; - msg.data = buf; - *(int *)buf = -1; - msg.cursize = strlen(buf)+1+4+4; - NET_SendMessage(sock, &msg); - } -// Netchan_OutOfBand(svs.socket, net_from, strlen(buf)+1+4+4, buf); - } - -// Netchan_OutOfBandPrint (net_from, "%c%i", S2C_CHALLENGE, -// svs.challenges[i].challenge); -} -#endif - - -void SVC_DecodeConnect (void) -{ - qbyte msg[1024]; - int msglen = net_message.cursize; - int firstcoded; - - netadr_t validater; - validater.type = NA_IP; - validater.ip[0] = 127; - validater.ip[1] = 0; - validater.ip[2] = 0; - validater.ip[3] = 1; - validater.port = BigShort(20235); - - msg[0] = 255;msg[1] = 255;msg[2] = 255;msg[3] = 255; - msg[4] = 'v'; - msg[5] = 6+13+6; - msglen = 6; - strcpy(msg+msglen, "validconnect "); - msglen+=strlen(msg+msglen); - strcpy(msg+msglen, NET_AdrToString(net_from)); - strcat(msg+msglen, " "); - msglen+=strlen(msg+msglen); -// memcpy(msg+msglen, &net_from, 6); -// msglen+=6; - firstcoded = msglen; - memcpy(msg+msglen, net_message.data+18, net_message.cursize-18); - msglen += net_message.cursize-18; - - msg[5] = firstcoded; - Netchan_OutOfBand(NS_SERVER, validater, msglen-4, msg+4); -} void SV_GetNewSpawnParms(client_t *cl) { @@ -1085,6 +1075,93 @@ qboolean SV_ChallengePasses(int challenge) return false; } +void SV_RejectMessage(int protocol, char *format, ...) +{ + va_list argptr; + char string[8192]; + int len; + + va_start (argptr, format); + switch(protocol) + { +#ifdef NQPROT + case SCP_NETQUAKE: + string[4] = CCREP_REJECT; + _vsnprintf (string+5,sizeof(string)-1-5, format,argptr); + len = strlen(string+4)+1+4; + *(int*)string = BigLong(NETFLAG_CTL|len); + NET_SendPacket(NS_SERVER, len, string, net_from); + return; + case SCP_DARKPLACES: + strcpy(string, "reject "); + _vsnprintf (string+7,sizeof(string)-1-7, format,argptr); + len = strlen(string); + break; +#endif + + case SCP_QUAKE2: + default: + strcpy(string, "print\n"); + _vsnprintf (string+6,sizeof(string)-1-6, format,argptr); + len = strlen(string); + break; + + case SCP_QUAKEWORLD: + string[0] = A2C_PRINT; + string[1] = '\n'; + _vsnprintf (string+2,sizeof(string)-1-2, format,argptr); + len = strlen(string); + break; + } + va_end (argptr); + + Netchan_OutOfBand (NS_SERVER, net_from, len, (qbyte *)string); +} + +void SV_AcceptMessage(int protocol) +{ + char string[8192]; + sizebuf_t sb; + int len; + + memset(&sb, 0, sizeof(sb)); + sb.maxsize = sizeof(string); + sb.data = string; + + switch(protocol) + { +#ifdef NQPROT + case SCP_NETQUAKE: + SZ_Clear(&sb); + MSG_WriteLong(&sb, 0); + MSG_WriteByte(&sb, CCREP_ACCEPT); + MSG_WriteLong(&sb, BigShort(net_local_sv_ipadr.port)); + *(int*)sb.data = BigLong(NETFLAG_CTL|sb.cursize); + NET_SendPacket(NS_SERVER, sb.cursize, sb.data, net_from); + return; + case SCP_DARKPLACES: + strcpy(string, "accept"); + len = strlen(string); + break; +#endif + + case SCP_QUAKE2: + default: + strcpy(string, "print\n"); + len = strlen(string); + break; + + case SCP_QUAKEWORLD: + string[0] = S2C_CONNECTION; + string[1] = '\n'; + string[2] = '\0'; + len = strlen(string); + break; + } + + Netchan_OutOfBand (NS_SERVER, net_from, len, (qbyte *)string); +} + /* ================== SVC_DirectConnect @@ -1093,12 +1170,7 @@ A connection request that did not come from the master ================== */ int nextuserid; -void SVC_DirectConnect -#ifdef NQPROT - (qsocket_t *socket) -#else - (void) -#endif +client_t *SVC_DirectConnect(void) { char userinfo[MAX_CLIENTS][2048]; netadr_t adr; @@ -1120,54 +1192,79 @@ void SVC_DirectConnect int maxpacketentities; - int numssclients; + int numssclients = 1; - qboolean isquake2client = false; + int protocol; unsigned int protextsupported=0; char *name; - numssclients = 1; - if (atoi(Cmd_Argv(0)+7)) + if (*(Cmd_Argv(0)+7) == '\\') { -#ifdef NQPROT - if (!socket) -#endif - numssclients = atoi(Cmd_Argv(0)+7); - if (numssclients<1) + Q_strncpyz (userinfo[0], net_message.data + 11, sizeof(userinfo[0])-1); + + if (strcmp(Info_ValueForKey(userinfo[0], "protocol"), "darkplaces 3")) { - SV_OutOfBandPrintf (false, net_from, "\nServer is version %4.2f.\n", VERSION); - Con_Printf ("* rejected connect from broken client\n"); - return; + SV_RejectMessage (SCP_BAD, "Server is version %4.2f.\n", VERSION); + Con_Printf ("* rejected connect from incompatable client\n"); + return NULL; } - } - version = atoi(Cmd_Argv(1)); - if (version >= 31 && version <= 34) + + //it's a darkplaces client. + protocol = SCP_DARKPLACES; + challenge = atoi(Info_ValueForKey(userinfo[0], "challenge")); + + qport = 0; + } + else { - numssclients = 1; + if (atoi(Cmd_Argv(0)+7)) + { + #ifdef NQPROT + if (!socket) + #endif + numssclients = atoi(Cmd_Argv(0)+7); + if (numssclients<1 || numssclients > 4) + { + SV_RejectMessage (SCP_BAD, "Server is version %4.2f.\n", VERSION); + Con_Printf ("* rejected connect from broken client\n"); + return NULL; + } + } - //quake2 - isquake2client = version; - } - else if (version != PROTOCOL_VERSION) - { - SV_OutOfBandPrintf (false, net_from, "\nServer is version %4.2f.\n", VERSION); - Con_Printf ("* rejected connect from version %i\n", version); - return; + version = atoi(Cmd_Argv(1)); + if (version >= 31 && version <= 34) + { + numssclients = 1; + protocol = SCP_QUAKE2; + } + else if (version == 3) + { + numssclients = 1; + protocol = SCP_NETQUAKE; + } + else if (version != PROTOCOL_VERSION) + { + SV_RejectMessage (SCP_BAD, "Server is version %4.2f.\n", VERSION); + Con_Printf ("* rejected connect from version %i\n", version); + return NULL; + } + else + protocol = SCP_QUAKEWORLD; + + qport = atoi(Cmd_Argv(2)); + + challenge = atoi(Cmd_Argv(3)); + + // note an extra qbyte is needed to replace spectator key + for (i = 0; i < numssclients; i++) + Q_strncpyz (userinfo[i], Cmd_Argv(4+i), sizeof(userinfo[i])-1); } - qport = atoi(Cmd_Argv(2)); - - challenge = atoi(Cmd_Argv(3)); - - // note an extra qbyte is needed to replace spectator key - for (i = 0; i < numssclients; i++) - Q_strncpyz (userinfo[i], Cmd_Argv(4+i), sizeof(userinfo[i])-1); - - if (!isquake2client) //readd? + if (protocol == SCP_QUAKEWORLD) //readd? { while(!msg_badread) { @@ -1205,15 +1302,10 @@ void SVC_DirectConnect // see if the challenge is valid if (!SV_ChallengePasses(challenge)) { - SV_OutOfBandPrintf (isquake2client, net_from, "\nBad challenge.\n"); - return; + SV_RejectMessage (protocol, "Bad challenge.\n"); + return NULL; } } - if (i == MAX_CHALLENGES) - { - SV_OutOfBandPrintf (isquake2client, net_from, "No challenge for address.\n"); - return; - } // check for password or spectator_password if (svprogfuncs) @@ -1226,8 +1318,8 @@ void SVC_DirectConnect strcmp(spectator_password.string, s) ) { // failed Con_Printf ("%s:spectator password failed\n", NET_AdrToString (net_from)); - SV_OutOfBandPrintf (isquake2client, net_from, "\nrequires a spectator password\n\n"); - return; + SV_RejectMessage (protocol, "requires a spectator password\n\n"); + return NULL; } Info_RemoveKey (userinfo[0], "spectator"); // remove key Info_SetValueForStarKey (userinfo[0], "*spectator", "1", sizeof(userinfo[0])); @@ -1241,8 +1333,8 @@ void SVC_DirectConnect strcmp(password.string, s) ) { Con_Printf ("%s:password failed\n", NET_AdrToString (net_from)); - SV_OutOfBandPrintf (isquake2client, net_from, "\nserver requires a password\n\n"); - return; + SV_RejectMessage (protocol, "server requires a password\n\n"); + return NULL; } spectator = false; Info_RemoveKey (userinfo[0], "password"); // remove passwd @@ -1260,9 +1352,7 @@ void SVC_DirectConnect newcl->userid = nextuserid; newcl->fteprotocolextensions = protextsupported; -#ifdef NQPROT - newcl->nqprot = false; -#endif + newcl->protocol = protocol; if (sv.msgfromdemo) newcl->wasrecorded = true; @@ -1293,7 +1383,7 @@ void SVC_DirectConnect if (cl->state == cs_connected) { Con_Printf("%s:dup connect\n", NET_AdrToString (adr)); nextuserid--; - return; + return NULL; } #ifdef NQPROT if (!socket) @@ -1308,13 +1398,13 @@ void SVC_DirectConnect name = Info_ValueForKey (temp.userinfo, "name"); - if (!isquake2client &&!atoi(Info_ValueForKey (temp.userinfo, "iknow"))) + if (protocol == SCP_QUAKEWORLD &&!atoi(Info_ValueForKey (temp.userinfo, "iknow"))) { if (sv.worldmodel->fromgame == fg_halflife && !(newcl->fteprotocolextensions & PEXT_HLBSP)) { if (atof(Info_ValueForKey (temp.userinfo, "*FuhQuake")) < 0.3) { - SV_OutOfBandPrintf (isquake2client, adr, "%c\nThe server is using a halflife level and we don't think your client supports this\nuse 'setinfo iknow 1' to ignore this check\nYou can go to "ENGINEWEBSITE" to get a compatable client\n\nYou may need to enable an option\n\n", A2C_PRINT); + SV_RejectMessage (protocol, "The server is using a halflife level and we don't think your client supports this\nuse 'setinfo iknow 1' to ignore this check\nYou can go to "ENGINEWEBSITE" to get a compatable client\n\nYou may need to enable an option\n\n"); // Con_Printf("player %s was dropped due to incompatable client\n", name); // return; } @@ -1322,7 +1412,7 @@ void SVC_DirectConnect #ifdef PEXT_Q2BSP else if (sv.worldmodel->fromgame == fg_quake2 && !(newcl->fteprotocolextensions & PEXT_Q2BSP)) { - SV_OutOfBandPrintf (isquake2client, adr, "%c\nThe server is using a quake 2 level and we don't think your client supports this\nuse 'setinfo iknow 1' to ignore this check\nYou can go to "ENGINEWEBSITE" to get a compatable client\n\nYou may need to enable an option\n\n", A2C_PRINT); + SV_RejectMessage (protocol, "The server is using a quake 2 level and we don't think your client supports this\nuse 'setinfo iknow 1' to ignore this check\nYou can go to "ENGINEWEBSITE" to get a compatable client\n\nYou may need to enable an option\n\n"); // Con_Printf("player %s was dropped due to incompatable client\n", name); // return; } @@ -1330,7 +1420,7 @@ void SVC_DirectConnect #ifdef PEXT_Q3BSP else if (sv.worldmodel->fromgame == fg_quake3 && !(newcl->fteprotocolextensions & PEXT_Q3BSP)) { - SV_OutOfBandPrintf (isquake2client, adr, "%c\nThe server is using a quake 3 level and we don't think your client supports this\nuse 'setinfo iknow 1' to ignore this check\nYou can go to "ENGINEWEBSITE" to get a compatable client\n\nYou may need to enable an option\n\n", A2C_PRINT); + SV_RejectMessage (protocol, "The server is using a quake 3 level and we don't think your client supports this\nuse 'setinfo iknow 1' to ignore this check\nYou can go to "ENGINEWEBSITE" to get a compatable client\n\nYou may need to enable an option\n\n"); // Con_Printf("player %s was dropped due to incompatable client\n", name); // return; } @@ -1371,12 +1461,6 @@ void SVC_DirectConnect } } } -#ifdef NQPROT - else if (socket && cl->netchan.qsocket == socket) - { - newcl = cl; //replace this slot - it was a place holder for a qw protocol over nq transports. - } -#endif } if (!newcl) //client has no slot. It's possible to bipass this if server is loading a game. (or a duplicated qsocket) @@ -1393,8 +1477,8 @@ void SVC_DirectConnect || (clients + spectators >= sv.allocated_client_slots) )) { Con_Printf ("%s:full connect\n", NET_AdrToString (adr)); - SV_OutOfBandPrintf (isquake2client, adr, "\nserver is full\n\n"); - return; + SV_RejectMessage (protocol, "\nserver is full\n\n"); + return NULL; } // find a client slot @@ -1413,9 +1497,9 @@ void SVC_DirectConnect else { Con_Printf ("%s:full connect\n", NET_AdrToString (adr)); - SV_OutOfBandPrintf (isquake2client, adr, "\nserver is full\n\n"); + SV_RejectMessage (protocol, "server is full\n\n"); } - return; + return NULL; } } @@ -1428,16 +1512,16 @@ void SVC_DirectConnect { if (NET_CompareAdr (adr, newcl->netchan.remote_address)) { - SV_OutOfBandPrintf (isquake2client, adr, "\nYou were banned.\nContact the administrator to complain.\n"); - return; + SV_RejectMessage (protocol, "You were banned.\nContact the administrator to complain.\n"); + return NULL; } } else { if (NET_CompareBaseAdr (adr, newcl->netchan.remote_address)) { - SV_OutOfBandPrintf (isquake2client, adr, "\nYou were banned.\nContact the administrator to complain.\n"); - return; + SV_RejectMessage (protocol, "You were banned.\nContact the administrator to complain.\n"); + return NULL; } } } @@ -1480,7 +1564,7 @@ void SVC_DirectConnect temp.q2edict = q2ent; if (!ge->ClientConnect(q2ent, temp.userinfo)) - return; + return NULL; ge->ClientUserinfoChanged(q2ent, temp.userinfo); @@ -1516,6 +1600,9 @@ void SVC_DirectConnect else newcl->netchan.compress = false; + newcl->protocol = protocol; + newcl->netchan.isnqprotocol = ISNQCLIENT(newcl); + newcl->state = cs_connected; newcl->datagram.allowoverflow = true; @@ -1524,8 +1611,6 @@ void SVC_DirectConnect // spectator mode can ONLY be set at join time newcl->spectator = spectator; - - newcl->isq2client = isquake2client; // parse some info from the info strings SV_ExtractFromUserinfo (newcl); @@ -1548,9 +1633,9 @@ void SVC_DirectConnect { if (rank_needlogin.value) { - SV_OutOfBandPrintf (isquake2client, adr, "\nBad password/username\nThis server requires logins. Please see the serverinfo for website and info on how to register.\n"); + SV_RejectMessage (protocol, "Bad password/username\nThis server requires logins. Please see the serverinfo for website and info on how to register.\n"); newcl->state = cs_free; - return; + return NULL; } // SV_OutOfBandPrintf (isquake2client, adr, "\nWARNING: You have not got a place on the ranking system, probably because a user with the same name has already connected and your pwds differ.\n\n"); @@ -1562,22 +1647,22 @@ void SVC_DirectConnect rankstats_t rs; if (!Rank_GetPlayerStats(newcl->rankid, &rs)) { - SV_OutOfBandPrintf (isquake2client, adr, "\nRankings/Account system failed\n"); + SV_RejectMessage (protocol, "Rankings/Account system failed\n"); Con_Printf("banned player %s is trying to connect\n", newcl->name); newcl->name[0] = 0; memset (newcl->userinfo, 0, sizeof(newcl->userinfo)); newcl->state = cs_free; - return; + return NULL; } if (rs.flags1 & RANK_BANNED) { - SV_OutOfBandTPrintf (isquake2client, adr, newcl->language, STL_YOUAREBANNED); + SV_RejectMessage (protocol, "You were banned.\nContact the administrator to complain.\n"); Con_Printf("banned player %s is trying to connect\n", newcl->name); newcl->name[0] = 0; memset (newcl->userinfo, 0, sizeof(newcl->userinfo)); newcl->state = cs_free; - return; + return NULL; } if (rs.flags1 & RANK_MUTED) @@ -1613,13 +1698,13 @@ void SVC_DirectConnect else //measure this guy in minuites. s = va(langtext(STL_SHORTGREETING, newcl->language), newcl->name, (int)(rs.timeonserver/60)); - SV_OutOfBandPrintf (isquake2client, adr, s); + SV_OutOfBandPrintf (protocol == SCP_QUAKE2, adr, s); } else if (!cl->istobeloaded) { SV_GetNewSpawnParms(newcl); - SV_OutOfBandTPrintf (isquake2client, adr, newcl->language, STL_FIRSTGREETING, newcl->name, (int)rs.timeonserver); + SV_OutOfBandTPrintf (protocol == SCP_QUAKE2, adr, newcl->language, STL_FIRSTGREETING, newcl->name, (int)rs.timeonserver); } //else loaded players already have thier initial parms set } @@ -1635,25 +1720,7 @@ void SVC_DirectConnect if (!newcl->wasrecorded) { -#ifdef NQPROT - if (socket) - { - sizebuf_t msg; - char data[64]; - *(int*)data = -1; - data[4] = S2C_CONNECTION; - data[5] = 0; - msg.data = data; - msg.cursize = 5; - newcl->netchan.qsocket = socket; - NET_SendMessage(socket, &msg); - } - else -#endif - if (isquake2client) - Netchan_OutOfBandPrint (NS_SERVER, adr, "client_connect"); - else - Netchan_OutOfBandPrint (NS_SERVER, adr, "%c", S2C_CONNECTION ); + SV_AcceptMessage (protocol); if (newcl->spectator) { @@ -1742,144 +1809,18 @@ void SVC_DirectConnect Sys_ServerActivity(); -} -void SV_ClearClient(client_t *cl) -{ - client_frame_t *frames = cl->frames; - char *on, *ot; - on = cl->name; - ot = cl->team; - memset(cl, 0, sizeof(client_t)); - cl->name = on; - cl->team = ot; - cl->frames = frames; - if (frames) - memset(frames, 0, sizeof(client_frame_t)*UPDATE_BACKUP); -} -#ifdef NQPROT -//FIXME: move to header -void SV_New_f (void); -void SVNQ_New_f (void); -void SVNQ_CheckForNewClients(void) -{ - client_t *newcl, *cl; - struct qsocket_s *ret; - int i; - netadr_t addr; - - edict_t *ent; - -#ifdef Q2SERVER - if (ge) //disable nq entirly if using q2. - return; -#endif - -// -// check for new connections -// - while (1) + if (ISNQCLIENT(newcl)) { - ret = NET_CheckNewConnections (); - if (!ret) - break; - - *(int*)net_from.ip = 0; - -/* SVC_DirectConnect(); - net_activeconnections++; - return; -*/ - - newcl = NULL; - for (i=0,cl=svs.clients ; inetchan.qsocket == ret) - SV_DropClient(cl); - } - - for (i=0,cl=svs.clients ; istate != cs_free) - continue; - - break; - } - if (i==MAX_CLIENTS) - Sys_Error("Erm... Out of client slots. Hmm.."); - - SV_ClearClient(cl); - if (cl->frames) - Z_Free(cl->frames); - cl->frames = Z_Malloc((sizeof(client_frame_t)+sizeof(entity_state_t)*MAX_STANDARD_PACKET_ENTITIES)*UPDATE_BACKUP); - for (i = 0; i < UPDATE_BACKUP; i++) - { - cl->frames[i].entities.max_entities = MAX_STANDARD_PACKET_ENTITIES; - cl->frames[i].entities.entities = (entity_state_t*)(cl->frames+UPDATE_BACKUP) + i*cl->frames[i].entities.max_entities; - } - - net_from.port = cl - svs.clients; - cl->state = cs_zombie; - cl->userid = nextuserid++; - - cl->language = LANGDEFAULT; - - ent = EDICT_NUM(svprogfuncs, (cl-svs.clients)+1); - cl->edict = ent; - - host_client = cl; - if (!strcmp(ret->address, "LOCAL")) - { - addr.ip[0] = 0; - addr.ip[1] = 0; - addr.ip[2] = 0; - addr.ip[3] = 0; - addr.port = 0; - } - else - NET_StringToAdr(ret->address, &addr); - Netchan_Setup(ret->socket, &cl->netchan, addr, 0); - cl->netchan.message.maxsize = MAX_NQMSGLEN; - cl->netchan.qsocket = ret; - - cl->send_message = true; - - cl->datagram.allowoverflow = true; - cl->datagram.data = cl->datagram_buf; - cl->datagram.maxsize = MAX_NQDATAGRAM; - - if (!ret->qwprotocol) - { - cl->state = cs_connected; //this is a real player - *cl->userinfo = '\0'; - Info_SetValueForKey(cl->userinfo, "name", "unnamed", sizeof(cl->userinfo)); - SV_ExtractFromUserinfo(cl); - - if (pr_global_struct->SetNewParms) - PR_ExecuteProgram (svprogfuncs, pr_global_struct->SetNewParms); - for (i=0 ; ispawn_parms[i] = (&pr_global_struct->parm1)[i]; - - SVNQ_New_f(); - } - else - { - //this is just to recieve the connectionless messages over a specific connection... - cl->state = cs_zombie; //zombie for a nice timeout - cl->connection_started = -1; //drop when qsocket fails. - cl->sendinfo = false; - SVC_GetChallengeQSocket(ret); -// SV_New_f(); - } - -// Netchan_Transmit(&cl->netchan, cl->netchan.message.cursize, cl->netchan.message.data); -// cl->netchan.message.cursize = 0; -// NET_SendMessage(ret, &cl->netchan.message); - - net_activeconnections++; + newcl->netchan.message.maxsize = sizeof(newcl->netchan.message_buf); + host_client = newcl; + SVNQ_New_f(); } + + return newcl; } -#endif + + int Rcon_Validate (void) { if (!strlen (rcon_password.string)) @@ -2012,11 +1953,7 @@ Clients that are in the game can still send connectionless packets. ================= */ -#ifdef NQPROT -qboolean SV_ConnectionlessPacket (qsocket_t *sock) -#else qboolean SV_ConnectionlessPacket (void) -#endif { char *s; char *c; @@ -2062,45 +1999,16 @@ qboolean SV_ConnectionlessPacket (void) Netchan_OutOfBandPrint (NS_SERVER, net_from, "%c\nThis server requires client validation.\nPlease use the "DISTRIBUTION" validation program\n", A2C_PRINT); else { -#ifdef NQPROT - SVC_DirectConnect (sock); -#else SVC_DirectConnect (); -#endif - return true; - } - } - else if (!strcmp(c,"verifyconnect")) - SVC_DecodeConnect (); - else if (!strcmp(c,"validconnect")) - { - if (net_from.type != NA_IP || ((*(unsigned *)net_from.ip != *(unsigned *)net_local_ipadr.ip - && *(unsigned *)net_from.ip != htonl(INADDR_LOOPBACK))) ) - { - Con_Printf ("Validified connect packet from remote host. Ignored.\n"); - } - else - { - //these messages contain the ip address that it was origionally from (before being farmed out) - NET_StringToAdr(Cmd_Argv(1), &net_from); - Cmd_ShiftArgs(1, false); //get rid of the ip address... -#ifdef NQPROT - SVC_DirectConnect (sock); -#else - SVC_DirectConnect (); -#endif return true; } } else if (!strcmp(c,"getchallenge")) { -#ifdef NQPROT - if (sock) - SVC_GetChallengeQSocket (sock); - else -#endif - SVC_GetChallenge (); + SVC_GetChallenge (); } + else if (!strcmp(c, "getinfo")) + SVC_GetInfo(Cmd_Args()); else if (!strcmp(c, "rcon")) SVC_RemoteCommand (); else @@ -2110,6 +2018,85 @@ qboolean SV_ConnectionlessPacket (void) return false; } +void SVNQ_ConnectionlessPacket(void) +{ + sizebuf_t sb; + int header; + int length; + client_t *client; + char *str; + char buffer[256]; +// if (net_from.type == NA_LOOPBACK) + return; + + MSG_BeginReading(); + header = BigLong(MSG_ReadLong()); + if (!(header & NETFLAG_CTL)) + return; //no idea what it is. + + length = header & NETFLAG_LENGTH_MASK; + if (length != net_message.cursize) + return; //corrupt or not ours + + switch(MSG_ReadByte()) + { + case CCREQ_CONNECT: + sb.maxsize = sizeof(buffer); + sb.data = buffer; + if (strcmp(MSG_ReadString(), NET_GAMENAME_NQ)) + { + SZ_Clear(&sb); + MSG_WriteLong(&sb, 0); + MSG_WriteByte(&sb, CCREP_REJECT); + MSG_WriteString(&sb, "Incorrect game\n"); + *(int*)sb.data = BigLong(NETFLAG_CTL+sb.cursize); + NET_SendPacket(NS_SERVER, sb.cursize, sb.data, net_from); + return; //not our game. + } + if (MSG_ReadByte() != NET_PROTOCOL_VERSION) + { + SZ_Clear(&sb); + MSG_WriteLong(&sb, 0); + MSG_WriteByte(&sb, CCREP_REJECT); + MSG_WriteString(&sb, "Incorrect version\n"); + *(int*)sb.data = BigLong(NETFLAG_CTL+sb.cursize); + NET_SendPacket(NS_SERVER, sb.cursize, sb.data, net_from); + return; //not our version... + } + str = va("connect %i %i %i \"\\name\\unconnected\"", NET_PROTOCOL_VERSION, 0, SV_NewChallenge()); + Cmd_TokenizeString (str, false, false); + + client = SVC_DirectConnect(); + + if (client) + { + SZ_Clear(&sb); + MSG_WriteLong(&sb, 0); + MSG_WriteByte(&sb, CCREP_ACCEPT); + MSG_WriteLong(&sb, BigShort(net_local_sv_ipadr.port)); + *(int*)sb.data = BigLong(NETFLAG_CTL|sb.cursize); + NET_SendPacket(NS_SERVER, sb.cursize, sb.data, net_from); + + //nq supports packet truncation, so give them the full ammount + client->netchan.message.maxsize = sizeof(client->netchan.message_buf); + + host_client = client; + SVNQ_New_f(); + } + else + { + SZ_Clear(&sb); + MSG_WriteLong(&sb, 0); + MSG_WriteByte(&sb, CCREP_REJECT); + MSG_WriteString(&sb, "Bugger ye off"); + *(int*)sb.data = BigLong(NETFLAG_CTL|sb.cursize); + NET_SendPacket(NS_SERVER, sb.cursize, sb.data, net_from); + + } + break; + } +} + /* ============================================================================== @@ -2358,106 +2345,6 @@ void SV_OpenRoute_f(void) //============================================================================ -#ifdef NQPROT -//FIXME: move to header -void SVNQ_ExecuteClientMessage (client_t *cl); -qboolean SVNQ_ReadClientMessages (void) -{ - int ret; - int qport; - - if (host_client->state == cs_free) - return false; - - if (!host_client->netchan.qsocket) - return false; - - - do - { - ret = NET_GetMessage (host_client->netchan.qsocket); - - net_from.port = host_client - svs.clients; - if (ret == -1) - { - Sys_Printf ("SV_ReadClientMessage: NET_GetMessage failed\n"); - SV_DropClient(host_client); - host_client->state = cs_free; - return false; - } - if (!ret) - { - if (host_client->state == cs_spawned && !host_client->netchan.qsocket->qwprotocol) - { - extern usercmd_t cmd; - host_client->send_message = true; - sv_player = host_client->edict; - cmd = host_client->lastcmd; - SV_ClientThink(); - host_client->lastcmd.impulse = cmd.impulse; - } - return true; - } - - - - MSG_BeginReading (); - // check for connectionless packet (0xffffffff) first - if (*(int *)net_message.data == -1) - { - if (SV_ConnectionlessPacket (host_client->netchan.qsocket)) - return true; - continue; - } - -// if (host_client->state == cs_free) -// continue; - - if (host_client->nqprot) - { - host_client->netchan.last_received = realtime; - SVNQ_ExecuteClientMessage (host_client); - } - else - { - // read the qport out of the message so we can fix up - // stupid address translating routers - MSG_BeginReading (); - MSG_ReadLong (); // sequence number - MSG_ReadLong (); // sequence number - qport = MSG_ReadShort () & 0xffff; - - memcpy(&host_client->netchan.remote_address, &net_from, sizeof(net_from)); - if (!NET_CompareBaseAdr (net_from, host_client->netchan.remote_address)) - continue; - // if (host_client->netchan.qport != qport) - // continue; - if (host_client->netchan.remote_address.port != net_from.port) - { - Con_DPrintf ("SV_ReadPackets: fixing up a translated port\n"); - host_client->netchan.remote_address.port = net_from.port; - } - if (Netchan_Process(&host_client->netchan)) - { // this is a valid, sequenced packet, so process it - svs.stats.packets++; - host_client->send_message = true; // reply at end of frame - if (host_client->state != cs_zombie) - SV_ExecuteClientMessage (host_client); - } - } - } while (ret); - - if (host_client->state == cs_spawned && !host_client->netchan.qsocket->qwprotocol) - { - extern usercmd_t cmd; - host_client->send_message = true; - sv_player = host_client->edict; - cmd = host_client->lastcmd; - SV_ClientThink(); - } - return true; -} -#endif /* ================= SV_ReadPackets @@ -2484,12 +2371,7 @@ void SV_ReadPackets (void) // check for connectionless packet (0xffffffff) first if (*(int *)net_message.data == -1) { - SV_ConnectionlessPacket -#ifdef NQPROT - (NULL); -#else - (); -#endif + SV_ConnectionlessPacket(); continue; } @@ -2515,6 +2397,20 @@ void SV_ReadPackets (void) continue; if (!NET_CompareBaseAdr (net_from, cl->netchan.remote_address)) continue; +#ifdef NQPROT + if (ISNQCLIENT(cl) && cl->netchan.remote_address.port == net_from.port) + { + if (cl->state != cs_zombie) + { + if (NQNetChan_Process(&cl->netchan)) + { + svs.stats.packets++; + SVNQ_ExecuteClientMessage(cl); + } + } + break; + } +#endif if (cl->netchan.qport != qport) continue; if (cl->netchan.remote_address.port != net_from.port) @@ -2531,7 +2427,7 @@ void SV_ReadPackets (void) cl->send_message = true; // reply at end of frame #ifdef Q2SERVER - if (cl->isq2client) + if (cl->protocol == SCP_QUAKE2) SVQ2_ExecuteClientMessage(cl); else #endif @@ -2543,15 +2439,15 @@ void SV_ReadPackets (void) if (i != MAX_CLIENTS) continue; + +#ifdef NQPROT + SVNQ_ConnectionlessPacket(); +#endif // packet is not from a known client // Con_Printf ("%s:sequenced packet without connection\n" // ,NET_AdrToString(net_from)); } -#ifdef NQPROT - for (i=0, host_client = svs.clients ; iv->velocity[2] >= (1.0 / 32.0) && ((int)ent->v->flags & FL_ONGROUND)) + ent->v->flags = (int)ent->v->flags & ~FL_ONGROUND; + // frefall if not onground if ( ! ((int)ent->v->flags & (FL_ONGROUND | FL_FLY | FL_SWIM) ) ) { - if (ent->v->velocity[2] < movevars.gravity*-0.1) - hitsound = true; - else - hitsound = false; + hitsound = ent->v->velocity[2] < movevars.gravity*-0.1; SV_AddGravity (ent, 1.0); SV_CheckVelocity (ent); @@ -1345,7 +1345,7 @@ SV_WalkMove Only used by players ====================== */ -/* +#if 0 #define SMSTEPSIZE 4 void SV_WalkMove (edict_t *ent) { @@ -1502,7 +1502,7 @@ void SV_WalkMove (edict_t *ent) // Con_Printf("down not good\n"); } } -*/ +#else int SV_SetOnGround (edict_t *ent) @@ -1654,7 +1654,7 @@ void SV_WalkMove (edict_t *ent) SV_SetOnGround (ent); SV_CheckVelocity(ent); } - +#endif /* @@ -1815,6 +1815,9 @@ void SV_RunEntity (edict_t *ent) SV_WalkMove (ent); + if (!(ent->entnum > 0 && ent->entnum <= sv.allocated_client_slots)) + SV_LinkEdict (ent, true); + break; default: SV_Error ("SV_Physics: bad movetype %i on %s", (int)ent->v->movetype, svprogfuncs->stringtable + ent->v->classname); @@ -1980,18 +1983,15 @@ qboolean SV_Physics (void) host_frametime = sv_maxtic.value; old_time = realtime; + sv.physicstime = sv.time; + pr_global_struct->frametime = host_frametime; for (i = 0; i < sv.allocated_client_slots; i++) { host_client = &svs.clients[i]; if (host_client->state == cs_spawned) - if (sv_nomsec.value || SV_PlayerPhysicsQC -#ifndef NQPROT - ) -#else - || (host_client->nqprot)) -#endif + if (sv_nomsec.value || SV_PlayerPhysicsQC || !ISQWCLIENT(host_client)) SV_ClientThink(); } @@ -2022,12 +2022,7 @@ qboolean SV_Physics (void) if (i > 0 && i <= sv.allocated_client_slots) { - if (sv_nomsec.value || SV_PlayerPhysicsQC -#ifndef NQPROT - ) -#else - || (svs.clients[i-1].nqprot)) -#endif + if (sv_nomsec.value || SV_PlayerPhysicsQC || !ISQWCLIENT(&svs.clients[i-1])) { SV_Physics_Client(ent, i); SV_RunNewmis (); diff --git a/engine/server/sv_send.c b/engine/server/sv_send.c index 9f500731..4b44170b 100644 --- a/engine/server/sv_send.c +++ b/engine/server/sv_send.c @@ -83,7 +83,7 @@ void SV_FlushRedirect (void) spare = s[chop]; s[chop] = '\0'; - ClientReliableWrite_Begin (host_client, host_client->isq2client?svcq2_print:svc_print, chop+3); + ClientReliableWrite_Begin (host_client, host_client->protocol==SCP_QUAKE2?svcq2_print:svc_print, chop+3); ClientReliableWrite_Byte (host_client, PRINT_HIGH); ClientReliableWrite_String (host_client, s); @@ -91,7 +91,7 @@ void SV_FlushRedirect (void) totallen -= chop; s[0] = spare; } - ClientReliableWrite_Begin (host_client, host_client->isq2client?svcq2_print:svc_print, strlen(s)+3); + ClientReliableWrite_Begin (host_client, host_client->protocol==SCP_QUAKE2?svcq2_print:svc_print, strlen(s)+3); ClientReliableWrite_Byte (host_client, PRINT_HIGH); ClientReliableWrite_String (host_client, s); } @@ -223,9 +223,9 @@ EVENT MESSAGES static void SV_PrintToClient(client_t *cl, int level, char *string) { - ClientReliableWrite_Begin (cl, cl->isq2client?svcq2_print:svc_print, strlen(string)+3); + ClientReliableWrite_Begin (cl, cl->protocol==SCP_QUAKE2?svcq2_print:svc_print, strlen(string)+3); #ifdef NQPROT - if (cl->nqprot) + if (!ISQWCLIENT(cl)) { if (level == PRINT_CHAT) ClientReliableWrite_Byte (cl, 1); @@ -416,7 +416,7 @@ void VARGS SV_BroadcastCommand (char *fmt, ...) continue; if (cl->state>=cs_connected) { - ClientReliableWrite_Begin(cl, cl->isq2client?svcq2_stufftext:svc_stufftext, strlen(string)+2); + ClientReliableWrite_Begin(cl, ISQ2CLIENT(cl)?svcq2_stufftext:svc_stufftext, strlen(string)+2); ClientReliableWrite_String (cl, string); } } @@ -527,7 +527,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int } #ifdef NQPROT - if (client->nqprot) + if (!ISQWCLIENT(client)) { if (reliable) { @@ -604,16 +604,15 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int continue; } - if (svprogfuncs) - if (!((int)client->edict->v->dimension_see & dimension_mask)) - continue; - if (to == MULTICAST_PHS_R || to == MULTICAST_PHS) { vec3_t delta; VectorSubtract(origin, client->edict->v->origin, delta); if (Length(delta) <= 1024) goto inrange; } + else if (svprogfuncs) + if (!((int)client->edict->v->dimension_see & dimension_mask)) + continue; leaf = Mod_PointInLeaf (client->edict->v->origin, sv.worldmodel); if (leaf) @@ -629,7 +628,7 @@ void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int inrange: #ifdef NQPROT - if (client->nqprot) + if (!ISQWCLIENT(client)) { if (reliable) { ClientReliableCheckBlock(client, sv.nqmulticast.cursize); @@ -905,6 +904,7 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg) // send the chokecount for r_netgraph + if (ISQWCLIENT(client)) if (client->chokecount) { MSG_WriteByte (msg, svc_chokecount); @@ -915,12 +915,14 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg) for (split = client; split; split=split->controlled, pnum++) SV_WriteEntityDataToMessage(split, msg, pnum); + MSG_WriteByte (msg, svc_time); + MSG_WriteFloat(msg, sv.physicstime); + client->nextservertimeupdate = sv.physicstime; + // Z_EXT_TIME protocol extension // every now and then, send an update so that extrapolation // on client side doesn't stray too far off -#ifdef NQPROT - if (!client->nqprot) -#endif + if (ISQWCLIENT(client)) if (client->zquake_extensions & Z_EXT_SERVERTIME && sv.time - client->nextservertimeupdate > 0) { MSG_WriteByte (msg, svc_updatestatlong); @@ -930,17 +932,16 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg) client->nextservertimeupdate = sv.time+10; } - #ifdef NQPROT - if (!client->nqprot) + if (ISQWCLIENT(client)) return; ent = client->edict; MSG_WriteByte (msg, svc_time); - MSG_WriteFloat(msg, sv.time); - client->nextservertimeupdate = sv.time+10; + MSG_WriteFloat(msg, sv.physicstime); + client->nextservertimeupdate = sv.physicstime; bits = 0; @@ -1223,12 +1224,13 @@ void SV_UpdateClientStats (client_t *client, int pnum) { client->stats[i] = stats[i]; #ifdef NQPROT - if (client->nqprot) + if (!ISQWCLIENT(client)) { ClientReliableWrite_Begin(client, svc_updatestat, 3); ClientReliableWrite_Byte(client, i); ClientReliableWrite_Long(client, stats[i]); - } else + } + else #endif if (pnum) @@ -1284,7 +1286,7 @@ qboolean SV_SendClientDatagram (client_t *client) if (sv.worldmodel && !client->controller) { - if (client->isq2client) + if (ISQ2CLIENT(client)) { SV_BuildClientFrame (client); @@ -1314,7 +1316,7 @@ qboolean SV_SendClientDatagram (client_t *client) // send deltas over reliable stream if (sv.worldmodel) - if (!client->isq2client && Netchan_CanReliable (&client->netchan, SV_RateForClient(client))) + if (!ISQ2CLIENT(client) && Netchan_CanReliable (&client->netchan, SV_RateForClient(client))) { int pnum=1; client_t *c; @@ -1405,7 +1407,7 @@ void SV_UpdateToReliableMessages (void) } continue; } - if (!host_client->isq2client) + if (!ISQ2CLIENT(host_client)) { if (host_client->sendinfo) { @@ -1435,66 +1437,65 @@ void SV_UpdateToReliableMessages (void) host_client->old_frags = host_client->edict->v->frags; } - } - if (svprogfuncs) - { - extern cvar_t sv_gravity; - // maxspeed/entgravity changes - ent = host_client->edict; - - newval = ent->v->gravity*sv_gravity.value; - if (progstype != PROG_QW) { - if (!newval) - newval = 1; - } - - if (host_client->entgravity != newval) - { - sp = SV_SplitClientDest(host_client, svc_entgravity, 5); - ClientReliableWrite_Float(sp, newval/movevars.gravity); //lie to the client in a cunning way - host_client->entgravity = newval; - } - newval = ent->v->maxspeed; - if (progstype != PROG_QW) - { - if (!newval) - newval = sv_maxspeed.value; - } - if (ent->v->hasted) - newval*=ent->v->hasted; - #ifdef SVCHAT //enforce a no moving time when chatting. Prevent client prediction going mad. - if (host_client->chat.active) - newval = 0; - #endif - if (host_client->maxspeed != newval) - { //MSVC can really suck at times (optimiser bug) - - if (host_client->controller) - { //this is a slave client. - //find the right number and send. - int pnum = 0; - client_t *sp; - for (sp = host_client->controller; sp; sp = sp->controlled) - { - if (sp == host_client) - break; - pnum++; - } - sp = host_client->controller; - - ClientReliableWrite_Begin (sp, svc_choosesplitclient, 7); - ClientReliableWrite_Byte (sp, pnum); - ClientReliableWrite_Byte (sp, svc_maxspeed); - ClientReliableWrite_Float(sp, newval); - } - else + extern cvar_t sv_gravity; + // maxspeed/entgravity changes + ent = host_client->edict; + + newval = ent->v->gravity*sv_gravity.value; + if (progstype != PROG_QW) { - ClientReliableWrite_Begin(host_client, svc_maxspeed, 5); - ClientReliableWrite_Float(host_client, newval); + if (!newval) + newval = 1; + } + + if (host_client->entgravity != newval) + { + sp = SV_SplitClientDest(host_client, svc_entgravity, 5); + ClientReliableWrite_Float(sp, newval/movevars.gravity); //lie to the client in a cunning way + host_client->entgravity = newval; + } + newval = ent->v->maxspeed; + if (progstype != PROG_QW) + { + if (!newval) + newval = sv_maxspeed.value; + } + if (ent->v->hasted) + newval*=ent->v->hasted; + #ifdef SVCHAT //enforce a no moving time when chatting. Prevent client prediction going mad. + if (host_client->chat.active) + newval = 0; + #endif + if (host_client->maxspeed != newval) + { //MSVC can really suck at times (optimiser bug) + + if (host_client->controller) + { //this is a slave client. + //find the right number and send. + int pnum = 0; + client_t *sp; + for (sp = host_client->controller; sp; sp = sp->controlled) + { + if (sp == host_client) + break; + pnum++; + } + sp = host_client->controller; + + ClientReliableWrite_Begin (sp, svc_choosesplitclient, 7); + ClientReliableWrite_Byte (sp, pnum); + ClientReliableWrite_Byte (sp, svc_maxspeed); + ClientReliableWrite_Float(sp, newval); + } + else + { + ClientReliableWrite_Begin(host_client, svc_maxspeed, 5); + ClientReliableWrite_Float(host_client, newval); + } + host_client->maxspeed = newval; } - host_client->maxspeed = newval; } } } @@ -1512,8 +1513,10 @@ void SV_UpdateToReliableMessages (void) if (sv.nqdatagram.overflowed) SZ_Clear (&sv.nqdatagram); #endif +#ifdef Q2SERVER if (sv.q2datagram.overflowed) SZ_Clear (&sv.q2datagram); +#endif // append the broadcast messages to each client messages for (j=0, client = svs.clients ; jcontroller) continue; //splitscreen + +#ifdef Q2SERVER + if (ISQ2CLIENT(client)) + { + ClientReliableCheckBlock(client, sv.q2reliable_datagram.cursize); + ClientReliableWrite_SZ(client, sv.q2reliable_datagram.data, sv.q2reliable_datagram.cursize); + + if (client->state != cs_spawned) + continue; // datagrams only go to spawned + SZ_Write (&client->datagram + , sv.q2datagram.data + , sv.q2datagram.cursize); + } + else +#endif #ifdef NQPROT - if (client->nqprot) + if (!ISQWCLIENT(client)) { ClientReliableCheckBlock(client, sv.nqreliable_datagram.cursize); ClientReliableWrite_SZ(client, sv.nqreliable_datagram.data, sv.nqreliable_datagram.cursize); @@ -1536,18 +1554,6 @@ void SV_UpdateToReliableMessages (void) } else #endif - if (client->isq2client) - { - ClientReliableCheckBlock(client, sv.q2reliable_datagram.cursize); - ClientReliableWrite_SZ(client, sv.q2reliable_datagram.data, sv.q2reliable_datagram.cursize); - - if (client->state != cs_spawned) - continue; // datagrams only go to spawned - SZ_Write (&client->datagram - , sv.q2datagram.data - , sv.q2datagram.cursize); - } - else { ClientReliableCheckBlock(client, sv.reliable_datagram.cursize); ClientReliableWrite_SZ(client, sv.reliable_datagram.data, sv.reliable_datagram.cursize); @@ -1690,6 +1696,12 @@ void SV_SendClientMessages (void) // only send messages if the client has sent one // and the bandwidth is not choked + if (ISNQCLIENT(c)) + { //nq clients get artificial choke too + c->send_message = false; + if (c->nextservertimeupdate != sv.physicstime) + c->send_message = true; + } if (!c->send_message) continue; c->send_message = false; // try putting this after choke? diff --git a/engine/server/sv_sys_unix.c b/engine/server/sv_sys_unix.c index a0ce6880..2f1caf2e 100644 --- a/engine/server/sv_sys_unix.c +++ b/engine/server/sv_sys_unix.c @@ -34,6 +34,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cvar_t sys_nostdout = {"sys_nostdout","0"}; cvar_t sys_extrasleep = {"sys_extrasleep","0"}; +cvar_t sys_maxtic = {"sys_maxtic", "100"}; qboolean stdin_ready; @@ -306,10 +307,10 @@ int main(int argc, char *argv[]) while (1) { if (do_stdin) - stdin_ready = NET_Sleep(100, true); + stdin_ready = NET_Sleep(sys_maxtic.value, true); else { - NET_Sleep(100, false); + NET_Sleep(sys_maxtic.value, false); stdin_ready = false; } diff --git a/engine/server/sv_sys_win.c b/engine/server/sv_sys_win.c index 2a7c26f4..654c4203 100644 --- a/engine/server/sv_sys_win.c +++ b/engine/server/sv_sys_win.c @@ -157,6 +157,7 @@ void CreateSampleService(qboolean create); void PR_Deinit(void); cvar_t sys_nostdout = {"sys_nostdout","0"}; +cvar_t sys_maxtic = {"sys_maxtic", "100"}; HWND consolewindowhandle; HWND hiddenwindowhandler; @@ -608,6 +609,7 @@ is marked void Sys_Init (void) { Cvar_Register (&sys_nostdout, "System controls"); + Cvar_Register (&sys_maxtic, "System controls"); Cmd_AddCommand("hide", Sys_HideConsole); } @@ -675,13 +677,12 @@ void ServerMainLoop(void) oldtime = Sys_DoubleTime () - 0.1; while (1) { - NET_Sleep(100, false); + NET_Sleep(sys_maxtic.value, false); // find time passed since last cycle newtime = Sys_DoubleTime (); time = newtime - oldtime; oldtime = newtime; - SV_Frame (time); diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 241e3670..d2386e7a 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -118,9 +118,7 @@ void SV_New_f (void) if (host_client->state == cs_spawned) return; -#ifdef NQPROT - host_client->nqprot = false; -#endif + /* splitt delay host_client->state = cs_connected; host_client->connection_started = realtime; @@ -154,7 +152,7 @@ void SV_New_f (void) // send the serverdata - MSG_WriteByte (&host_client->netchan.message, host_client->isq2client?svcq2_serverdata:svc_serverdata); + MSG_WriteByte (&host_client->netchan.message, ISQ2CLIENT(host_client)?svcq2_serverdata:svc_serverdata); #ifdef PROTOCOL_VERSION_FTE if (host_client->fteprotocolextensions)//let the client know { @@ -165,9 +163,9 @@ void SV_New_f (void) MSG_WriteLong (&host_client->netchan.message, host_client->fteprotocolextensions); } #endif - MSG_WriteLong (&host_client->netchan.message, host_client->isq2client?host_client->isq2client:PROTOCOL_VERSION); + MSG_WriteLong (&host_client->netchan.message, ISQ2CLIENT(host_client)?PROTOCOL_VERSION_Q2:PROTOCOL_VERSION); MSG_WriteLong (&host_client->netchan.message, svs.spawncount); - if (host_client->isq2client) + if (ISQ2CLIENT(host_client)) MSG_WriteByte (&host_client->netchan.message, 0); MSG_WriteString (&host_client->netchan.message, gamedir); @@ -190,7 +188,7 @@ void SV_New_f (void) if (sv.state == ss_cinematic) playernum = -1; - if (host_client->isq2client) + if (ISQ2CLIENT(host_client)) MSG_WriteShort (&host_client->netchan.message, playernum); else MSG_WriteByte (&host_client->netchan.message, playernum); @@ -215,7 +213,7 @@ void SV_New_f (void) // game server // #ifdef Q2SERVER - if (host_client->isq2client) + if (ISQ2CLIENT(host_client)) { if (sv.state != ss_cinematic) { @@ -265,9 +263,7 @@ void SVNQ_New_f (void) extern cvar_t coop; char message[2048]; int i; -#ifdef NQPROT - host_client->nqprot = true; -#endif + MSG_WriteByte (&host_client->netchan.message, svc_print); #ifdef DISTRIBUTION sprintf (message, "%c\n" DISTRIBUTION " QuakeWorld version %4.2f server\n", 2, VERSION); @@ -1325,7 +1321,7 @@ void SV_Begin_f (void) // if we are paused, tell the client if (sv.paused) { - if (!host_client->isq2client) + if (!ISQ2CLIENT(host_client)) { ClientReliableWrite_Begin (host_client, svc_setpause, 2); ClientReliableWrite_Byte (host_client, sv.paused); @@ -1402,7 +1398,7 @@ void SV_NextDownload_f (void) if (r > 768) r = 768; r = fread (buffer, 1, r, host_client->download); - ClientReliableWrite_Begin (host_client, host_client->isq2client?svcq2_download:svc_download, 6+r); + ClientReliableWrite_Begin (host_client, ISQ2CLIENT(host_client)?svcq2_download:svc_download, 6+r); ClientReliableWrite_Short (host_client, r); host_client->downloadcount += r; @@ -1623,7 +1619,7 @@ void SV_BeginDownload_f(void) else #endif { - ClientReliableWrite_Begin (host_client, host_client->isq2client?svcq2_download:svc_download, 4); + ClientReliableWrite_Begin (host_client, ISQ2CLIENT(host_client)?svcq2_download:svc_download, 4); ClientReliableWrite_Short (host_client, -1); ClientReliableWrite_Byte (host_client, 0); } @@ -1670,7 +1666,7 @@ void SV_BeginDownload_f(void) else #endif { - ClientReliableWrite_Begin (host_client, host_client->isq2client?svcq2_download:svc_download, 4); + ClientReliableWrite_Begin (host_client, ISQ2CLIENT(host_client)?svcq2_download:svc_download, 4); ClientReliableWrite_Short (host_client, -1); ClientReliableWrite_Byte (host_client, 0); } @@ -2044,7 +2040,7 @@ void SV_TogglePause (void) { if (!cl->state) continue; - if (!cl->isq2client && !cl->controller) + if (!ISQ2CLIENT(host_client) && !cl->controller) { ClientReliableWrite_Begin (cl, svc_setpause, 2); ClientReliableWrite_Byte (cl, sv.paused); @@ -2920,7 +2916,7 @@ void SV_ExecuteUserCommand (char *s, qboolean fromQC) } #ifdef Q2SERVER - if (host_client->isq2client) + if (ISQ2CLIENT(host_client)) u = ucmdsq2; else #endif @@ -3156,7 +3152,7 @@ void SVNQ_Begin_f (void) // if we are paused, tell the client if (sv.paused) { - if (!host_client->isq2client) + if (!ISQ2CLIENT(host_client)) { ClientReliableWrite_Begin (host_client, svc_setpause, 2); ClientReliableWrite_Byte (host_client, sv.paused); @@ -3181,8 +3177,8 @@ void SVNQ_Begin_f (void) SZ_Write (&host_client->netchan.message, sv.signon.data, sv.signon.cursize); - MSG_WriteByte (&host_client->netchan.message, svc_signonnum); - MSG_WriteByte (&host_client->netchan.message, 4); +// MSG_WriteByte (&host_client->netchan.message, svc_signonnum); +// MSG_WriteByte (&host_client->netchan.message, 4); host_client->send_message = true; @@ -3323,6 +3319,21 @@ void SVNQ_NQColour_f (void) MSG_WriteByte (&sv.nqreliable_datagram, playercolor); } +void SVNQ_Ping_f(void) +{ + int i; + client_t *cl; + + Con_Printf ("Ping times:\n"); + for (i=0,cl=svs.clients ; istate) + continue; + + Con_Printf ("%3i %s\n", SV_CalcPing (cl), cl->name); + } +} + ucmd_t nqucmds[] = { {"status", NULL}, @@ -3345,7 +3356,7 @@ ucmd_t nqucmds[] = {"begin", SVNQ_Begin_f, true}, {"prespawn", SVNQ_PreSpawn_f, true}, {"kick", NULL}, - {"ping", NULL}, + {"ping", SVNQ_Ping_f}, {"ban", NULL}, {"vote", SV_Vote_f}, @@ -3670,6 +3681,21 @@ int SV_PMTypeForClient (client_t *cl) return PM_SPECTATOR; return PM_OLD_SPECTATOR; } + + if (sv_brokenmovetypes.value) //this is to mimic standard qw servers, which don't support movetypes other than MOVETYPE_FLY. + { //it prevents bugs from being visible in unsuspecting mods. + if (cl->spectator) + { + if (cl->zquake_extensions & Z_EXT_PM_TYPE_NEW) + return PM_SPECTATOR; + return PM_OLD_SPECTATOR; + } + + if (cl->edict->v->health <= 0) + return PM_DEAD; + return PM_NORMAL; + } + if (cl->edict->v->movetype == MOVETYPE_NOCLIP) { if (cl->zquake_extensions & Z_EXT_PM_TYPE_NEW) @@ -3681,11 +3707,7 @@ int SV_PMTypeForClient (client_t *cl) return PM_FLY; if (cl->edict->v->movetype == MOVETYPE_NONE) - { - if (sv_brokenmovetypes.value) - return PM_NORMAL; return PM_NONE; - } if (cl->edict->v->health <= 0) return PM_DEAD; @@ -4535,8 +4557,10 @@ void SVNQ_ReadClientMove (usercmd_t *move) { int i; int bits; + client_frame_t *frame; - MSG_ReadFloat (); //message time (nq uses it to time pings - qw ignores it) + frame = &host_client->frames[host_client->netchan.incoming_acknowledged & UPDATE_MASK]; + frame->ping_time = sv.time - MSG_ReadFloat (); // read current angles @@ -4588,18 +4612,19 @@ void SVNQ_ExecuteClientMessage (client_t *cl) client_frame_t *frame; int seq_hash; - MSG_BeginReading (); + cl->netchan.outgoing_sequence++; + cl->netchan.incoming_acknowledged = cl->netchan.outgoing_sequence-1; // calc ping time frame = &cl->frames[cl->netchan.incoming_acknowledged & UPDATE_MASK]; - frame->ping_time = realtime - frame->senttime; + frame->ping_time = 999; // make sure the reply sequence number matches the incoming // sequence number - if (cl->netchan.incoming_sequence >= cl->netchan.outgoing_sequence) +// if (cl->netchan.incoming_sequence >= cl->netchan.outgoing_sequence) cl->netchan.outgoing_sequence = cl->netchan.incoming_sequence; - else - cl->send_message = false; // don't reply, sequences have slipped +// else +// cl->send_message = false; // don't reply, sequences have slipped // save time for ping calculations cl->frames[cl->netchan.outgoing_sequence & UPDATE_MASK].senttime = realtime; diff --git a/engine/server/world.c b/engine/server/world.c index 045a3d8f..86afdeb1 100644 --- a/engine/server/world.c +++ b/engine/server/world.c @@ -369,6 +369,8 @@ void SV_TouchLinks ( edict_t *ent, areanode_t *node ) //work out who they are first. for (l = node->trigger_edicts.next ; l != &node->trigger_edicts ; l = next) { + if (linkcount == MAX_NODELINKS) + break; next = l->next; touch = EDICT_FROM_AREA(l); if (touch == ent) @@ -389,8 +391,6 @@ void SV_TouchLinks ( edict_t *ent, areanode_t *node ) continue; nodelinks[linkcount++] = touch; - if (linkcount == MAX_NODELINKS) - break; } old_self = pr_global_struct->self; @@ -1476,12 +1476,12 @@ void SV_ClipMoveToEntities ( moveclip_t *clip ) if (touch->v->solid != SOLID_BSP) angles = vec3_origin; // boxes don't rotate -/* if (touch->svflags & SVF_MONSTER) + if ((int)touch->v->flags & FL_MONSTER) trace = CM_TransformedBoxTrace (clip->start, clip->end, - clip->mins2, clip->maxs2, headnode, clip->contentmask, - touch->s.origin, angles); + clip->mins2, clip->maxs2, headnode, MASK_PLAYERSOLID, + touch->v->origin, angles); else -*/ trace = CM_TransformedBoxTrace (clip->start, clip->end, + trace = CM_TransformedBoxTrace (clip->start, clip->end, clip->mins, clip->maxs, headnode, MASK_PLAYERSOLID, touch->v->origin, angles); diff --git a/engine/sw/r_bsp.c b/engine/sw/r_bsp.c index fdf9ad19..6360792a 100644 --- a/engine/sw/r_bsp.c +++ b/engine/sw/r_bsp.c @@ -881,7 +881,7 @@ void R_RenderWorld (void) int clientarea; int CM_WriteAreaBits (qbyte *buffer, int area); #ifdef Q2CLIENT - if (cls.q2server) + if (cls.protocol == CP_QUAKE2) memcpy(areabits, cl.q2frame.areabits, sizeof(areabits)); else #endif