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:
Spoike 2005-05-26 12:55:34 +00:00
parent 759ee1a2b7
commit 95948b35ec
81 changed files with 2268 additions and 6880 deletions

View File

@ -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

View File

@ -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();

View File

@ -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
}

View File

@ -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;

View File

@ -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)

View File

@ -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();

View File

@ -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;

View File

@ -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:

View File

@ -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))

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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.
}
}

View File

@ -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, "");

View File

@ -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';

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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");

View File

@ -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

View File

@ -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;

View File

@ -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)

View File

@ -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, &current_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)

View File

@ -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);

View File

@ -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;

View File

@ -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 @@@

View File

@ -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

View File

@ -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;
}

View File

@ -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)
}
}
/*
=====================================================================

View File

@ -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;
}

View File

@ -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];

View File

@ -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.

View File

@ -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);

View File

@ -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)

View File

@ -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.

View File

@ -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);

View File

@ -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

View File

@ -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"

View File

@ -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;
}

View File

@ -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 ) {

View File

@ -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;

View File

@ -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] );

View File

@ -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.

View File

@ -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;

View File

@ -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)
{

View File

@ -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];

View File

@ -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

View File

@ -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, '?');

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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"

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -3356,8 +3356,8 @@ int main (int argc, char **argv)
#endif
return !sucess;
}
#endif
#endif
#endif//usegui
#endif//qcconly
#endif
#endif//minimal

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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 ();

View File

@ -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?

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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