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
This commit is contained in:
parent
759ee1a2b7
commit
95948b35ec
81 changed files with 2268 additions and 6880 deletions
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 ; pnum<pack->num_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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<<i) )
|
||||
{
|
||||
if (nq_dp_protocol == 5 || nq_dp_protocol == 6)
|
||||
if (nq_dp_protocol >= 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:
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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, "");
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 @@@
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 <path>
|
||||
// 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)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=====================================================================
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 ; i<map_numfogs ; i++, ret++)
|
||||
{
|
||||
if (!ret->numplanes)
|
||||
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];
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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] );
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, '?');
|
||||
|
|
|
@ -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);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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);
|
|
@ -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
|
|
@ -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
|
File diff suppressed because it is too large
Load diff
|
@ -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);
|
|
@ -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 <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef __sun__
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
|
||||
#ifdef NeXT
|
||||
#include <libc.h>
|
||||
#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
|
|
@ -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"
|
|
@ -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);
|
|
@ -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 <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#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
|
|
@ -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);
|
|
@ -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 <wsipx.h>
|
||||
#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
|
|
@ -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);
|
|
@ -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);
|
|
@ -3356,8 +3356,8 @@ int main (int argc, char **argv)
|
|||
#endif
|
||||
return !sucess;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif//usegui
|
||||
#endif//qcconly
|
||||
|
||||
#endif
|
||||
#endif//minimal
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ; i<Cmd_Argc() ; i++)
|
||||
{
|
||||
if (!strcmp(Cmd_Argv(i), "none") || !NET_StringToAdr (Cmd_Argv(i), &master_adr[i-1]))
|
||||
{
|
||||
Con_TPrintf (STL_NOMASTERMODE);
|
||||
return;
|
||||
}
|
||||
if (master_adr[i-1].port == 0)
|
||||
master_adr[i-1].port = BigShort (27000);
|
||||
|
||||
Con_TPrintf (STL_MASTERAT, NET_AdrToString (master_adr[i-1]));
|
||||
|
||||
Con_TPrintf (STL_SENDINGPING);
|
||||
|
||||
data[0] = A2A_PING;
|
||||
data[1] = 0;
|
||||
if (sv.state)
|
||||
NET_SendPacket (NS_SERVER, 2, data, master_adr[i-1]);
|
||||
Master_Add(Cmd_Argv(i));
|
||||
}
|
||||
|
||||
svs.last_heartbeat = -99999;
|
||||
|
@ -846,7 +836,7 @@ void SV_StuffToClient_f(void)
|
|||
|
||||
while((cl = SV_GetClientForString(clientname, &clnum)))
|
||||
{
|
||||
if (cl->isq2client)
|
||||
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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1102,13 +1102,13 @@ void SV_Physics_Step (edict_t *ent)
|
|||
{
|
||||
qboolean hitsound;
|
||||
|
||||
if (ent->v->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 ();
|
||||
|
|
|
@ -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 ; j<MAX_CLIENTS ; j++, client++)
|
||||
|
@ -1522,8 +1525,23 @@ void SV_UpdateToReliableMessages (void)
|
|||
continue; // reliables go to all connected or spawned
|
||||
if (client->controller)
|
||||
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?
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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 ; i<MAX_CLIENTS ; i++,cl++)
|
||||
{
|
||||
if (!cl->state)
|
||||
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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue