I wonder how much this will break. Ahh well. It works for me, and I need to go to bed.
Well, plugins should be able to read/write files through the engine. audio decoding plugin interface is in (might be changed later). TCPConnect is in. msg_filter and scr_centersbar. some recording fixes too. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1634 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
e54ecb4a9a
commit
339d478659
53 changed files with 1235 additions and 446 deletions
|
@ -116,6 +116,7 @@ CLIENT_OBJS = $(CLIENT_ASM_OBJS) \
|
|||
cl_cam.o \
|
||||
cl_screen.o \
|
||||
cl_ui.o \
|
||||
cl_ignore.o \
|
||||
cl_cg.o \
|
||||
clq3_parse.o \
|
||||
pr_csqc.o \
|
||||
|
|
|
@ -1105,7 +1105,10 @@ void CL_PlayDemo_f (void)
|
|||
Con_Printf ("Playing demo from %s.\n", name);
|
||||
|
||||
if (!Q_strcasecmp(name + strlen(name) - 3, "mvd"))
|
||||
{
|
||||
cls.demoplayback = DPB_MVD;
|
||||
cls.findtrack = true;
|
||||
}
|
||||
else
|
||||
cls.demoplayback = DPB_QUAKEWORLD;
|
||||
cls.state = ca_demostart;
|
||||
|
|
|
@ -256,7 +256,6 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean
|
|||
#ifdef PROTOCOLEXTENSIONS
|
||||
int morebits=0;
|
||||
#endif
|
||||
vec3_t move;
|
||||
|
||||
// set everything to the state we are delta'ing from
|
||||
*to = *from;
|
||||
|
@ -436,12 +435,15 @@ void CL_ParsePacketEntities (qboolean delta)
|
|||
int word, newnum, oldnum;
|
||||
qboolean full;
|
||||
int from;
|
||||
/*
|
||||
cl.oldgametime = cl.gametime;
|
||||
cl.oldgametimemark = cl.gametimemark;
|
||||
cl.gametime = realtime;
|
||||
cl.gametimemark = realtime;
|
||||
*/
|
||||
|
||||
if (!(cls.fteprotocolextensions & PEXT_ACCURATETIMINGS))
|
||||
{
|
||||
cl.oldgametime = cl.gametime;
|
||||
cl.oldgametimemark = cl.gametimemark;
|
||||
cl.gametime = realtime;
|
||||
cl.gametimemark = realtime;
|
||||
}
|
||||
|
||||
newpacket = cls.netchan.incoming_sequence&UPDATE_MASK;
|
||||
newp = &cl.frames[newpacket].packet_entities;
|
||||
cl.frames[newpacket].invalid = false;
|
||||
|
@ -1182,7 +1184,6 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum)
|
|||
entity_state_t *ps;
|
||||
float *org=NULL, *ang=NULL;
|
||||
vec3_t axis[3];
|
||||
vec3_t destorg;
|
||||
float transform[12], parent[12], result[12], old[12], temp[12];
|
||||
|
||||
int model = 0; //these two are only initialised because msvc sucks at detecting usage.
|
||||
|
@ -1442,13 +1443,10 @@ void CL_TransitionPacketEntities(packet_entities_t *newpack, packet_entities_t *
|
|||
packet_entities_t *CL_ProcessPacketEntities(float *servertime, qboolean nolerp)
|
||||
{
|
||||
packet_entities_t *packnew, *packold;
|
||||
entity_state_t *snew, *sold;
|
||||
int i;
|
||||
static float oldoldtime;
|
||||
//, spnum;
|
||||
|
||||
*servertime -= 0.1;
|
||||
|
||||
if (nolerp)
|
||||
{ //force our emulated time to as late as we can.
|
||||
//this will disable all position interpolation
|
||||
|
@ -1513,12 +1511,11 @@ void CL_LinkPacketEntities (void)
|
|||
packet_entities_t *pack;
|
||||
entity_state_t *state;
|
||||
lerpents_t *le;
|
||||
float f;
|
||||
model_t *model;
|
||||
vec3_t old_origin;
|
||||
float autorotate;
|
||||
int i;
|
||||
int oldpnum, newpnum;
|
||||
int newpnum;
|
||||
//, spnum;
|
||||
dlight_t *dl;
|
||||
vec3_t angles;
|
||||
|
@ -1679,8 +1676,6 @@ void CL_LinkPacketEntities (void)
|
|||
}
|
||||
else
|
||||
{
|
||||
float a1, a2;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
angles[i] = le->angles[i];
|
||||
|
@ -2295,15 +2290,15 @@ void CL_ParsePlayerinfo (void)
|
|||
memcpy(state, prevstate, sizeof(player_state_t));
|
||||
info->prevcount = cl.parsecount;
|
||||
|
||||
/* if (cls.findtrack && info->stats[STAT_HEALTH] > 0)
|
||||
if (cls.findtrack && info->stats[STAT_HEALTH] > 0)
|
||||
{
|
||||
extern int ideal_track;
|
||||
autocam = CAM_TRACK;
|
||||
Cam_Lock(num);
|
||||
ideal_track = num;
|
||||
// extern int ideal_track;
|
||||
autocam[0] = CAM_TRACK;
|
||||
Cam_Lock(0, num);
|
||||
// ideal_track = num;
|
||||
cls.findtrack = false;
|
||||
}
|
||||
*/
|
||||
|
||||
flags = MSG_ReadShort ();
|
||||
state->flags = MVD_TranslateFlags(flags);
|
||||
|
||||
|
|
|
@ -856,7 +856,7 @@ void VARGS CL_SendClientCommand(qboolean reliable, char *format, ...)
|
|||
va_end (argptr);
|
||||
|
||||
|
||||
// Con_Printf("Queing stringcmd %s\n", string);
|
||||
Con_DPrintf("Queing stringcmd %s\n", string);
|
||||
|
||||
#ifdef Q3CLIENT
|
||||
if (cls.protocol == CP_QUAKE3)
|
||||
|
|
|
@ -119,6 +119,7 @@ cvar_t cl_item_bobbing = {"cl_model_bobbing", "0"};
|
|||
|
||||
cvar_t requiredownloads = {"requiredownloads","1", NULL, CVAR_ARCHIVE};
|
||||
cvar_t cl_standardchat = {"cl_standardchat", "0"};
|
||||
cvar_t msg_filter = {"msg_filter", "0"}; //0 for neither, 1 for mm1, 2 for mm2, 3 for both
|
||||
cvar_t cl_standardmsg = {"cl_standardmsg", "0"};
|
||||
cvar_t cl_parsewhitetext = {"cl_parsewhitetext", "0"};
|
||||
|
||||
|
@ -259,44 +260,11 @@ void CL_ConnectToDarkPlaces(char *challenge, netadr_t adr)
|
|||
cl.splitclients = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=======================
|
||||
CL_SendConnectPacket
|
||||
|
||||
called by CL_Connect_f and CL_CheckResend
|
||||
======================
|
||||
*/
|
||||
void CL_SendConnectPacket (
|
||||
#ifdef PROTOCOL_VERSION_FTE
|
||||
int ftepext,
|
||||
#endif
|
||||
int compressioncrc
|
||||
/*, ...*/) //dmw new parms
|
||||
unsigned int CL_SupportedFTEExtensions(void)
|
||||
{
|
||||
netadr_t adr;
|
||||
char data[2048];
|
||||
char playerinfo2[MAX_INFO_STRING];
|
||||
double t1, t2;
|
||||
#ifdef PROTOCOL_VERSION_FTE
|
||||
int fteprotextsupported=0;
|
||||
#endif
|
||||
int clients;
|
||||
int c;
|
||||
unsigned int fteprotextsupported = 0;
|
||||
|
||||
// JACK: Fixed bug where DNS lookups would cause two connects real fast
|
||||
// Now, adds lookup time to the connect time.
|
||||
// Should I add it to realtime instead?!?!
|
||||
|
||||
if (cls.state != ca_disconnected)
|
||||
return;
|
||||
|
||||
if (cl_nopext.value) //imagine it's an unenhanced server
|
||||
{
|
||||
ftepext = 0;
|
||||
compressioncrc = 0;
|
||||
}
|
||||
|
||||
#ifdef PROTOCOL_VERSION_FTE
|
||||
#ifdef PEXT_SCALE //dmw - protocol extensions
|
||||
fteprotextsupported |= PEXT_SCALE;
|
||||
#endif
|
||||
|
@ -312,6 +280,9 @@ void CL_SendConnectPacket (
|
|||
#ifdef PEXT_BULLETENS
|
||||
fteprotextsupported |= PEXT_BULLETENS;
|
||||
#endif
|
||||
#ifdef PEXT_ACCURATETIMINGS
|
||||
fteprotextsupported |= PEXT_ACCURATETIMINGS;
|
||||
#endif
|
||||
#ifdef PEXT_ZLIBDL
|
||||
fteprotextsupported |= PEXT_ZLIBDL;
|
||||
#endif
|
||||
|
@ -370,10 +341,54 @@ void CL_SendConnectPacket (
|
|||
fteprotextsupported |= PEXT_DPFLAGS;
|
||||
#endif
|
||||
|
||||
return fteprotextsupported;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=======================
|
||||
CL_SendConnectPacket
|
||||
|
||||
called by CL_Connect_f and CL_CheckResend
|
||||
======================
|
||||
*/
|
||||
void CL_SendConnectPacket (
|
||||
#ifdef PROTOCOL_VERSION_FTE
|
||||
int ftepext,
|
||||
#endif
|
||||
int compressioncrc
|
||||
/*, ...*/) //dmw new parms
|
||||
{
|
||||
netadr_t adr;
|
||||
char data[2048];
|
||||
char playerinfo2[MAX_INFO_STRING];
|
||||
double t1, t2;
|
||||
#ifdef PROTOCOL_VERSION_FTE
|
||||
int fteprotextsupported=0;
|
||||
#endif
|
||||
int clients;
|
||||
int c;
|
||||
|
||||
// JACK: Fixed bug where DNS lookups would cause two connects real fast
|
||||
// Now, adds lookup time to the connect time.
|
||||
// Should I add it to realtime instead?!?!
|
||||
|
||||
if (cls.state != ca_disconnected)
|
||||
return;
|
||||
|
||||
if (cl_nopext.value) //imagine it's an unenhanced server
|
||||
{
|
||||
ftepext = 0;
|
||||
compressioncrc = 0;
|
||||
}
|
||||
|
||||
#ifdef PROTOCOL_VERSION_FTE
|
||||
fteprotextsupported = CL_SupportedFTEExtensions();
|
||||
|
||||
fteprotextsupported &= ftepext;
|
||||
|
||||
#ifdef Q2CLIENT
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
if (cls.protocol != CP_QUAKEWORLD)
|
||||
fteprotextsupported = 0;
|
||||
#endif
|
||||
|
||||
|
@ -732,6 +747,75 @@ void CLNQ_Connect_f (void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef TCPCONNECT
|
||||
void CL_TCPConnect_f (void)
|
||||
{
|
||||
char buffer[6];
|
||||
int newsocket;
|
||||
int len;
|
||||
int _true = true;
|
||||
|
||||
float giveuptime;
|
||||
|
||||
char *server;
|
||||
|
||||
if (Cmd_Argc() != 2)
|
||||
{
|
||||
Con_TPrintf (TLC_SYNTAX_CONNECT);
|
||||
return;
|
||||
}
|
||||
|
||||
server = Cmd_Argv (1);
|
||||
|
||||
CL_Disconnect_f ();
|
||||
|
||||
Q_strncpyz (cls.servername, server, sizeof(cls.servername));
|
||||
|
||||
NET_StringToAdr(cls.servername, &cls.sockettcpdest);
|
||||
|
||||
if (cls.sockettcp != INVALID_SOCKET)
|
||||
closesocket (cls.sockettcp);
|
||||
cls.sockettcp = INVALID_SOCKET;
|
||||
cls.tcpinlen = 0;
|
||||
|
||||
newsocket = TCP_OpenStream(cls.sockettcpdest);
|
||||
if (newsocket == INVALID_SOCKET)
|
||||
{
|
||||
//failed
|
||||
Con_Printf("Failed to connect, server is either down, firewalled, or on a different port\n");
|
||||
return;
|
||||
}
|
||||
|
||||
Con_Printf("Waiting for confirmation of server (10 secs)\n");
|
||||
|
||||
giveuptime = Sys_DoubleTime() + 10;
|
||||
|
||||
while(giveuptime > Sys_DoubleTime())
|
||||
{
|
||||
len = recv(newsocket, buffer, sizeof(buffer), 0);
|
||||
if (!strncmp(buffer, "qizmo\n", 6))
|
||||
{
|
||||
cls.sockettcp = newsocket;
|
||||
break;
|
||||
}
|
||||
SCR_UpdateScreen();
|
||||
}
|
||||
|
||||
if (cls.sockettcp == INVALID_SOCKET)
|
||||
{
|
||||
Con_Printf("Timeout - wrong server type\n");
|
||||
closesocket(newsocket);
|
||||
return;
|
||||
}
|
||||
Con_Printf("Confirmed\n");
|
||||
|
||||
send(cls.sockettcp, buffer, sizeof(buffer), 0);
|
||||
setsockopt(cls.sockettcp, IPPROTO_TCP, TCP_NODELAY, (char *)&_true, sizeof(_true));
|
||||
|
||||
CL_BeginServerConnect();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
=====================
|
||||
CL_Rcon_f
|
||||
|
@ -1012,6 +1096,15 @@ void CL_Disconnect (void)
|
|||
|
||||
cls.protocol = CP_UNKNOWN;
|
||||
cl.servercount = 0;
|
||||
cls.findtrack = false;
|
||||
|
||||
#ifdef TCPCONNECT
|
||||
if (cls.sockettcp != INVALID_SOCKET)
|
||||
{
|
||||
closesocket(cls.sockettcp);
|
||||
cls.sockettcp = INVALID_SOCKET;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef serverrunning
|
||||
|
@ -1406,6 +1499,32 @@ void CL_SetInfo_f (void)
|
|||
if (!stricmp(Cmd_Argv(1), pmodel_name) || !strcmp(Cmd_Argv(1), emodel_name))
|
||||
return;
|
||||
|
||||
if (Cmd_Argv(1)[0] == '*')
|
||||
{
|
||||
int i;
|
||||
if (!strcmp(Cmd_Argv(1), "*"))
|
||||
if (!strcmp(Cmd_Argv(2), ""))
|
||||
{ //clear it out
|
||||
char *k;
|
||||
for(i=0;;)
|
||||
{
|
||||
k = Info_KeyForNumber(cls.userinfo, i);
|
||||
if (!*k)
|
||||
break; //no more.
|
||||
else if (*k == '*')
|
||||
i++; //can't remove * keys
|
||||
else if ((var = Cvar_FindVar(k)) && var->flags&CVAR_SERVERINFO)
|
||||
i++; //this one is a cvar.
|
||||
else
|
||||
Info_RemoveKey(cls.userinfo, k); //we can remove this one though, so yay.
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
Con_TPrintf (TL_STARKEYPROTECTED);
|
||||
return;
|
||||
}
|
||||
|
||||
var = Cvar_FindVar(Cmd_Argv(1));
|
||||
if (var && (var->flags & CVAR_USERINFO))
|
||||
{ //get the cvar code to set it. the server might have locked it.
|
||||
|
@ -1425,6 +1544,13 @@ void CL_SetInfo_f (void)
|
|||
}
|
||||
}
|
||||
|
||||
void CL_SaveInfo(FILE *f)
|
||||
{
|
||||
fwrite("\n", 1, 1, f);
|
||||
fwrite("setinfo * \"\"\n", 13, 1, f);
|
||||
Info_WriteToFile(f, cls.userinfo, "setinfo", CVAR_USERINFO);
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
CL_Packet_f
|
||||
|
@ -1491,7 +1617,17 @@ void CL_Packet_f (void)
|
|||
}
|
||||
*out = 0;
|
||||
|
||||
#ifdef TCPCONNECT
|
||||
{
|
||||
int tcpsock; //extra code to stop the packet command from sending to the server via tcp
|
||||
tcpsock = cls.sockettcp;
|
||||
cls.sockettcp = -1;
|
||||
NET_SendPacket (NS_CLIENT, out-send, send, adr);
|
||||
cls.sockettcp = tcpsock;
|
||||
}
|
||||
#else
|
||||
NET_SendPacket (NS_CLIENT, out-send, send, adr);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -2462,6 +2598,7 @@ void CL_Init (void)
|
|||
|
||||
Cvar_Register (&requiredownloads, cl_controlgroup);
|
||||
Cvar_Register (&cl_standardchat, cl_controlgroup);
|
||||
Cvar_Register (&msg_filter, cl_controlgroup);
|
||||
Cvar_Register (&cl_standardmsg, cl_controlgroup);
|
||||
Cvar_Register (&cl_parsewhitetext, cl_controlgroup);
|
||||
Cvar_Register (&cl_nopext, cl_controlgroup);
|
||||
|
@ -2501,6 +2638,9 @@ void CL_Init (void)
|
|||
Cmd_AddCommand ("quit", CL_Quit_f);
|
||||
|
||||
Cmd_AddCommand ("connect", CL_Connect_f);
|
||||
#ifdef TCPCONNECT
|
||||
Cmd_AddCommand ("tcpconnect", CL_TCPConnect_f);
|
||||
#endif
|
||||
#ifdef NQPROT
|
||||
Cmd_AddCommand ("nqconnect", CLNQ_Connect_f);
|
||||
#endif
|
||||
|
@ -2552,6 +2692,8 @@ void CL_Init (void)
|
|||
#ifdef _WINDOWS
|
||||
Cmd_AddCommand ("windows", CL_Windows_f);
|
||||
#endif
|
||||
|
||||
Ignore_Init();
|
||||
}
|
||||
|
||||
|
||||
|
@ -2716,7 +2858,9 @@ void Host_Frame (double time)
|
|||
|
||||
#if defined(WINAVI) && !defined(NOMEDIA)
|
||||
if (cls.demoplayback && recordingdemo && recordavi_frametime>0.01)
|
||||
time = recordavi_frametime;
|
||||
{
|
||||
realframetime = time = recordavi_frametime;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (cls.demoplayback && cl_demospeed.value>0)
|
||||
|
@ -2928,6 +3072,31 @@ void Host_FixupModelNames(void)
|
|||
simple_crypt(soundlist_name, sizeof(soundlist_name) - 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef Q3CLIENT
|
||||
void CL_ReadCDKey(void)
|
||||
{ //q3 cdkey
|
||||
//you don't need one, just use a server without sv_strictauth set to 0.
|
||||
char *buffer;
|
||||
buffer = COM_LoadTempFile("q3key");
|
||||
if (buffer) //a cdkey is meant to be 16 chars
|
||||
{
|
||||
cvar_t *var;
|
||||
char *chr;
|
||||
for (chr = buffer; *chr; chr++)
|
||||
{
|
||||
if (*(unsigned char*)chr < ' ')
|
||||
{
|
||||
*chr = '\0'; //don't get more than one line.
|
||||
break;
|
||||
}
|
||||
}
|
||||
var = Cvar_Get("cl_cdkey", buffer, CVAR_LATCH, "Q3 compatability");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
||||
|
@ -3015,6 +3184,10 @@ void Host_Init (quakeparms_t *parms)
|
|||
Master_SetupSockets();
|
||||
#endif
|
||||
|
||||
#ifdef Q3CLIENT
|
||||
CL_ReadCDKey();
|
||||
#endif
|
||||
|
||||
// Con_Printf ("Exe: "__TIME__" "__DATE__"\n");
|
||||
Con_TPrintf (TL_HEAPSIZE, parms->memsize/ (1024*1024.0));
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
// cl_parse.c -- parse a message received from the server
|
||||
|
||||
#include "quakedef.h"
|
||||
#include "cl_ignore.h"
|
||||
|
||||
void CL_GetNumberedEntityInfo (int num, float *org, float *ang);
|
||||
void CLNQ_ParseDarkPlaces5Entities(void);
|
||||
|
@ -184,7 +185,7 @@ char *svc_nqstrings[] =
|
|||
"dpsvc_spawnstaticsound2"
|
||||
};
|
||||
|
||||
extern cvar_t requiredownloads, cl_standardchat;
|
||||
extern cvar_t requiredownloads, cl_standardchat, msg_filter;
|
||||
int oldparsecountmod;
|
||||
int parsecountmod;
|
||||
double parsecounttime;
|
||||
|
@ -2495,11 +2496,11 @@ void CL_NewTranslation (int slot)
|
|||
int i, j;
|
||||
int top, bottom;
|
||||
qbyte *dest, *source;
|
||||
int local;
|
||||
#endif
|
||||
|
||||
char *s;
|
||||
player_info_t *player;
|
||||
int local;
|
||||
|
||||
if (slot >= MAX_CLIENTS)
|
||||
Sys_Error ("CL_NewTranslation: slot > MAX_CLIENTS");
|
||||
|
@ -2720,12 +2721,11 @@ void CL_SetStat (int pnum, int stat, int value)
|
|||
if (stat == STAT_VIEWHEIGHT && cls.z_ext & Z_EXT_VIEWHEIGHT)
|
||||
cl.viewheight[pnum] = value;
|
||||
|
||||
if (stat == STAT_TIME && cls.z_ext & Z_EXT_SERVERTIME)
|
||||
if (stat == STAT_TIME && (cls.fteprotocolextensions & PEXT_ACCURATETIMINGS))
|
||||
{
|
||||
cl.oldgametime = cl.gametime;
|
||||
cl.oldgametimemark = cl.gametimemark;
|
||||
|
||||
// cl.servertime_works = true;
|
||||
cl.gametime = value * 0.001;
|
||||
cl.gametimemark = realtime;
|
||||
}
|
||||
|
@ -3049,6 +3049,7 @@ char *CL_ParseChat(char *text, player_info_t **player)
|
|||
char *p;
|
||||
extern cvar_t cl_parsewhitetext;
|
||||
char *s;
|
||||
int check_flood;
|
||||
|
||||
flags = TP_CategorizeMessage (text, &offset, player);
|
||||
|
||||
|
@ -3094,6 +3095,16 @@ char *CL_ParseChat(char *text, player_info_t **player)
|
|||
|
||||
if (flags == 2 && !TP_FilterMessage(text + offset))
|
||||
return NULL;
|
||||
|
||||
if ((int)msg_filter.value & flags)
|
||||
return NULL; //filter chat
|
||||
|
||||
check_flood = Ignore_Check_Flood(s, flags, offset);
|
||||
if (check_flood == IGNORE_NO_ADD)
|
||||
return NULL;
|
||||
else if (check_flood == NO_IGNORE_ADD)
|
||||
Ignore_Flood_Add(s);
|
||||
|
||||
}
|
||||
|
||||
suppress_talksound = false;
|
||||
|
@ -4145,8 +4156,9 @@ int MSG_ReadShortPQ (char **s)
|
|||
}
|
||||
void CLNQ_ParseProQuakeMessage (char *s)
|
||||
{
|
||||
int cmd, i, j;
|
||||
int team, frags, shirt, ping;
|
||||
int cmd;
|
||||
int ping;
|
||||
// int team, shirt, frags, i, j;
|
||||
|
||||
s++;
|
||||
cmd = *s++;
|
||||
|
@ -4215,13 +4227,6 @@ void CLNQ_ParseProQuakeMessage (char *s)
|
|||
Host_Error ("CL_ParseProQuakeMessage: pqc_ping_times > MAX_CLIENTS");
|
||||
cl.players[ping / 4096].ping = ping & 4095;
|
||||
}
|
||||
// cl.last_ping_time = cl.time;
|
||||
/*
|
||||
Con_Printf("pqc_ping_times ");
|
||||
for (i = 0 ; i < cl.maxclients ; i++)
|
||||
Con_Printf("%4d ", cl.scores[i].ping);
|
||||
Con_Printf("\n");
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -800,7 +800,7 @@ void SCR_CalcRefdef (void)
|
|||
}
|
||||
size /= 100.0;
|
||||
|
||||
if (!cl_sbar.value && full)
|
||||
if (cl_sbar.value!=1 && full)
|
||||
h = vid.height;
|
||||
else
|
||||
h = vid.height - sb_lines;
|
||||
|
@ -813,7 +813,7 @@ void SCR_CalcRefdef (void)
|
|||
}
|
||||
|
||||
r_refdef.vrect.height = vid.height * size;
|
||||
if (cl_sbar.value || !full) {
|
||||
if (cl_sbar.value==1 || !full) {
|
||||
if (r_refdef.vrect.height > vid.height - sb_lines)
|
||||
r_refdef.vrect.height = vid.height - sb_lines;
|
||||
} else if (r_refdef.vrect.height > vid.height)
|
||||
|
|
|
@ -143,6 +143,8 @@ typedef struct player_info_s
|
|||
int ping;
|
||||
qbyte pl;
|
||||
|
||||
qboolean ignored;
|
||||
|
||||
// skin information
|
||||
int topcolor;
|
||||
int bottomcolor;
|
||||
|
@ -299,6 +301,7 @@ typedef struct
|
|||
} protocol;
|
||||
|
||||
qboolean resendinfo;
|
||||
qboolean findtrack;
|
||||
|
||||
int framecount;
|
||||
|
||||
|
@ -316,6 +319,13 @@ typedef struct
|
|||
int socketip6;
|
||||
int socketipx;
|
||||
|
||||
#ifdef TCPCONNECT
|
||||
int sockettcp;
|
||||
netadr_t sockettcpdest;
|
||||
unsigned char tcpinbuffer[1500];
|
||||
int tcpinlen;
|
||||
#endif
|
||||
|
||||
enum {DL_NONE, DL_QW, DL_QWCHUNKS, DL_Q3, DL_QWPENDING, DL_HTTP, DL_FTP} downloadmethod;
|
||||
FILE *downloadqw; // file transfer from server
|
||||
char downloadtempname[MAX_OSPATH];
|
||||
|
|
|
@ -972,7 +972,6 @@ void CLQ3_SendAuthPacket(netadr_t gameserver)
|
|||
//this should be the right code, but it doesn't work.
|
||||
if (gameserver.type == NA_IP)
|
||||
{
|
||||
char keydata[64];
|
||||
char *key = Cvar_Get("cl_cdkey", "", 0, "Quake3 auth")->string;
|
||||
netadr_t authaddr;
|
||||
#define AUTHORIZE_SERVER_NAME "authorize.quake3arena.com:27952"
|
||||
|
|
|
@ -726,16 +726,16 @@ int Image_WritePNG (char *filename, int compression, qbyte *pixels, int width, i
|
|||
|
||||
#if defined(_WIN32)
|
||||
|
||||
#define JPEG_API VARGS
|
||||
#include "jpeglib.h"
|
||||
#include "jerror.h"
|
||||
#pragma comment(lib, "../libs/jpeg.lib")
|
||||
#define JPEG_API VARGS
|
||||
#include "jpeglib.h"
|
||||
#include "jerror.h"
|
||||
#pragma comment(lib, "../libs/jpeg.lib")
|
||||
|
||||
#else
|
||||
|
||||
//#include <jinclude.h>
|
||||
#include <jpeglib.h>
|
||||
#include <jerror.h>
|
||||
// #include <jinclude.h>
|
||||
#include <jpeglib.h>
|
||||
#include <jerror.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1113,7 +1113,7 @@ qboolean Media_ShowFilm(void)
|
|||
unsigned char *pa=roqfilm->y[0];
|
||||
unsigned char *pb=roqfilm->u[0];
|
||||
unsigned char *pc=roqfilm->v[0];
|
||||
int pix=0;
|
||||
int pixel=0;
|
||||
int num_columns=(roqfilm->width)>>1;
|
||||
int y;
|
||||
int x;
|
||||
|
@ -1141,19 +1141,19 @@ qboolean Media_ShowFilm(void)
|
|||
b = 116130 * u;
|
||||
|
||||
t=r+y1;
|
||||
framedata[pix] =(unsigned char) LIMIT(t);
|
||||
framedata[pixel] =(unsigned char) LIMIT(t);
|
||||
t=g+y1;
|
||||
framedata[pix+1] =(unsigned char) LIMIT(t);
|
||||
framedata[pixel+1] =(unsigned char) LIMIT(t);
|
||||
t=b+y1;
|
||||
framedata[pix+2] =(unsigned char) LIMIT(t);
|
||||
framedata[pixel+2] =(unsigned char) LIMIT(t);
|
||||
|
||||
t=r+y2;
|
||||
framedata[pix+4] =(unsigned char) LIMIT(t);
|
||||
framedata[pixel+4] =(unsigned char) LIMIT(t);
|
||||
t=g+y2;
|
||||
framedata[pix+5] =(unsigned char) LIMIT(t);
|
||||
framedata[pixel+5] =(unsigned char) LIMIT(t);
|
||||
t=b+y2;
|
||||
framedata[pix+6] =(unsigned char) LIMIT(t);
|
||||
pix+=8;
|
||||
framedata[pixel+6] =(unsigned char) LIMIT(t);
|
||||
pixel+=8;
|
||||
|
||||
}
|
||||
if(y & 0x01) { pb += num_columns; pc += num_columns; }
|
||||
|
@ -1329,7 +1329,7 @@ void Media_RecordFrame (void)
|
|||
return;
|
||||
|
||||
if (recordingdemo)
|
||||
if (scr_con_current > 0)
|
||||
if (scr_con_current > 0 || !cl.validsequence)
|
||||
{
|
||||
scr_con_current=0;
|
||||
key_dest = key_game;
|
||||
|
@ -1354,6 +1354,8 @@ void Media_RecordFrame (void)
|
|||
}
|
||||
else*/
|
||||
{
|
||||
if (recordavi_videotime > realtime+1)
|
||||
recordavi_videotime = realtime; //urm, wrapped?..
|
||||
if (recordavi_videotime > realtime)
|
||||
goto skipframe;
|
||||
recordavi_videotime += recordavi_frametime;
|
||||
|
@ -1381,7 +1383,7 @@ void Media_RecordFrame (void)
|
|||
case CT_SCREENSHOT:
|
||||
{
|
||||
char filename[MAX_OSPATH];
|
||||
sprintf(filename, "%s%i.%s", capturefilenameprefix, captureframe++, capturecodec.string);
|
||||
sprintf(filename, "%s/%8.8i.%s", capturefilenameprefix, captureframe++, capturecodec.string);
|
||||
SCR_ScreenShot(filename);
|
||||
}
|
||||
break;
|
||||
|
@ -1421,6 +1423,9 @@ void Media_RecordAudioFrame (short *sample_buffer, int samples)
|
|||
return;
|
||||
}
|
||||
|
||||
if (captureaudiosamples > recordavi_wave_format.nSamplesPerSec)
|
||||
captureaudiosamples = 0; //doh, this WILL cause a bit of wierd sound...
|
||||
|
||||
memcpy(captureaudiomem+captureaudiosamples*2, sample_buffer, samples*2);
|
||||
|
||||
captureaudiosamples+=samples/2;
|
||||
|
@ -1504,7 +1509,7 @@ void Media_RecordFilm_f (void)
|
|||
|
||||
recordavi_frametime = 1/capturerate.value;
|
||||
|
||||
if (fourcc)
|
||||
if (*fourcc)
|
||||
{
|
||||
if (!strcmp(fourcc, "tga") ||
|
||||
!strcmp(fourcc, "png") ||
|
||||
|
@ -1648,7 +1653,7 @@ void Media_RecordDemo_f(void)
|
|||
scr_con_current=0;
|
||||
key_dest = key_game;
|
||||
|
||||
if (recordavi_video_stream)
|
||||
if (capturetype != CT_NONE)
|
||||
recordingdemo = true;
|
||||
}
|
||||
#else
|
||||
|
|
|
@ -365,6 +365,7 @@ typedef struct {
|
|||
presetinfo_t preset[] =
|
||||
{
|
||||
{"r_presetname", {"286", "fast", "default", "nice", "realtime"}},
|
||||
{"gl_texturemode", {"nn", "ln", "ln", "ll", "ll"}},
|
||||
{"r_particlesdesc", {"none", "highfps", "spikeset", "spikeset", "spikeset"}},
|
||||
{"r_stains", {"0", "0", "1", "1", "1"}},
|
||||
{"r_drawflat", {"1", "0", "0", "0", "0"}},
|
||||
|
|
|
@ -116,9 +116,6 @@ void Master_SetupSockets(void)
|
|||
pollsocketsIPX[i] = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
|
||||
void NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s);
|
||||
|
||||
void Master_HideServer(serverinfo_t *server)
|
||||
{
|
||||
int i, j;
|
||||
|
|
|
@ -848,7 +848,7 @@ static void buildmatricies(void)
|
|||
ML_ModelViewMatrix(modelview, r_refdef.viewangles, r_refdef.vieworg);
|
||||
ML_ProjectionMatrix2(proj, r_refdef.fov_x, r_refdef.fov_y);
|
||||
Matrix4_Multiply(proj, modelview, mvp);
|
||||
Matrix4x4_Invert_Simple(mvpi, mvp); //not actually used in this function.
|
||||
Matrix4x4_Invert_Simple((matrix4x4_t*)mvpi, (matrix4x4_t*)mvp); //not actually used in this function.
|
||||
|
||||
csqc_rebuildmatricies = false;
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#pragma warning(3:4674) // dtor of thrown object is inaccessible
|
||||
#pragma warning(3:4705) // statement has no effect (example: a+1;)
|
||||
|
||||
#pragma warning(4:4013) // statement has no effect (example: a+1;)
|
||||
|
||||
|
||||
#pragma warning( 4 : 4267) //truncation from const double to float
|
||||
#endif
|
||||
|
|
|
@ -85,6 +85,7 @@ static cvar_t vid_width = {"vid_width", "640", NULL, CVAR_ARCHIVE|CVAR_RENDERERL
|
|||
static cvar_t vid_height = {"vid_height", "480", NULL, CVAR_ARCHIVE|CVAR_RENDERERLATCH};
|
||||
static cvar_t vid_refreshrate = {"vid_displayfrequency", "0", NULL, CVAR_ARCHIVE|CVAR_RENDERERLATCH};
|
||||
|
||||
cvar_t gl_texturemode = {"gl_texturemode", "GL_LINEAR_MIPMAP_NEAREST"};
|
||||
cvar_t gl_motionblur = {"gl_motionblur", "0"};
|
||||
cvar_t gl_motionblurscale = {"gl_motionblurscale", "1"};
|
||||
cvar_t gl_fontedgeclamp = {"gl_fontedgeclamp", "0"}; //gl blends. Set this to 1 to stop the outside of your conchars from being visible
|
||||
|
@ -148,6 +149,7 @@ cvar_t gl_mylumassuck = {"gl_mylumassuck", "0"};
|
|||
cvar_t scr_sshot_type = {"scr_sshot_type", "jpg"};
|
||||
|
||||
|
||||
cvar_t scr_centersbar = {"scr_centersbar", "0"};
|
||||
cvar_t scr_consize = {"scr_consize", "0.5"};
|
||||
cvar_t scr_viewsize = {"viewsize","100", NULL, CVAR_ARCHIVE};
|
||||
cvar_t scr_fov = {"fov","90", NULL, CVAR_ARCHIVE}; // 10 - 170
|
||||
|
@ -313,11 +315,11 @@ void GLRenderer_Init(void)
|
|||
#endif
|
||||
|
||||
Cvar_Register (&gl_nobind, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_max_size, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_picmip, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_picmip2d, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_drawdisk, GLRENDEREROPTIONS);
|
||||
|
||||
Cvar_Register (&gl_texturemode, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_savecompressedtex, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_compress, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&gl_driver, GLRENDEREROPTIONS);
|
||||
|
@ -447,7 +449,6 @@ void Renderer_Init(void)
|
|||
Cvar_Register (&_windowed_mouse, VIDCOMMANDGROUP);
|
||||
Cvar_Register (&vid_renderer, VIDCOMMANDGROUP);
|
||||
|
||||
Cvar_Register (&_windowed_mouse, VIDCOMMANDGROUP);
|
||||
Cvar_Register (&vid_fullscreen, VIDCOMMANDGROUP);
|
||||
// Cvar_Register (&vid_stretch, VIDCOMMANDGROUP);
|
||||
Cvar_Register (&vid_bpp, VIDCOMMANDGROUP);
|
||||
|
@ -471,21 +472,12 @@ void Renderer_Init(void)
|
|||
|
||||
Cvar_Register(&scr_viewsize, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_fov, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_conspeed, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_centertime, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_showram, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_showturtle, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_showpause, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_printspeed, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_allowsnap, SCREENOPTIONS);
|
||||
Cvar_Register(&scr_chatmodecvar, SCREENOPTIONS);
|
||||
|
||||
Cvar_Register (&scr_sshot_type, SCREENOPTIONS);
|
||||
|
||||
|
||||
//screen
|
||||
Cvar_Register (&scr_fov, SCREENOPTIONS);
|
||||
Cvar_Register (&scr_viewsize, SCREENOPTIONS);
|
||||
Cvar_Register (&scr_conspeed, SCREENOPTIONS);
|
||||
Cvar_Register (&scr_showram, SCREENOPTIONS);
|
||||
Cvar_Register (&scr_showturtle, SCREENOPTIONS);
|
||||
|
|
|
@ -1643,10 +1643,19 @@ void Sbar_Draw (void)
|
|||
}
|
||||
else
|
||||
{ //single player sbar takes full screen
|
||||
|
||||
extern cvar_t scr_centersbar;
|
||||
|
||||
sbar_rect.width = vid.width;
|
||||
sbar_rect.height = vid.height;
|
||||
sbar_rect.x = 0;
|
||||
sbar_rect.y = 0;
|
||||
|
||||
if (scr_centersbar.value)
|
||||
{
|
||||
sbar_rect.x = (vid.width - 320)/2;
|
||||
sbar_rect.width -= sbar_rect.x;
|
||||
}
|
||||
}
|
||||
|
||||
if (sbarfailed) //files failed to load.
|
||||
|
@ -1668,7 +1677,7 @@ void Sbar_Draw (void)
|
|||
{
|
||||
if (!cl.spectator || autocam[pnum] == CAM_TRACK)
|
||||
Sbar_DrawInventory (pnum);
|
||||
if (!headsup || sbar_rect.width<512)
|
||||
if ((!headsup || sbar_rect.width<512) && cl.deathmatch)
|
||||
Sbar_DrawFrags ();
|
||||
}
|
||||
|
||||
|
@ -1732,25 +1741,19 @@ void Sbar_Draw (void)
|
|||
Sbar_TeamOverlay();
|
||||
|
||||
#ifdef RGLQUAKE
|
||||
if (cl.splitclients)
|
||||
if (cl_sbar.value == 1 || scr_viewsize.value<100)
|
||||
{
|
||||
if (sb_showscores || sb_showteamscores ||
|
||||
deadcount == cl.splitclients)
|
||||
sb_updates = 0;
|
||||
// clear unused areas in gl
|
||||
#if 0
|
||||
{
|
||||
int x = (sbar_rect.width - 320)>>1;
|
||||
|
||||
// left
|
||||
if (x > 0) {
|
||||
Draw_TileClear (0, sbar_rect.height - sb_lines, x, sb_lines);
|
||||
Draw_TileClear (x+320, sbar_rect.height - sb_lines, sbar_rect.width - x+320, sb_lines);
|
||||
}
|
||||
if (cl.splitclients==1 && sbar_rect.x>0)
|
||||
{ // left
|
||||
Draw_TileClear (0, sbar_rect.height - sb_lines, sbar_rect.x, sb_lines);
|
||||
}
|
||||
#endif
|
||||
if (sbar_rect.width > 320 && !headsup)
|
||||
Draw_TileClear (320, sbar_rect.height - sb_lines, sbar_rect.width - 320, sb_lines);
|
||||
if (sbar_rect.x + 320 <= sbar_rect.width && !headsup)
|
||||
Draw_TileClear (sbar_rect.x + 320, sbar_rect.height - sb_lines, sbar_rect.width - (320), sb_lines);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1114,6 +1114,7 @@ S_UpdateAmbientSounds
|
|||
===================
|
||||
*/
|
||||
char *Media_NextTrack(void);
|
||||
mleaf_t *Q1BSP_LeafForPoint (model_t *model, vec3_t p);
|
||||
void S_UpdateAmbientSounds (soundcardinfo_t *sc)
|
||||
{
|
||||
mleaf_t *l;
|
||||
|
|
|
@ -148,73 +148,15 @@ void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, qbyte *data)
|
|||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
==============
|
||||
S_LoadSound
|
||||
==============
|
||||
*/
|
||||
#ifdef AVAIL_MP3
|
||||
sfxcache_t *S_LoadMP3Sound (sfx_t *s);
|
||||
#endif
|
||||
sfxcache_t *S_LoadOVSound (sfx_t *s);
|
||||
typedef sfxcache_t *(*S_LoadSound_t) (sfx_t *s, qbyte *data, int datalen, int sndspeed);
|
||||
|
||||
sfxcache_t *S_LoadSound (sfx_t *s)
|
||||
sfxcache_t *S_LoadWavSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
|
||||
{
|
||||
char namebuffer[256];
|
||||
qbyte *data;
|
||||
wavinfo_t info;
|
||||
int len;
|
||||
sfxcache_t *sc;
|
||||
qbyte stackbuf[1*1024]; // avoid dirtying the cache heap
|
||||
|
||||
// see if still in memory
|
||||
sc = Cache_Check (&s->cache);
|
||||
if (sc)
|
||||
return sc;
|
||||
|
||||
#ifdef AVAIL_OGGVORBIS
|
||||
//ogg vorbis support. The only bit actual code outside snd_ov.c (excluding def for the function call)
|
||||
sc = S_LoadOVSound(s); // try and load a replacement ov instead.
|
||||
if (sc)
|
||||
return sc;
|
||||
#endif
|
||||
|
||||
#ifdef AVAIL_MP3
|
||||
//mp3 support. The only bit actual code outside snd_mp3.c (excluding def for the function call)
|
||||
sc = S_LoadMP3Sound(s); // try and load a replacement mp3 instead.
|
||||
if (sc)
|
||||
return sc;
|
||||
#endif
|
||||
|
||||
|
||||
//Con_Printf ("S_LoadSound: %x\n", (int)stackbuf);
|
||||
// load it in
|
||||
|
||||
if (*s->name == '*')
|
||||
{
|
||||
Q_strcpy(namebuffer, "players/male/"); //q2
|
||||
Q_strcat(namebuffer, s->name+1); //q2
|
||||
}
|
||||
else if (s->name[0] == '.' && s->name[1] == '.' && s->name[2] == '/')
|
||||
Q_strcpy(namebuffer, s->name+3);
|
||||
else
|
||||
{
|
||||
Q_strcpy(namebuffer, "sound/");
|
||||
Q_strcat(namebuffer, s->name);
|
||||
}
|
||||
|
||||
// Con_Printf ("loading %s\n",namebuffer);
|
||||
|
||||
data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf));
|
||||
|
||||
if (!data)
|
||||
{
|
||||
//FIXME: check to see if qued for download.
|
||||
Con_Printf ("Couldn't load %s\n", namebuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info = GetWavinfo (s->name, data, com_filesize);
|
||||
info = GetWavinfo (s->name, data, datalen);
|
||||
if (info.numchannels < 1 || info.numchannels > 2)
|
||||
{
|
||||
Con_Printf ("%s has an unsupported quantity of channels.\n",s->name);
|
||||
|
@ -226,7 +168,9 @@ sfxcache_t *S_LoadSound (sfx_t *s)
|
|||
|
||||
sc = Cache_Alloc ( &s->cache, len + sizeof(sfxcache_t), s->name);
|
||||
if (!sc)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sc->length = info.samples;
|
||||
sc->loopstart = info.loopstart;
|
||||
|
@ -239,6 +183,138 @@ sfxcache_t *S_LoadSound (sfx_t *s)
|
|||
return sc;
|
||||
}
|
||||
|
||||
sfxcache_t *S_LoadOVSound (sfx_t *s, qbyte *data, int datalen, int sndspeed);
|
||||
|
||||
S_LoadSound_t AudioInputPlugins[8] =
|
||||
{
|
||||
S_LoadWavSound
|
||||
|
||||
#ifdef AVAIL_OGGVORBIS
|
||||
// , S_LoadOVSound
|
||||
#endif
|
||||
};
|
||||
|
||||
qboolean S_RegisterSoundInputPlugin(S_LoadSound_t loadfnc)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sizeof(AudioInputPlugins)/sizeof(AudioInputPlugins[0]); i++)
|
||||
{
|
||||
if (!AudioInputPlugins[i])
|
||||
{
|
||||
AudioInputPlugins[i] = loadfnc;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
S_LoadSound
|
||||
==============
|
||||
*/
|
||||
#ifdef AVAIL_MP3
|
||||
sfxcache_t *S_LoadMP3Sound (sfx_t *s);
|
||||
#endif
|
||||
|
||||
sfxcache_t *S_LoadSound (sfx_t *s)
|
||||
{
|
||||
char stackbuf[65536];
|
||||
char namebuffer[256];
|
||||
qbyte *data;
|
||||
sfxcache_t *sc;
|
||||
int i;
|
||||
|
||||
char *name = s->name;
|
||||
|
||||
// see if still in memory
|
||||
sc = Cache_Check (&s->cache);
|
||||
if (sc)
|
||||
return sc;
|
||||
|
||||
s->decoder = NULL;
|
||||
|
||||
|
||||
#ifdef AVAIL_MP3
|
||||
//mp3 support. The only bit actual code outside snd_mp3.c (excluding def for the function call)
|
||||
sc = S_LoadMP3Sound(s); // try and load a replacement mp3 instead.
|
||||
if (sc)
|
||||
return sc;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
if (name[1] == ':' && name[2] == '\\')
|
||||
{
|
||||
FILE *f;
|
||||
#ifndef _WIN32 //convert from windows to a suitable alternative.
|
||||
char unixname[128];
|
||||
sprintf(unixname, "/mnt/%c/%s", name[0]-'A'+'a', name+3);
|
||||
name = unixname;
|
||||
while (*name)
|
||||
{
|
||||
if (*name == '\\')
|
||||
*name = '/';
|
||||
name++;
|
||||
}
|
||||
name = unixname;
|
||||
#endif
|
||||
|
||||
if ((f = fopen(name, "rb")))
|
||||
{
|
||||
com_filesize = COM_filelength(f);
|
||||
data = Hunk_TempAlloc (com_filesize);
|
||||
fread(data, 1, com_filesize, f);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_SafePrintf ("Couldn't load %s\n", namebuffer);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Con_Printf ("S_LoadSound: %x\n", (int)stackbuf);
|
||||
// load it in
|
||||
|
||||
if (*name == '*')
|
||||
{
|
||||
Q_strcpy(namebuffer, "players/male/"); //q2
|
||||
Q_strcat(namebuffer, name+1); //q2
|
||||
}
|
||||
else if (name[0] == '.' && name[1] == '.' && name[2] == '/')
|
||||
Q_strcpy(namebuffer, name+3);
|
||||
else
|
||||
{
|
||||
Q_strcpy(namebuffer, "sound/");
|
||||
Q_strcat(namebuffer, name);
|
||||
}
|
||||
|
||||
// Con_Printf ("loading %s\n",namebuffer);
|
||||
|
||||
data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf));
|
||||
}
|
||||
|
||||
if (!data)
|
||||
{
|
||||
//FIXME: check to see if qued for download.
|
||||
Con_Printf ("Couldn't load %s\n", namebuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = sizeof(AudioInputPlugins)/sizeof(AudioInputPlugins[0])-1; i >= 0; i--)
|
||||
{
|
||||
if (AudioInputPlugins[i])
|
||||
{
|
||||
sc = AudioInputPlugins[i](s, data, com_filesize, snd_speed);
|
||||
if (sc)
|
||||
return sc;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -15,12 +15,12 @@ HINSTANCE oggvorbislibrary;
|
|||
void *oggvorbislibrary;
|
||||
#endif
|
||||
|
||||
int (*p_ov_open_callbacks) (void *datasource, OggVorbis_File *vf, char *initial, long ibytes, ov_callbacks callbacks);
|
||||
int (*p_ov_clear)(OggVorbis_File *vf);
|
||||
vorbis_info *(*p_ov_info)(OggVorbis_File *vf,int link);
|
||||
vorbis_comment *(*p_ov_comment) (OggVorbis_File *vf,int link);
|
||||
ogg_int64_t (*p_ov_pcm_total)(OggVorbis_File *vf,int i);
|
||||
long (*p_ov_read)(OggVorbis_File *vf,char *buffer,int length,
|
||||
int (VARGS *p_ov_open_callbacks) (void *datasource, OggVorbis_File *vf, char *initial, long ibytes, ov_callbacks callbacks);
|
||||
int (VARGS *p_ov_clear)(OggVorbis_File *vf);
|
||||
vorbis_info *(VARGS *p_ov_info)(OggVorbis_File *vf,int link);
|
||||
vorbis_comment *(VARGS *p_ov_comment) (OggVorbis_File *vf,int link);
|
||||
ogg_int64_t (VARGS *p_ov_pcm_total)(OggVorbis_File *vf,int i);
|
||||
long (VARGS *p_ov_read)(OggVorbis_File *vf,char *buffer,int length,
|
||||
int bigendianp,int word,int sgned,int *bitstream);
|
||||
|
||||
|
||||
|
@ -48,67 +48,18 @@ qboolean OV_StartDecode(unsigned char *start, unsigned long length, ovdecoderbuf
|
|||
|
||||
qbyte *COM_LoadFile (char *path, int usehunk);
|
||||
|
||||
sfxcache_t *S_LoadOVSound (sfx_t *s)
|
||||
sfxcache_t *S_LoadOVSound (sfx_t *s, qbyte *data, int datalen, int sndspeed)
|
||||
{
|
||||
char namebuffer[MAX_OSPATH];
|
||||
char *name;
|
||||
ovdecoderbuffer_t *buffer;
|
||||
FILE *f;
|
||||
|
||||
char *data;
|
||||
qboolean telluser;
|
||||
int len;
|
||||
|
||||
name = s->name;
|
||||
|
||||
if (name[0] == '#')
|
||||
strcpy(namebuffer, &name[1]);
|
||||
else
|
||||
sprintf (namebuffer, "sound/%s", name);
|
||||
|
||||
len = strlen(namebuffer);
|
||||
telluser = strcmp(namebuffer+len-4, ".wav");
|
||||
if (!telluser)
|
||||
strcpy(namebuffer+len-4, ".ogg");
|
||||
|
||||
//try opening from a quake path
|
||||
data = COM_LoadMallocFile(namebuffer);
|
||||
if (!data)
|
||||
{//if that didn't work, try opening direct from exe - this is media after all.
|
||||
|
||||
if (!telluser)
|
||||
return NULL; //never go out of the quake path for a wav replacement.
|
||||
#ifndef _WIN32
|
||||
char unixname[128];
|
||||
if (name[1] == ':' && name[2] == '\\') //convert from windows to a suitable alternative.
|
||||
{
|
||||
sprintf(unixname, "/mnt/%c/%s", name[0]-'A'+'a', name+3);
|
||||
name = unixname;
|
||||
while (*name)
|
||||
{
|
||||
if (*name == '\\')
|
||||
*name = '/';
|
||||
name++;
|
||||
}
|
||||
name = unixname;
|
||||
}
|
||||
#endif
|
||||
if ((f = fopen(name, "rb")))
|
||||
{
|
||||
com_filesize = COM_filelength(f);
|
||||
data = BZ_Malloc(com_filesize);
|
||||
fread(data, 1, com_filesize, f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_SafePrintf ("Couldn't load %s\n", namebuffer);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!s->decoder)
|
||||
s->decoder = Z_Malloc(sizeof(ovdecoderbuffer_t) + sizeof(sfxdecode_t));
|
||||
buffer = (ovdecoderbuffer_t*)(s->decoder+1);
|
||||
|
@ -120,7 +71,7 @@ sfxcache_t *S_LoadOVSound (sfx_t *s)
|
|||
s->decoder->decodemore = OV_DecodeSome;
|
||||
s->decoder->abort = OV_CancelDecoder;
|
||||
|
||||
if (!OV_StartDecode(data, com_filesize, buffer))
|
||||
if (!OV_StartDecode(data, datalen, buffer))
|
||||
{
|
||||
if (buffer->mediaaswavdata)
|
||||
{
|
||||
|
@ -152,11 +103,11 @@ int OV_DecodeSome(sfx_t *s, int minlength)
|
|||
ovdecoderbuffer_t *dec = s->decoder->buf;
|
||||
int bytesread;
|
||||
|
||||
Con_Printf("Minlength = %03i ", minlength);
|
||||
// Con_Printf("Minlength = %03i ", minlength);
|
||||
|
||||
if (dec->mediaaswavbuflen < dec->mediaaswavpos+minlength+11050) //expand if needed.
|
||||
{
|
||||
Con_Printf("Expand buffer\n");
|
||||
// Con_Printf("Expand buffer\n");
|
||||
dec->mediaaswavbuflen += minlength+22100;
|
||||
dec->mediaaswavdata = BZ_Realloc(dec->mediaaswavdata, dec->mediaaswavbuflen);
|
||||
s->cache.data = dec->mediaaswavdata;
|
||||
|
@ -171,7 +122,7 @@ int OV_DecodeSome(sfx_t *s, int minlength)
|
|||
|
||||
if (minlength < sc->length)
|
||||
{
|
||||
Con_Printf("No need for decode\n");
|
||||
// Con_Printf("No need for decode\n");
|
||||
//done enough for now, don't whizz through the lot
|
||||
return 0;
|
||||
}
|
||||
|
@ -206,7 +157,7 @@ int OV_DecodeSome(sfx_t *s, int minlength)
|
|||
|
||||
if (minlength<=sc->length)
|
||||
{
|
||||
Con_Printf("Reached length\n");
|
||||
// Con_Printf("Reached length\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -355,6 +306,10 @@ qboolean OV_StartDecode(unsigned char *start, unsigned long length, ovdecoderbuf
|
|||
(long)p_ov_pcm_total(&buffer->vf,-1));
|
||||
Con_Printf("Encoded by: %s\n\n",p_ov_comment(&buffer->vf,-1)->vendor);
|
||||
*/ }
|
||||
|
||||
buffer->start = BZ_Malloc(length);
|
||||
memcpy(buffer->start, start, length);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -869,7 +869,7 @@ qboolean Sys_InitTerminal (void)
|
|||
if (!AllocConsole())
|
||||
return false;
|
||||
SetConsoleCtrlHandler (HandlerRoutine, TRUE);
|
||||
SetConsoleTitle (FULLENGINENAME, " dedicated server");
|
||||
SetConsoleTitle (FULLENGINENAME " dedicated server");
|
||||
hinput = GetStdHandle (STD_INPUT_HANDLE);
|
||||
houtput = GetStdHandle (STD_OUTPUT_HANDLE);
|
||||
|
||||
|
|
|
@ -1243,6 +1243,7 @@ entity_t *CL_EntityNum(int num)
|
|||
float CalcFov (float fov_x, float width, float height);
|
||||
void SCR_VRectForPlayer(vrect_t *vrect, int pnum)
|
||||
{
|
||||
extern int glwidth, glheight;
|
||||
#if MAX_SPLITS > 4
|
||||
#pragma warning "Please change this function to cope with the new MAX_SPLITS value"
|
||||
#endif
|
||||
|
@ -1263,10 +1264,20 @@ void SCR_VRectForPlayer(vrect_t *vrect, int pnum)
|
|||
|
||||
case 2: //horizontal bands
|
||||
case 3:
|
||||
vrect->width = vid.width;
|
||||
vrect->height = vid.height/cl.splitclients;
|
||||
vrect->x = 0;
|
||||
vrect->y = 0 + vrect->height*pnum;
|
||||
if (glwidth > glheight * 2)
|
||||
{ //over twice as wide as high, assume duel moniter, horizontal.
|
||||
vrect->width = vid.width/cl.splitclients;
|
||||
vrect->height = vid.height;
|
||||
vrect->x = 0 + vrect->width*pnum;
|
||||
vrect->y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vrect->width = vid.width;
|
||||
vrect->height = vid.height/cl.splitclients;
|
||||
vrect->x = 0;
|
||||
vrect->y = 0 + vrect->height*pnum;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
@ -1625,7 +1636,6 @@ void V_Init (void)
|
|||
Cvar_Register (&v_kickroll, VIEWVARS);
|
||||
Cvar_Register (&v_kickpitch, VIEWVARS);
|
||||
|
||||
Cvar_Register (&v_idlescale, VIEWVARS);
|
||||
Cvar_Register (&v_deathtilt, VIEWVARS);
|
||||
|
||||
Cvar_Register (&scr_autoid, VIEWVARS);
|
||||
|
|
|
@ -92,21 +92,6 @@ static size_t strlcat (char *dst, const char *src, size_t size)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
|
||||
va_start (argptr, fmt);
|
||||
#ifdef _WIN32
|
||||
_vsnprintf (dest, size, fmt, argptr);
|
||||
#else
|
||||
vsnprintf (dest, size, fmt, argptr);
|
||||
#endif
|
||||
va_end (argptr);
|
||||
|
||||
dest[size-1] = 0;
|
||||
}
|
||||
|
||||
//a list of all the cvars
|
||||
//this is down to the fact that I keep defining them but forgetting to register. :/
|
||||
#define TP_CVARS \
|
||||
|
|
|
@ -115,6 +115,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define SVCHAT //serverside npc chatting. see sv_chat.c
|
||||
#define Q2SERVER //server can run a q2 game dll and switches to q2 network and everything else.
|
||||
#define Q2CLIENT //client can connect to q2 servers
|
||||
#define Q3CLIENT
|
||||
#define Q3SERVER
|
||||
#define NQPROT //server and client are capable of using quake1/netquake protocols. (qw is still prefered. uses the command 'nqconnect')
|
||||
#define FISH //sw rendering only
|
||||
#define ZLIB //zip/pk3 support
|
||||
|
@ -130,6 +132,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define PPL //per pixel lighting (stencil shadowing)
|
||||
#define DDS //a sort of image file format.
|
||||
|
||||
#define TCPCONNECT //a tcpconnect command, that allows the player to connect to tcp-encapsulated qw protocols.
|
||||
|
||||
#define PLUGINS
|
||||
|
||||
#define CSQC_DAT //support for csqc
|
||||
|
|
|
@ -176,6 +176,9 @@ void Cbuf_AddText (const char *text, int level)
|
|||
{
|
||||
int l;
|
||||
|
||||
if (!strcmp(text, "cmd "))
|
||||
Con_Printf("cmd text\n");
|
||||
|
||||
if (level > sizeof(cmd_text)/sizeof(cmd_text[0]) || level < 0)
|
||||
{
|
||||
Con_Printf("Bad execution level\n");
|
||||
|
@ -2721,6 +2724,7 @@ void Cmd_WriteConfig_f(void)
|
|||
fprintf(f, "// FTE config file\n\n");
|
||||
#ifndef SERVERONLY
|
||||
Key_WriteBindings (f);
|
||||
CL_SaveInfo(f);
|
||||
#else
|
||||
fprintf(f, "// Dedicated Server config\n\n");
|
||||
#endif
|
||||
|
@ -2732,6 +2736,8 @@ void Cmd_WriteConfig_f(void)
|
|||
Alias_WriteAliases (f);
|
||||
Cvar_WriteVariables (f, true);
|
||||
fclose(f);
|
||||
|
||||
FS_FlushFSHash();
|
||||
}
|
||||
|
||||
#ifndef SERVERONLY
|
||||
|
|
|
@ -154,6 +154,24 @@ void Q_strncpyz(char *d, const char *s, int n)
|
|||
*d='\0';
|
||||
}
|
||||
|
||||
//windows/linux have inconsistant snprintf
|
||||
//this is an attempt to get them consistant and safe
|
||||
//size is the total size of the buffer
|
||||
void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
|
||||
va_start (argptr, fmt);
|
||||
#ifdef _WIN32
|
||||
_vsnprintf (dest, size, fmt, argptr);
|
||||
#else
|
||||
vsnprintf (dest, size, fmt, argptr);
|
||||
#endif
|
||||
va_end (argptr);
|
||||
|
||||
dest[size-1] = 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void Q_memset (void *dest, int fill, int count)
|
||||
|
@ -2725,6 +2743,37 @@ void Info_Print (char *s)
|
|||
}
|
||||
}
|
||||
|
||||
void Info_WriteToFile(FILE *f, char *info, char *commandname, int cvarflags)
|
||||
{
|
||||
char *command;
|
||||
char *value;
|
||||
cvar_t *var;
|
||||
|
||||
while(*info == '\\')
|
||||
{
|
||||
command = info+1;
|
||||
value = strchr(command, '\\');
|
||||
info = strchr(value+1, '\\');
|
||||
if (!info) //eot..
|
||||
info = value+strlen(value);
|
||||
|
||||
if (*command == '*') //unsettable, so don't write it for later setting.
|
||||
continue;
|
||||
|
||||
var = Cvar_FindVar(command);
|
||||
if (var && var->flags & cvarflags)
|
||||
continue; //this is saved via a cvar.
|
||||
|
||||
fwrite(commandname, strlen(commandname), 1, f);
|
||||
fwrite(" ", 1, 1, f);
|
||||
fwrite(command, value-command, 1, f);
|
||||
fwrite(" ", 1, 1, f);
|
||||
fwrite(value+1, info-(value+1), 1, f);
|
||||
fwrite("\n", 1, 1, f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static qbyte chktbl[1024 + 4] = {
|
||||
0x78,0xd2,0x94,0xe3,0x41,0xec,0xd6,0xd5,0xcb,0xfc,0xdb,0x8a,0x4b,0xcc,0x85,0x01,
|
||||
0x23,0xd2,0xe5,0xf2,0x29,0xa7,0x45,0x94,0x4a,0x62,0xe3,0xa5,0x6f,0x3f,0xe1,0x7a,
|
||||
|
|
|
@ -183,6 +183,7 @@ int wildcmp(char *wild, char *string); //1 if match
|
|||
#define Q_strcmp(s1, s2) strcmp((s1), (s2))
|
||||
#define Q_strncmp(s1, s2, n) strncmp((s1), (s2), (n))
|
||||
|
||||
void VARGS Q_snprintfz (char *dest, size_t size, char *fmt, ...);
|
||||
|
||||
#define Q_strncpyS(d, s, n) do{const char *____in=(s);char *____out=(d);int ____i; for (____i=0;*(____in); ____i++){if (____i == (n))break;*____out++ = *____in++;}if (____i < (n))*____out='\0';}while(0) //only use this when it should be used. If undiciided, use N
|
||||
#define Q_strncpyN(d, s, n) do{if (n < 0)Sys_Error("Bad length in strncpyz");Q_strncpyS((d), (s), (n));((char *)(d))[n] = '\0';}while(0) //this'll stop me doing buffer overflows. (guarenteed to overflow if you tried the wrong size.)
|
||||
|
@ -320,11 +321,13 @@ extern qboolean standard_quake; //fixme: remove
|
|||
#define MAX_INFO_KEY 64
|
||||
char *Info_ValueForKey (char *s, const char *key);
|
||||
void Info_RemoveKey (char *s, const char *key);
|
||||
char *Info_KeyForNumber (char *s, int num);
|
||||
void Info_RemovePrefixedKeys (char *start, char prefix);
|
||||
void Info_RemoveNonStarKeys (char *start);
|
||||
void Info_SetValueForKey (char *s, const char *key, const char *value, int maxsize);
|
||||
void Info_SetValueForStarKey (char *s, const char *key, const char *value, int maxsize);
|
||||
void Info_Print (char *s);
|
||||
void Info_WriteToFile(FILE *f, char *info, char *commandname, int cvarflags);
|
||||
|
||||
unsigned int Com_BlockChecksum (void *buffer, int length);
|
||||
void Com_BlockFullChecksum (void *buffer, int len, unsigned char *outbuf);
|
||||
|
|
|
@ -2158,6 +2158,9 @@ void COM_InitFilesystem (void)
|
|||
if (!COM_CheckParm("-usehome"))
|
||||
*com_homedir = '\0';
|
||||
|
||||
if (COM_CheckParm("-nohome"))
|
||||
*com_homedir = '\0';
|
||||
|
||||
if (*com_homedir)
|
||||
{
|
||||
Con_Printf("Using home directory \"%s\"\n", com_homedir);
|
||||
|
|
|
@ -52,6 +52,9 @@ struct sockaddr_qstorage
|
|||
|
||||
|
||||
extern netadr_t net_local_sv_ipadr;
|
||||
extern netadr_t net_local_sv_ip6adr;
|
||||
extern netadr_t net_local_sv_ipxadr;
|
||||
extern netadr_t net_local_sv_tcpipadr;
|
||||
extern netadr_t net_local_cl_ipadr;
|
||||
extern netadr_t net_from; // address of who sent the packet
|
||||
extern sizebuf_t net_message;
|
||||
|
|
|
@ -21,21 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
struct sockaddr;
|
||||
|
||||
#include "quakedef.h"
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define USEIPX
|
||||
#endif
|
||||
#include "winquake.h"
|
||||
#ifdef USEIPX
|
||||
#include "wsipx.h"
|
||||
#endif
|
||||
#ifdef IPPROTO_IPV6
|
||||
#include "ws2tcpip.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "netinc.h"
|
||||
|
||||
netadr_t net_local_cl_ipadr;
|
||||
|
@ -44,6 +29,7 @@ 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_local_sv_tcpipadr;
|
||||
|
||||
netadr_t net_from;
|
||||
sizebuf_t net_message;
|
||||
|
@ -79,8 +65,11 @@ void (*pfreeaddrinfo) (struct addrinfo*);
|
|||
#endif
|
||||
#endif
|
||||
|
||||
void NET_GetLocalAddress (int socket, netadr_t *out);
|
||||
int TCP_OpenListenSocket (int port);
|
||||
|
||||
extern cvar_t sv_public, sv_listen;
|
||||
extern cvar_t sv_tcpport;
|
||||
|
||||
|
||||
|
||||
|
@ -100,7 +89,7 @@ typedef struct
|
|||
loopback_t loopbacks[2];
|
||||
//=============================================================================
|
||||
|
||||
void NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s)
|
||||
int NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s)
|
||||
{
|
||||
switch(a->type)
|
||||
{
|
||||
|
@ -110,7 +99,7 @@ void NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s)
|
|||
|
||||
*(int *)&((struct sockaddr_in*)s)->sin_addr = INADDR_BROADCAST;
|
||||
((struct sockaddr_in*)s)->sin_port = a->port;
|
||||
break;
|
||||
return sizeof(struct sockaddr_in);
|
||||
|
||||
case NA_IP:
|
||||
memset (s, 0, sizeof(struct sockaddr_in));
|
||||
|
@ -118,7 +107,7 @@ void NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s)
|
|||
|
||||
*(int *)&((struct sockaddr_in*)s)->sin_addr = *(int *)&a->ip;
|
||||
((struct sockaddr_in*)s)->sin_port = a->port;
|
||||
break;
|
||||
return sizeof(struct sockaddr_in);
|
||||
#ifdef IPPROTO_IPV6
|
||||
case NA_BROADCAST_IP6:
|
||||
memset (s, 0, sizeof(struct sockaddr_in));
|
||||
|
@ -129,7 +118,7 @@ void NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s)
|
|||
((struct sockaddr_in6*)s)->sin6_addr.s6_addr[1] = 0x02;
|
||||
((struct sockaddr_in6*)s)->sin6_addr.s6_addr[15] = 0x01;
|
||||
((struct sockaddr_in6*)s)->sin6_port = a->port;
|
||||
break;
|
||||
return sizeof(struct sockaddr_in6);
|
||||
|
||||
case NA_IPV6:
|
||||
memset (s, 0, sizeof(struct sockaddr_in));
|
||||
|
@ -137,7 +126,7 @@ void NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s)
|
|||
|
||||
memcpy(&((struct sockaddr_in6*)s)->sin6_addr, a->ip6, sizeof(struct in6_addr));
|
||||
((struct sockaddr_in6*)s)->sin6_port = a->port;
|
||||
break;
|
||||
return sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
#ifdef USEIPX
|
||||
case NA_IPX:
|
||||
|
@ -145,17 +134,18 @@ void NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s)
|
|||
memcpy(((struct sockaddr_ipx *)s)->sa_netnum, &a->ipx[0], 4);
|
||||
memcpy(((struct sockaddr_ipx *)s)->sa_nodenum, &a->ipx[4], 6);
|
||||
((struct sockaddr_ipx *)s)->sa_socket = a->port;
|
||||
break;
|
||||
return sizeof(struct sockaddr_ipx);
|
||||
case NA_BROADCAST_IPX:
|
||||
memset (s, 0, sizeof(struct sockaddr_ipx));
|
||||
((struct sockaddr_ipx*)s)->sa_family = AF_IPX;
|
||||
memset(&((struct sockaddr_ipx*)s)->sa_netnum, 0, 4);
|
||||
memset(&((struct sockaddr_ipx*)s)->sa_nodenum, 0xff, 6);
|
||||
((struct sockaddr_ipx*)s)->sa_socket = a->port;
|
||||
break;
|
||||
return sizeof(struct sockaddr_ipx);
|
||||
#endif
|
||||
default:
|
||||
Sys_Error("Bad type - needs fixing");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,7 +271,7 @@ char *NET_AdrToString (netadr_t a)
|
|||
#ifdef IPPROTO_IPV6
|
||||
case NA_BROADCAST_IP6:
|
||||
case NA_IPV6:
|
||||
sprintf (s, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%i", a.ip6[0], a.ip6[1], a.ip6[2], a.ip6[3], a.ip6[4], a.ip6[5], a.ip6[6], a.ip6[7], a.ip6[8], a.ip6[9], a.ip6[10], a.ip6[11], a.ip6[12], a.ip6[13], a.ip6[14], a.ip6[15], ntohs(a.port));
|
||||
sprintf (s, "[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]:%i", a.ip6[0], a.ip6[1], a.ip6[2], a.ip6[3], a.ip6[4], a.ip6[5], a.ip6[6], a.ip6[7], a.ip6[8], a.ip6[9], a.ip6[10], a.ip6[11], a.ip6[12], a.ip6[13], a.ip6[14], a.ip6[15], ntohs(a.port));
|
||||
break;
|
||||
#endif
|
||||
#ifdef USEIPX
|
||||
|
@ -395,29 +385,42 @@ qboolean NET_StringToSockaddr (char *s, struct sockaddr_qstorage *sadr)
|
|||
udp6hint.ai_socktype = SOCK_DGRAM;
|
||||
udp6hint.ai_protocol = IPPROTO_UDP;
|
||||
|
||||
port = s + strlen(s);
|
||||
while(port >= s)
|
||||
if (*s == '[')
|
||||
{
|
||||
if (*port == ':')
|
||||
break;
|
||||
port--;
|
||||
}
|
||||
|
||||
if (port == s)
|
||||
port = NULL;
|
||||
if (port)
|
||||
{
|
||||
len = port - s;
|
||||
if (len >= sizeof(dupbase))
|
||||
len = sizeof(dupbase)-1;
|
||||
strncpy(dupbase, s, len);
|
||||
dupbase[len] = '\0';
|
||||
error = pgetaddrinfo(dupbase, port+1, &udp6hint, &addrinfo);
|
||||
port = strstr(s, "]:");
|
||||
if (!port)
|
||||
error = EAI_NONAME;
|
||||
else
|
||||
{
|
||||
error = pgetaddrinfo(s+1. port+2, &udp6hint, &addrinfo);
|
||||
}
|
||||
}
|
||||
else
|
||||
error = EAI_NONAME;
|
||||
if (error) //failed, try string with no port.
|
||||
{
|
||||
port = s + strlen(s);
|
||||
while(port >= s)
|
||||
{
|
||||
if (*port == ':')
|
||||
break;
|
||||
port--;
|
||||
}
|
||||
|
||||
if (port == s)
|
||||
port = NULL;
|
||||
if (port)
|
||||
{
|
||||
len = port - s;
|
||||
if (len >= sizeof(dupbase))
|
||||
len = sizeof(dupbase)-1;
|
||||
strncpy(dupbase, s, len);
|
||||
dupbase[len] = '\0';
|
||||
error = pgetaddrinfo(dupbase, port+1, &udp6hint, &addrinfo);
|
||||
}
|
||||
else
|
||||
error = EAI_NONAME;
|
||||
if (error) //failed, try string with no port.
|
||||
error = pgetaddrinfo(s, NULL, &udp6hint, &addrinfo); //remember, this func will return any address family that could be using the udp protocol... (ip4 or ip6)
|
||||
}
|
||||
if (error)
|
||||
{
|
||||
return false;
|
||||
|
@ -674,11 +677,227 @@ qboolean NET_GetPacket (netsrc_t netsrc)
|
|||
if (net_message.cursize == sizeof(net_message_buffer) )
|
||||
{
|
||||
Con_TPrintf (TL_OVERSIZEPACKETFROM, NET_AdrToString (net_from));
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef TCPCONNECT
|
||||
#ifndef SERVERONLY
|
||||
if (netsrc == NS_CLIENT)
|
||||
{
|
||||
if (cls.sockettcp != INVALID_SOCKET)
|
||||
{//client receiving only via tcp
|
||||
|
||||
ret = recv(cls.sockettcp, cls.tcpinbuffer+cls.tcpinlen, sizeof(cls.tcpinbuffer)-cls.tcpinlen, 0);
|
||||
if (ret == -1)
|
||||
{
|
||||
err = qerrno;
|
||||
|
||||
if (err == EWOULDBLOCK)
|
||||
ret = 0;
|
||||
else
|
||||
{
|
||||
if (err == ECONNABORTED || err == ECONNRESET)
|
||||
{
|
||||
closesocket(cls.sockettcp);
|
||||
cls.sockettcp = INVALID_SOCKET;
|
||||
Con_TPrintf (TL_CONNECTIONLOSTORABORTED); //server died/connection lost.
|
||||
|
||||
if (cls.state != ca_disconnected)
|
||||
{
|
||||
if (cls.lastarbiatarypackettime+5 < Sys_DoubleTime()) //too many mvdsv
|
||||
Cbuf_AddText("disconnect\nreconnect\n", RESTRICT_LOCAL); //retry connecting.
|
||||
else
|
||||
Con_Printf("Packet was not delivered - server might be badly configured\n");
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
closesocket(cls.sockettcp);
|
||||
cls.sockettcp = INVALID_SOCKET;
|
||||
Con_Printf ("NET_GetPacket: Error (%i): %s\n", err, strerror(err));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
cls.tcpinlen += ret;
|
||||
|
||||
if (cls.tcpinlen < 2)
|
||||
return false;
|
||||
|
||||
net_message.cursize = BigShort(*(short*)cls.tcpinbuffer);
|
||||
if (net_message.cursize >= sizeof(net_message_buffer) )
|
||||
{
|
||||
closesocket(cls.sockettcp);
|
||||
cls.sockettcp = INVALID_SOCKET;
|
||||
Con_TPrintf (TL_OVERSIZEPACKETFROM, NET_AdrToString (net_from));
|
||||
return false;
|
||||
}
|
||||
if (net_message.cursize+2 > cls.tcpinlen)
|
||||
{ //not enough buffered to read a packet out of it.
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(net_message_buffer, cls.tcpinbuffer+2, net_message.cursize);
|
||||
memmove(cls.tcpinbuffer, cls.tcpinbuffer+net_message.cursize+2, cls.tcpinlen - (net_message.cursize+2));
|
||||
cls.tcpinlen -= net_message.cursize+2;
|
||||
|
||||
net_message.packing = SZ_RAWBYTES;
|
||||
net_message.currentbit = 0;
|
||||
net_from = cls.sockettcpdest;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef CLIENTONLY
|
||||
if (netsrc == NS_SERVER)
|
||||
{
|
||||
float timeval = Sys_DoubleTime();
|
||||
svtcpstream_t *st;
|
||||
st = svs.tcpstreams;
|
||||
|
||||
while (svs.tcpstreams && svs.tcpstreams->socketnum == INVALID_SOCKET)
|
||||
{
|
||||
st = svs.tcpstreams;
|
||||
svs.tcpstreams = svs.tcpstreams->next;
|
||||
BZ_Free(st);
|
||||
}
|
||||
|
||||
for (st = svs.tcpstreams; st; st = st->next)
|
||||
{//client receiving only via tcp
|
||||
|
||||
while (st->next && st->next->socketnum == INVALID_SOCKET)
|
||||
{
|
||||
svtcpstream_t *temp;
|
||||
temp = st->next;
|
||||
st->next = st->next->next;
|
||||
BZ_Free(temp);
|
||||
}
|
||||
|
||||
//due to the above checks about invalid sockets, the socket is always open for st below.
|
||||
|
||||
if (st->timeouttime < timeval)
|
||||
goto closesvstream;
|
||||
|
||||
ret = recv(st->socketnum, st->inbuffer+st->inlen, sizeof(st->inbuffer)-st->inlen, 0);
|
||||
if (ret == 0)
|
||||
goto closesvstream;
|
||||
else if (ret == -1)
|
||||
{
|
||||
err = qerrno;
|
||||
|
||||
if (err == EWOULDBLOCK)
|
||||
ret = 0;
|
||||
else
|
||||
{
|
||||
if (err == ECONNABORTED || err == ECONNRESET)
|
||||
{
|
||||
Con_TPrintf (TL_CONNECTIONLOSTORABORTED); //server died/connection lost.
|
||||
}
|
||||
else
|
||||
Con_Printf ("NET_GetPacket: Error (%i): %s\n", err, strerror(err));
|
||||
|
||||
closesvstream:
|
||||
closesocket(st->socketnum);
|
||||
st->socketnum = INVALID_SOCKET;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
st->inlen += ret;
|
||||
|
||||
if (st->waitingforprotocolconfirmation)
|
||||
{
|
||||
if (st->inlen < 6)
|
||||
continue;
|
||||
|
||||
if (strncmp(st->inbuffer, "qizmo\n", 6))
|
||||
{
|
||||
Con_Printf ("Unknown TCP client\n");
|
||||
goto closesvstream;
|
||||
}
|
||||
|
||||
memmove(st->inbuffer, st->inbuffer+6, st->inlen - (6));
|
||||
st->inlen -= 6;
|
||||
st->waitingforprotocolconfirmation = false;
|
||||
}
|
||||
|
||||
if (st->inlen < 2)
|
||||
continue;
|
||||
|
||||
net_message.cursize = BigShort(*(short*)st->inbuffer);
|
||||
if (net_message.cursize >= sizeof(net_message_buffer) )
|
||||
{
|
||||
Con_TPrintf (TL_OVERSIZEPACKETFROM, NET_AdrToString (net_from));
|
||||
goto closesvstream;
|
||||
}
|
||||
if (net_message.cursize+2 > st->inlen)
|
||||
{ //not enough buffered to read a packet out of it.
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(net_message_buffer, st->inbuffer+2, net_message.cursize);
|
||||
memmove(st->inbuffer, st->inbuffer+net_message.cursize+2, st->inlen - (net_message.cursize+2));
|
||||
st->inlen -= net_message.cursize+2;
|
||||
|
||||
net_message.packing = SZ_RAWBYTES;
|
||||
net_message.currentbit = 0;
|
||||
net_from = st->remoteaddr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#ifdef TCPCONNECT
|
||||
if (sv_tcpport.modified)
|
||||
{
|
||||
if (svs.sockettcp == INVALID_SOCKET && sv_tcpport.value)
|
||||
{
|
||||
svs.sockettcp = TCP_OpenListenSocket(sv_tcpport.value);
|
||||
if (svs.sockettcp != INVALID_SOCKET)
|
||||
NET_GetLocalAddress (svs.sockettcp, &net_local_sv_tcpipadr);
|
||||
else
|
||||
Con_Printf("Failed to open TCP port %i\n", (int)sv_tcpport.value);
|
||||
}
|
||||
else
|
||||
{
|
||||
UDP_CloseSocket(svs.sockettcp);
|
||||
svs.sockettcp = INVALID_SOCKET;
|
||||
}
|
||||
sv_tcpport.modified = false;
|
||||
}
|
||||
#endif
|
||||
if (svs.sockettcp != INVALID_SOCKET)
|
||||
{
|
||||
int newsock;
|
||||
newsock = accept(svs.sockettcp, (struct sockaddr*)&from, &fromlen);
|
||||
if (newsock != INVALID_SOCKET)
|
||||
{
|
||||
int _true = true;
|
||||
setsockopt(newsock, IPPROTO_TCP, TCP_NODELAY, (char *)&_true, sizeof(_true));
|
||||
|
||||
|
||||
|
||||
st = Z_Malloc(sizeof(svtcpstream_t));
|
||||
st->waitingforprotocolconfirmation = true;
|
||||
st->next = svs.tcpstreams;
|
||||
svs.tcpstreams = st;
|
||||
st->socketnum = newsock;
|
||||
st->inlen = 0;
|
||||
SockadrToNetadr(&from, &st->remoteaddr);
|
||||
send(newsock, "qizmo\n", 6, 0);
|
||||
|
||||
st->timeouttime = timeval + 30;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -706,6 +925,28 @@ void NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t to)
|
|||
Sys_Error("NET_SendPacket: bad netsrc");
|
||||
socket = 0;
|
||||
#else
|
||||
|
||||
#ifdef TCPCONNECT
|
||||
svtcpstream_t *st;
|
||||
for (st = svs.tcpstreams; st; st = st->next)
|
||||
{
|
||||
if (st->socketnum == INVALID_SOCKET)
|
||||
continue;
|
||||
|
||||
if (NET_CompareAdr(to, st->remoteaddr))
|
||||
{
|
||||
unsigned short slen = BigShort((unsigned short)length);
|
||||
send(st->socketnum, (char*)&slen, sizeof(slen), 0);
|
||||
send(st->socketnum, data, length, 0);
|
||||
|
||||
st->timeouttime = Sys_DoubleTime() + 20;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USEIPX
|
||||
if (to.type == NA_BROADCAST_IPX || to.type == NA_IPX)
|
||||
socket = svs.socketipx;
|
||||
|
@ -725,6 +966,24 @@ void NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t to)
|
|||
Sys_Error("NET_SendPacket: bad netsrc");
|
||||
socket = 0;
|
||||
#else
|
||||
|
||||
#ifdef TCPCONNECT
|
||||
if (cls.sockettcp != -1)
|
||||
{
|
||||
if (NET_CompareAdr(to, cls.sockettcpdest))
|
||||
{ //this goes to the server
|
||||
//so send it via tcp
|
||||
unsigned short slen = BigShort((unsigned short)length);
|
||||
send(cls.sockettcp, (char*)&slen, sizeof(slen), 0);
|
||||
send(cls.sockettcp, data, length, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef USEIPX
|
||||
if (to.type == NA_BROADCAST_IPX || to.type == NA_IPX)
|
||||
socket = cls.socketipx;
|
||||
|
@ -785,6 +1044,93 @@ void NET_SendPacket (netsrc_t netsrc, int length, void *data, netadr_t to)
|
|||
|
||||
//=============================================================================
|
||||
|
||||
int TCP_OpenStream (netadr_t remoteaddr)
|
||||
{
|
||||
unsigned long _true = true;
|
||||
int newsocket;
|
||||
int temp;
|
||||
struct sockaddr_qstorage qs;
|
||||
|
||||
temp = NetadrToSockadr(&remoteaddr, &qs);
|
||||
|
||||
if ((newsocket = socket (((struct sockaddr_in*)&qs)->sin_family, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
|
||||
return INVALID_SOCKET;
|
||||
|
||||
if (connect(newsocket, (struct sockaddr *)&qs, temp) == INVALID_SOCKET)
|
||||
{
|
||||
closesocket(newsocket);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
|
||||
Sys_Error ("UDP_OpenSocket: ioctl FIONBIO: %s", strerror(qerrno));
|
||||
|
||||
|
||||
return newsocket;
|
||||
}
|
||||
|
||||
int TCP_OpenListenSocket (int port)
|
||||
{
|
||||
int newsocket;
|
||||
struct sockaddr_in address;
|
||||
unsigned long _true = true;
|
||||
int i;
|
||||
int maxport = port + 100;
|
||||
|
||||
if ((newsocket = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
|
||||
return INVALID_SOCKET;
|
||||
|
||||
if (ioctlsocket (newsocket, FIONBIO, &_true) == -1)
|
||||
Sys_Error ("TCP_OpenListenSocket: ioctl FIONBIO: %s", strerror(qerrno));
|
||||
|
||||
address.sin_family = AF_INET;
|
||||
//ZOID -- check for interface binding option
|
||||
if ((i = COM_CheckParm("-ip")) != 0 && i < com_argc) {
|
||||
address.sin_addr.s_addr = inet_addr(com_argv[i+1]);
|
||||
Con_TPrintf(TL_NETBINDINTERFACE,
|
||||
inet_ntoa(address.sin_addr));
|
||||
} else
|
||||
address.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if (port == PORT_ANY)
|
||||
address.sin_port = 0;
|
||||
else
|
||||
address.sin_port = htons((short)port);
|
||||
|
||||
if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
|
||||
{
|
||||
if (!port)
|
||||
{
|
||||
Con_Printf("Cannot bind tcp socket\n");
|
||||
closesocket(newsocket);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
port++;
|
||||
if (port > maxport)
|
||||
{
|
||||
Con_Printf("Cannot bind tcp socket\n");
|
||||
closesocket(newsocket);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (listen(newsocket, 1) == INVALID_SOCKET)
|
||||
{
|
||||
Con_Printf("Cannot listen on tcp socket\n");
|
||||
closesocket(newsocket);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
return newsocket;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int UDP_OpenSocket (int port, qboolean bcast)
|
||||
{
|
||||
int newsocket;
|
||||
|
@ -1090,12 +1436,18 @@ void NET_Init (void)
|
|||
cls.socketip = INVALID_SOCKET;
|
||||
cls.socketip6 = INVALID_SOCKET;
|
||||
cls.socketipx = INVALID_SOCKET;
|
||||
#ifdef TCPCONNECT
|
||||
cls.sockettcp = INVALID_SOCKET;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CLIENTONLY
|
||||
svs.socketip = INVALID_SOCKET;
|
||||
svs.socketip6 = INVALID_SOCKET;
|
||||
svs.socketipx = INVALID_SOCKET;
|
||||
#ifdef TCPCONNECT
|
||||
svs.sockettcp = INVALID_SOCKET;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#ifndef SERVERONLY
|
||||
|
@ -1104,11 +1456,18 @@ void NET_InitClient(void)
|
|||
int port;
|
||||
int p;
|
||||
port = PORT_CLIENT;
|
||||
|
||||
p = COM_CheckParm ("-port");
|
||||
if (p && p < com_argc)
|
||||
{
|
||||
port = atoi(com_argv[p+1]);
|
||||
}
|
||||
p = COM_CheckParm ("-clport");
|
||||
if (p && p < com_argc)
|
||||
{
|
||||
port = atoi(com_argv[p+1]);
|
||||
}
|
||||
|
||||
//
|
||||
// open the single socket to be used for all communications
|
||||
//
|
||||
|
@ -1157,6 +1516,14 @@ void NET_CloseServer(void)
|
|||
svs.socketipx = INVALID_SOCKET;
|
||||
}
|
||||
#endif
|
||||
#ifdef TCPCONNECT
|
||||
if (svs.sockettcp != INVALID_SOCKET)
|
||||
{
|
||||
UDP_CloseSocket(svs.sockettcp );
|
||||
svs.sockettcp = INVALID_SOCKET;
|
||||
sv_tcpport.modified = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
net_local_sv_ipadr.type = NA_LOOPBACK;
|
||||
net_local_sv_ip6adr.type = NA_LOOPBACK;
|
||||
|
@ -1171,13 +1538,12 @@ void NET_InitServer(void)
|
|||
|
||||
if (sv_listen.value)
|
||||
{
|
||||
p = COM_CheckParm ("-svport");
|
||||
p = COM_CheckParm ("-port");
|
||||
if (p && p < com_argc)
|
||||
{
|
||||
port = atoi(com_argv[p+1]);
|
||||
}
|
||||
|
||||
p = COM_CheckParm ("-port");
|
||||
p = COM_CheckParm ("-svport");
|
||||
if (p && p < com_argc)
|
||||
{
|
||||
port = atoi(com_argv[p+1]);
|
||||
|
|
|
@ -1,58 +1,65 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#define EMSGSIZE WSAEMSGSIZE
|
||||
#define ECONNRESET WSAECONNRESET
|
||||
#define ECONNABORTED WSAECONNABORTED
|
||||
#define ECONNREFUSED WSAECONNREFUSED
|
||||
#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
|
||||
#define EAFNOSUPPORT WSAEAFNOSUPPORT
|
||||
#define EWOULDBLOCK WSAEWOULDBLOCK
|
||||
#define EMSGSIZE WSAEMSGSIZE
|
||||
#define ECONNRESET WSAECONNRESET
|
||||
#define ECONNABORTED WSAECONNABORTED
|
||||
#define ECONNREFUSED WSAECONNREFUSED
|
||||
#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
|
||||
#define EAFNOSUPPORT WSAEAFNOSUPPORT
|
||||
|
||||
#ifdef IPPROTO_IPV6
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#define USEIPX
|
||||
#endif
|
||||
#include "winquake.h"
|
||||
#ifdef USEIPX
|
||||
#include "wsipx.h"
|
||||
#endif
|
||||
#ifdef IPPROTO_IPV6
|
||||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
#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 <sys/uio.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef sun
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
#ifdef sun
|
||||
#include <sys/filio.h>
|
||||
#endif
|
||||
|
||||
#ifdef NeXT
|
||||
#include <libc.h>
|
||||
#endif
|
||||
#ifdef NeXT
|
||||
#include <libc.h>
|
||||
#endif
|
||||
|
||||
#if defined(__MORPHOS__) && !defined(ixemul)
|
||||
#define closesocket CloseSocket
|
||||
#define ioctlsocket IoctlSocket
|
||||
#else
|
||||
#define closesocket close
|
||||
#define ioctlsocket ioctl
|
||||
#endif
|
||||
#if defined(__MORPHOS__) && !defined(ixemul)
|
||||
#define closesocket CloseSocket
|
||||
#define ioctlsocket IoctlSocket
|
||||
#else
|
||||
#define closesocket close
|
||||
#define ioctlsocket ioctl
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define qerrno WSAGetLastError()
|
||||
#define qerrno WSAGetLastError()
|
||||
#elif defined(__MORPHOS__) && !defined(ixemul)
|
||||
#define qerrno Errno()
|
||||
#define qerrno Errno()
|
||||
#else
|
||||
#define qerrno errno
|
||||
#define qerrno errno
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef INVALID_SOCKET
|
||||
#define INVALID_SOCKET -1
|
||||
#define INVALID_SOCKET -1
|
||||
#endif
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ static plugin_t *protocolclientplugin;
|
|||
typedef struct {
|
||||
char *name;
|
||||
Plug_Builtin_t func;
|
||||
int flags;
|
||||
} Plug_Plugins_t;
|
||||
Plug_Plugins_t *plugbuiltins;
|
||||
int numplugbuiltins;
|
||||
|
@ -79,6 +80,7 @@ void Plug_RegisterBuiltin(char *name, Plug_Builtin_t bi, int flags)
|
|||
//got an empty number.
|
||||
plugbuiltins[newnum].name = name;
|
||||
plugbuiltins[newnum].func = bi;
|
||||
plugbuiltins[newnum].flags = flags;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -111,7 +113,13 @@ int VARGS Plug_FindBuiltin(void *offset, unsigned int mask, const long *args)
|
|||
for (i = 0; i < numplugbuiltins; i++)
|
||||
if (plugbuiltins[i].name)
|
||||
if (!strcmp(plugbuiltins[i].name, (char *)VM_POINTER(args[0])))
|
||||
{
|
||||
if (offset && plugbuiltins[i].flags & PLUG_BIF_DLLONLY)
|
||||
return 0; //block it, if not native
|
||||
if (!offset && plugbuiltins[i].flags & PLUG_BIF_QVMONLY)
|
||||
return 0; //block it, if not native
|
||||
return -i;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -258,6 +266,22 @@ int VARGS Plug_ExportToEngine(void *offset, unsigned int mask, const long *arg)
|
|||
return 1;
|
||||
}
|
||||
|
||||
typedef void (*funcptr_t) ();
|
||||
int VARGS Plug_ExportNative(void *offset, unsigned int mask, const long *arg)
|
||||
{
|
||||
funcptr_t func;
|
||||
char *name = (char*)VM_POINTER(arg[0]);
|
||||
arg++;
|
||||
|
||||
func = *(funcptr_t*)arg;
|
||||
|
||||
if (!strcmp(name, "S_LoadSound"))
|
||||
S_RegisterSoundInputPlugin(func);
|
||||
else
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
//Make SURE that the engine has resolved all cvar pointers into globals before this happens.
|
||||
plugin_t *plugin;
|
||||
|
@ -804,6 +828,7 @@ int VARGS Plug_Con_RenameSub(void *offset, unsigned int mask, const long *arg)
|
|||
typedef enum{
|
||||
STREAM_NONE,
|
||||
STREAM_SOCKET,
|
||||
STREAM_OSFILE,
|
||||
STREAM_FILE
|
||||
} plugstream_e;
|
||||
|
||||
|
@ -811,7 +836,13 @@ typedef struct {
|
|||
plugin_t *plugin;
|
||||
plugstream_e type;
|
||||
int socket;
|
||||
FILE *handle;
|
||||
struct {
|
||||
char filename[MAX_QPATH];
|
||||
qbyte *buffer;
|
||||
int buflen;
|
||||
int curlen;
|
||||
int curpos;
|
||||
} file;
|
||||
} pluginstream_t;
|
||||
pluginstream_t *pluginstreamarray;
|
||||
int pluginstreamarraylen;
|
||||
|
@ -834,6 +865,8 @@ int Plug_NewStreamHandle(plugstream_e type)
|
|||
pluginstreamarray[i].plugin = currentplug;
|
||||
pluginstreamarray[i].type = type;
|
||||
pluginstreamarray[i].socket = -1;
|
||||
pluginstreamarray[i].file.buffer = NULL;
|
||||
*pluginstreamarray[i].file.filename = '\0';
|
||||
|
||||
return i;
|
||||
}
|
||||
|
@ -991,6 +1024,62 @@ int VARGS Plug_Net_TCPConnect(void *offset, unsigned int mask, const long *arg)
|
|||
|
||||
return handle;
|
||||
}
|
||||
int VARGS Plug_FS_Open(void *offset, unsigned int mask, const long *arg)
|
||||
{
|
||||
//modes:
|
||||
//1: read
|
||||
//2: write
|
||||
|
||||
//char *name, int *handle, int mode
|
||||
|
||||
//return value is length of the file.
|
||||
|
||||
int handle;
|
||||
int *ret;
|
||||
char *data;
|
||||
|
||||
if (VM_OOB(arg[1], sizeof(int)))
|
||||
return -2;
|
||||
ret = VM_POINTER(arg[1]);
|
||||
|
||||
if (arg[2] == 1)
|
||||
{
|
||||
data = COM_LoadMallocFile(VM_POINTER(arg[0]));
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
handle = Plug_NewStreamHandle(STREAM_FILE);
|
||||
pluginstreamarray[handle].file.buffer = data;
|
||||
pluginstreamarray[handle].file.curpos = 0;
|
||||
pluginstreamarray[handle].file.curlen = com_filesize;
|
||||
pluginstreamarray[handle].file.buflen = com_filesize;
|
||||
|
||||
*ret = handle;
|
||||
|
||||
return com_filesize;
|
||||
}
|
||||
else if (arg[2] == 2)
|
||||
{
|
||||
data = BZ_Malloc(8192);
|
||||
if (!data)
|
||||
return -1;
|
||||
|
||||
handle = Plug_NewStreamHandle(STREAM_FILE);
|
||||
Q_strncpyz(pluginstreamarray[handle].file.filename, VM_POINTER(arg[0]), MAX_QPATH);
|
||||
pluginstreamarray[handle].file.buffer = data;
|
||||
pluginstreamarray[handle].file.curpos = 0;
|
||||
pluginstreamarray[handle].file.curlen = 0;
|
||||
pluginstreamarray[handle].file.buflen = 8192;
|
||||
|
||||
*ret = handle;
|
||||
|
||||
return com_filesize;
|
||||
}
|
||||
else
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
int VARGS Plug_Net_Recv(void *offset, unsigned int mask, const long *arg)
|
||||
{
|
||||
int read;
|
||||
|
@ -1017,6 +1106,16 @@ int VARGS Plug_Net_Recv(void *offset, unsigned int mask, const long *arg)
|
|||
else if (read == 0)
|
||||
return -2; //closed by remote connection.
|
||||
return read;
|
||||
case STREAM_FILE:
|
||||
if (pluginstreamarray[handle].file.curlen - pluginstreamarray[handle].file.curpos < destlen)
|
||||
{
|
||||
destlen = pluginstreamarray[handle].file.curlen - pluginstreamarray[handle].file.curpos;
|
||||
if (destlen < 0)
|
||||
return -2;
|
||||
}
|
||||
memcpy(dest, pluginstreamarray[handle].file.buffer + pluginstreamarray[handle].file.curpos, destlen);
|
||||
pluginstreamarray[handle].file.curpos += destlen;
|
||||
return destlen;
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
@ -1043,6 +1142,19 @@ int VARGS Plug_Net_Send(void *offset, unsigned int mask, const long *arg)
|
|||
else if (written == 0)
|
||||
return -2; //closed by remote connection.
|
||||
return written;
|
||||
case STREAM_FILE:
|
||||
if (pluginstreamarray[handle].file.buflen < pluginstreamarray[handle].file.curpos + srclen)
|
||||
{
|
||||
pluginstreamarray[handle].file.buflen = pluginstreamarray[handle].file.curpos + srclen+8192;
|
||||
pluginstreamarray[handle].file.buffer =
|
||||
BZ_Realloc(pluginstreamarray[handle].file.buffer, pluginstreamarray[handle].file.buflen);
|
||||
}
|
||||
memcpy(pluginstreamarray[handle].file.buffer + pluginstreamarray[handle].file.curpos, src, srclen);
|
||||
pluginstreamarray[handle].file.curpos += srclen;
|
||||
if (pluginstreamarray[handle].file.curpos > pluginstreamarray[handle].file.curlen)
|
||||
pluginstreamarray[handle].file.curlen = pluginstreamarray[handle].file.curpos;
|
||||
return -2;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
}
|
||||
|
@ -1089,10 +1201,20 @@ int VARGS Plug_Net_SendTo(void *offset, unsigned int mask, const long *arg)
|
|||
int VARGS Plug_Net_Close(void *offset, unsigned int mask, const long *arg)
|
||||
{
|
||||
int handle = VM_LONG(arg[0]);
|
||||
if (handle < 0 || handle >= pluginstreamarraylen || pluginstreamarray[handle].plugin != currentplug || pluginstreamarray[handle].type != STREAM_SOCKET)
|
||||
if (handle < 0 || handle >= pluginstreamarraylen || pluginstreamarray[handle].plugin != currentplug)
|
||||
return -2;
|
||||
|
||||
closesocket(pluginstreamarray[handle].socket);
|
||||
switch(pluginstreamarray[handle].type)
|
||||
{
|
||||
case STREAM_SOCKET:
|
||||
closesocket(pluginstreamarray[handle].socket);
|
||||
break;
|
||||
case STREAM_FILE:
|
||||
if (*pluginstreamarray[handle].file.filename)
|
||||
COM_WriteFile(pluginstreamarray[handle].file.filename, pluginstreamarray[handle].file.buffer, pluginstreamarray[handle].file.curlen);
|
||||
BZ_Free(pluginstreamarray[handle].file.buffer);
|
||||
break;
|
||||
}
|
||||
|
||||
pluginstreamarray[handle].plugin = NULL;
|
||||
|
||||
|
@ -1161,6 +1283,7 @@ void Plug_Init(void)
|
|||
|
||||
Plug_RegisterBuiltin("Plug_GetEngineFunction", Plug_FindBuiltin, 0);//plugin wishes to find a builtin number.
|
||||
Plug_RegisterBuiltin("Plug_ExportToEngine", Plug_ExportToEngine, 0); //plugin has a call back that we might be interested in.
|
||||
Plug_RegisterBuiltin("Plug_ExportNative", Plug_ExportNative, PLUG_BIF_DLLONLY);
|
||||
Plug_RegisterBuiltin("Con_Print", Plug_Con_Print, 0); //printf is not possible - qvm floats are never doubles, vararg floats in a cdecl call are always converted to doubles.
|
||||
Plug_RegisterBuiltin("Sys_Error", Plug_Sys_Error, 0);
|
||||
Plug_RegisterBuiltin("Sys_Milliseconds", Plug_Sys_Milliseconds, 0);
|
||||
|
@ -1203,6 +1326,12 @@ void Plug_Init(void)
|
|||
Plug_RegisterBuiltin("Net_SendTo", Plug_Net_SendTo, 0);
|
||||
Plug_RegisterBuiltin("Net_Close", Plug_Net_Close, 0);
|
||||
|
||||
Plug_RegisterBuiltin("FS_Open", Plug_FS_Open, 0);
|
||||
Plug_RegisterBuiltin("FS_Read", Plug_Net_Recv, 0);
|
||||
Plug_RegisterBuiltin("FS_Write", Plug_Net_Send, 0);
|
||||
Plug_RegisterBuiltin("FS_Close", Plug_Net_Close, 0);
|
||||
|
||||
|
||||
Plug_RegisterBuiltin("Media_ShowFrameRGBA_32", Plug_Media_ShowFrameRGBA_32, 0);
|
||||
|
||||
if (plug_loaddefault.value)
|
||||
|
|
|
@ -637,6 +637,7 @@ void PM_AirMove (void)
|
|||
else
|
||||
{ // not on ground, so little effect on velocity
|
||||
PM_AirAccelerate (wishdir, wishspeed, movevars.accelerate);
|
||||
// PM_Accelerate (wishdir, wishspeed, movevars.airaccelerate);
|
||||
|
||||
// add gravity
|
||||
pmove.velocity[2] -= movevars.entgravity * movevars.gravity * frametime;
|
||||
|
|
|
@ -27,9 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define PEXT_VIEW2 0x00000010
|
||||
#endif
|
||||
#define PEXT_BULLETENS 0x00000020
|
||||
#ifdef AVAIL_ZLIB
|
||||
// #define PEXT_ZLIBDL 0x00000040
|
||||
#endif
|
||||
#define PEXT_ACCURATETIMINGS 0x00000040
|
||||
//#define PEXT_LIGHTUPDATES 0x00000080 //send progs/zap.mdl in the same mannor as a nail.
|
||||
#define PEXT_FATNESS 0x00000100 //GL only (or servers)
|
||||
#define PEXT_HLBSP 0x00000200
|
||||
|
|
|
@ -102,6 +102,7 @@ void *Sys_LoadDLL(const char *name, void **vmMain, sys_calldll_t syscall)
|
|||
dllEntry=(void *)GetProcAddress(hVM, "dllEntry");
|
||||
if(!dllEntry)
|
||||
{
|
||||
Con_Printf ("Sys_LoadDLL: %s lacks a dllEntry function\n",name);
|
||||
FreeLibrary(hVM);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -111,6 +112,7 @@ void *Sys_LoadDLL(const char *name, void **vmMain, sys_calldll_t syscall)
|
|||
*vmMain=(void *)GetProcAddress(hVM, "vmMain");
|
||||
if(!*vmMain)
|
||||
{
|
||||
Con_Printf ("Sys_LoadDLL: %s lacks a vmMain function\n",name);
|
||||
FreeLibrary(hVM);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ LINK32=link.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /G5 /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /D "Q3CLIENT" /D "Q3SERVER" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c
|
||||
# ADD CPP /nologo /G5 /W3 /GX /ZI /Od /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "_DEBUG" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /Yu"quakedef.h" /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c
|
||||
# SUBTRACT CPP /X
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
|
@ -136,7 +136,7 @@ LINK32=link.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /I "..\client" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /G6 /Gr /W3 /GX /O2 /Ob2 /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "NDEBUG" /D "_MBCS" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /D "Q3CLIENT" /D "Q3SERVER" /FR /Yu"quakedef.h" /FD /c
|
||||
# ADD CPP /nologo /G6 /Gr /W3 /GX /O2 /Ob2 /I "..\client" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /I "../libs/dxsdk7/include" /D "NDEBUG" /D "_MBCS" /D "GLQUAKE" /D "WIN32" /D "_WINDOWS" /FR /Yu"quakedef.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "NDEBUG"
|
||||
|
@ -164,7 +164,7 @@ LINK32=link.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /G5 /ML /W3 /GX /ZI /Od /I "..\client\gltod3d\sdk7\include" /I "..\client\gltod3d\D3DFrame" /I "..\dxsdk\sdk\inc" /I "..\scitech\include" /I "..\client" /D "NQPROT" /D "_DEBUG" /D "GLQUAKE" /D "SERVERDLL" /D "WIN32" /D "_WINDOWS" /FR".\GLDebug/" /Fp".\GLDebug/qwcl.pch" /YX /Fo".\GLDebug/" /Fd".\GLDebug/" /FD /c
|
||||
# ADD CPP /nologo /G5 /W3 /Gi /GX /ZI /Od /I "..\client" /I "../libs/dxsdk7/include" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /D "SWQUAKE" /D "USE_D3D" /D "Q3SERVER" /D "Q3CLIENT" /Fr /Fp".\MDebug/qwcl.pch" /Yu"quakedef.h" /FD /c
|
||||
# ADD CPP /nologo /G5 /W3 /Gi /GX /ZI /Od /I "..\client" /I "../libs/dxsdk7/include" /I "../common" /I "../server" /I "../gl" /I "../sw" /I "../qclib" /I "../libs" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "GLQUAKE" /D "SWQUAKE" /D "USE_D3D" /Fr /Fp".\MDebug/qwcl.pch" /Yu"quakedef.h" /FD /c
|
||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||
# ADD BASE RSC /l 0x809 /d "_DEBUG"
|
||||
|
@ -286,7 +286,8 @@ BSC32=bscmake.exe
|
|||
LINK32=link.exe
|
||||
# ADD BASE LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:windows /pdb:".\GLDebug/dglqwcl.pdb" /debug /machine:I386 /out:"../../../fteminglqw.exe"
|
||||
# SUBTRACT BASE LINK32 /pdb:none
|
||||
# ADD LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /out:"../../fteqwsv.exe" /libpath:"../libs/dxsdk7/lib"
|
||||
# ADD LINK32 comctl32.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../fteqwsv.exe" /libpath:"../libs/dxsdk7/lib"
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "ftequake - Win32 Release Dedicated Server"
|
||||
|
||||
|
@ -539,8 +540,6 @@ SOURCE=..\server\svq3_game.c
|
|||
|
||||
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
|
||||
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
|
||||
|
||||
# PROP Exclude_From_Build 1
|
||||
|
@ -681,8 +680,6 @@ SOURCE=..\client\cl_cg.c
|
|||
|
||||
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
|
||||
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
|
||||
|
||||
# PROP Exclude_From_Build 1
|
||||
|
@ -798,6 +795,10 @@ SOURCE=..\client\cl_ents.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\client\cl_ignore.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\client\cl_input.c
|
||||
|
||||
!IF "$(CFG)" == "ftequake - Win32 Release"
|
||||
|
@ -1189,8 +1190,6 @@ SOURCE=..\client\clq3_parse.c
|
|||
|
||||
!ELSEIF "$(CFG)" == "ftequake - Win32 MRelease"
|
||||
|
||||
# PROP Exclude_From_Build 1
|
||||
|
||||
!ELSEIF "$(CFG)" == "ftequake - Win32 MinGLDebug"
|
||||
|
||||
# PROP Exclude_From_Build 1
|
||||
|
|
|
@ -860,6 +860,7 @@ static qboolean R_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int frame1, i
|
|||
if (g1 == g2) //lerping within group is only done if not changing group
|
||||
{
|
||||
lerp = fg1time*g1->rate;
|
||||
if (lerp < 0) lerp = 0; //hrm
|
||||
frame1=lerp;
|
||||
frame2=frame1+1;
|
||||
lerp-=frame1;
|
||||
|
@ -4077,10 +4078,10 @@ void GL_LoadQ3Model(model_t *mod, void *buffer)
|
|||
#ifndef SERVERONLY
|
||||
if (LittleLong(surf->numShaders)+externalskins)
|
||||
{
|
||||
#if 1//ndef Q3SHADERS
|
||||
#ifndef Q3SHADERS
|
||||
char name[1024];
|
||||
extern int gl_bumpmappingpossible;
|
||||
#endif
|
||||
extern int gl_bumpmappingpossible;
|
||||
char shadname[1024];
|
||||
|
||||
skin = Hunk_Alloc((LittleLong(surf->numShaders)+externalskins)*((sizeof(galiasskin_t)+sizeof(galiastexnum_t))));
|
||||
|
@ -4971,8 +4972,8 @@ galiasinfo_t *GLMod_ParseMD5MeshModel(char *buffer)
|
|||
int meshnum = 0;
|
||||
int i;
|
||||
|
||||
galiasbone_t *bones;
|
||||
galiasgroup_t *pose;
|
||||
galiasbone_t *bones = NULL;
|
||||
galiasgroup_t *pose = NULL;
|
||||
galiasinfo_t *inf, *root, *lastsurf;
|
||||
float *posedata;
|
||||
#ifndef SERVERONLY
|
||||
|
@ -5092,9 +5093,9 @@ galiasinfo_t *GLMod_ParseMD5MeshModel(char *buffer)
|
|||
|
||||
galisskeletaltransforms_t *trans;
|
||||
#ifndef SERVERONLY
|
||||
float *stcoord;
|
||||
float *stcoord = NULL;
|
||||
#endif
|
||||
int *indexes;
|
||||
int *indexes = NULL;
|
||||
float w;
|
||||
|
||||
vec4_t *rawweight = NULL;
|
||||
|
@ -5103,7 +5104,7 @@ galiasinfo_t *GLMod_ParseMD5MeshModel(char *buffer)
|
|||
|
||||
if (!nummeshes)
|
||||
Sys_Error("MD5MESH: mesh section before (or without) nummeshes");
|
||||
if (!foundjoints)
|
||||
if (!foundjoints || !bones || !pose)
|
||||
Sys_Error("MD5MESH: mesh must come after joints");
|
||||
|
||||
if (!lastsurf)
|
||||
|
@ -5169,7 +5170,7 @@ galiasinfo_t *GLMod_ParseMD5MeshModel(char *buffer)
|
|||
|
||||
buffer = COM_Parse(buffer);
|
||||
num = atoi(com_token);
|
||||
if (num < 0 || num >= numverts)
|
||||
if (num < 0 || num >= numverts || !stcoord || !indexes)
|
||||
Sys_Error("MD5MESH: vertex out of range");
|
||||
|
||||
EXPECT("(");
|
||||
|
|
|
@ -58,6 +58,7 @@ extern cvar_t gl_picmip2d;
|
|||
extern cvar_t r_drawdisk;
|
||||
extern cvar_t gl_compress;
|
||||
extern cvar_t gl_font, gl_conback, gl_smoothfont, gl_fontedgeclamp;
|
||||
extern cvar_t gl_texturemode;
|
||||
extern cvar_t cl_noblink;
|
||||
|
||||
extern cvar_t gl_savecompressedtex;
|
||||
|
@ -560,16 +561,17 @@ void GLDraw_CharToConback (int num, qbyte *dest)
|
|||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
char *altname;
|
||||
int minimize, maximize;
|
||||
} glmode_t;
|
||||
|
||||
glmode_t modes[] = {
|
||||
{"GL_NEAREST", GL_NEAREST, GL_NEAREST},
|
||||
{"GL_LINEAR", GL_LINEAR, GL_LINEAR},
|
||||
{"GL_NEAREST_MIPMAP_NEAREST", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
|
||||
{"GL_LINEAR_MIPMAP_NEAREST", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR},
|
||||
{"GL_NEAREST_MIPMAP_LINEAR", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST},
|
||||
{"GL_LINEAR_MIPMAP_LINEAR", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
|
||||
{"GL_NEAREST", "n", GL_NEAREST, GL_NEAREST},
|
||||
{"GL_LINEAR", "l", GL_LINEAR, GL_LINEAR},
|
||||
{"GL_NEAREST_MIPMAP_NEAREST", "nn", GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST},
|
||||
{"GL_LINEAR_MIPMAP_NEAREST", "ln", GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR},
|
||||
{"GL_NEAREST_MIPMAP_LINEAR", "nl", GL_NEAREST_MIPMAP_LINEAR, GL_NEAREST},
|
||||
{"GL_LINEAR_MIPMAP_LINEAR", "ll", GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR}
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -577,31 +579,23 @@ glmode_t modes[] = {
|
|||
Draw_TextureMode_f
|
||||
===============
|
||||
*/
|
||||
void GLDraw_TextureMode_f (void)
|
||||
void GLDraw_TextureMode_Changed (void)
|
||||
{
|
||||
int i;
|
||||
gltexture_t *glt;
|
||||
|
||||
if (Cmd_Argc() == 1)
|
||||
{
|
||||
for (i=0 ; i< 6 ; i++)
|
||||
if (gl_filter_min == modes[i].minimize)
|
||||
{
|
||||
Con_Printf ("%s\n", modes[i].name);
|
||||
return;
|
||||
}
|
||||
Con_Printf ("current filter is unknown???\n");
|
||||
return;
|
||||
}
|
||||
gl_texturemode.modified = false;
|
||||
|
||||
for (i=0 ; i< 6 ; i++)
|
||||
for (i=0 ; i< sizeof(modes)/sizeof(modes[0]) ; i++)
|
||||
{
|
||||
if (!Q_strcasecmp (modes[i].name, Cmd_Argv(1) ) )
|
||||
if (!Q_strcasecmp (modes[i].name, gl_texturemode.string ) )
|
||||
break;
|
||||
if (!Q_strcasecmp (modes[i].altname, gl_texturemode.string ) )
|
||||
break;
|
||||
}
|
||||
if (i == 6)
|
||||
{
|
||||
Con_Printf ("bad filter name\n");
|
||||
Con_Printf ("bad gl_texturemode name\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1085,8 +1079,6 @@ void GLDraw_Init (void)
|
|||
|
||||
memset(scrap_allocated, 0, sizeof(scrap_allocated));
|
||||
|
||||
Cmd_AddRemCommand ("gl_texturemode", &GLDraw_TextureMode_f);
|
||||
|
||||
GLDraw_ReInit();
|
||||
|
||||
R_BackendInit();
|
||||
|
|
|
@ -2793,7 +2793,7 @@ void * GLMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum
|
|||
else if (version == SPRITEHL_VERSION)
|
||||
{
|
||||
if (!pspriteframe->gl_texturenum)
|
||||
pspriteframe->gl_texturenum = GL_LoadTexture8Pal32 (name, width, height, (unsigned *)(pinframe + 1), (qbyte*)palette, true, true);
|
||||
pspriteframe->gl_texturenum = GL_LoadTexture8Pal32 (name, width, height, (qbyte *)(pinframe + 1), (qbyte*)palette, true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1213,6 +1213,7 @@ static void PPL_BaseChain_Flat(msurface_t *first)
|
|||
|
||||
for (s = first; s ; s=s->texturechain)
|
||||
{
|
||||
if (s->mesh->numvertexes < 3) continue;
|
||||
if (vi != s->lightmaptexturenum)
|
||||
{
|
||||
if (vi < 0)
|
||||
|
|
|
@ -3170,6 +3170,7 @@ qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
|||
}
|
||||
}
|
||||
|
||||
qbyte *Q1BSP_LeafPVS (model_t *model, mleaf_t *leaf, qbyte *buffer);
|
||||
|
||||
/*
|
||||
===============
|
||||
|
|
|
@ -130,7 +130,7 @@ needs almost the entire 256k of stack space!
|
|||
|
||||
void GLSCR_UpdateScreen (void)
|
||||
{
|
||||
extern cvar_t vid_conwidth, vid_conheight;
|
||||
extern cvar_t vid_conwidth, vid_conheight, gl_texturemode;
|
||||
int uimenu;
|
||||
#ifdef TEXTEDITOR
|
||||
extern qboolean editormodal;
|
||||
|
@ -214,6 +214,8 @@ void GLSCR_UpdateScreen (void)
|
|||
oldsbar = cl_sbar.value;
|
||||
vid.recalc_refdef = true;
|
||||
}
|
||||
if (gl_texturemode.modified)
|
||||
GLDraw_TextureMode_Changed();
|
||||
|
||||
GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
|
||||
|
||||
|
|
|
@ -414,6 +414,7 @@ qboolean VID_SetWindowedMode (rendererstate_t *info)
|
|||
vid.conwidth = info->width;
|
||||
vid.width = vid.conwidth;
|
||||
vid.height = vid.conheight;
|
||||
vid_conwidth.modified = true;
|
||||
|
||||
vid.numpages = 2;
|
||||
|
||||
|
@ -527,6 +528,7 @@ qboolean VID_SetFullDIBMode (rendererstate_t *info)
|
|||
vid.conwidth = info->width;
|
||||
vid.width = vid.conwidth;
|
||||
vid.height = vid.conheight;
|
||||
vid_conwidth.modified = true;
|
||||
|
||||
vid.numpages = 2;
|
||||
|
||||
|
@ -1275,11 +1277,7 @@ LONG WINAPI GLMainWndProc (
|
|||
{
|
||||
WindowRect.right = ((short*)&lParam)[0] - WindowRect.left;
|
||||
WindowRect.bottom = ((short*)&lParam)[1] - WindowRect.top;
|
||||
|
||||
if (modestate != MS_FULLDIB) //fullscreen doesn't have the RIGHT to respond to this. Apply to the Court of M$ if you want this changed...
|
||||
{
|
||||
vid_conwidth.modified = true; //make it reapplied
|
||||
}
|
||||
vid_conwidth.modified = true; //make it reapplied
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -249,8 +249,7 @@ void R_DrawSkyChain (msurface_t *s)
|
|||
|
||||
// used when gl_texsort is on
|
||||
GL_Bind(solidskytexture);
|
||||
speedscale = cl.gametime;
|
||||
speedscale += realtime - cl.gametimemark;
|
||||
speedscale = cl.servertime;
|
||||
speedscale*=8;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
|
@ -259,8 +258,7 @@ void R_DrawSkyChain (msurface_t *s)
|
|||
|
||||
qglEnable (GL_BLEND);
|
||||
GL_Bind (alphaskytexture);
|
||||
speedscale = cl.gametime;
|
||||
speedscale += realtime - cl.gametimemark;
|
||||
speedscale = cl.servertime;
|
||||
speedscale*=16;
|
||||
speedscale -= (int)speedscale & ~127 ;
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ char **com_argv;
|
|||
struct sockaddr_in;
|
||||
struct sockaddr;
|
||||
struct sockaddr_qstorage;
|
||||
void NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s);
|
||||
int NetadrToSockadr (netadr_t *a, struct sockaddr_qstorage *s);
|
||||
|
||||
qboolean SV_AllowDownload (char *name);
|
||||
|
||||
|
|
|
@ -394,7 +394,7 @@ reeval:
|
|||
#ifdef PARANOID
|
||||
NUM_FOR_EDICT(ed); // make sure it's in range
|
||||
#endif
|
||||
if (ed->readonly)
|
||||
if (!ed || ed->readonly)
|
||||
{
|
||||
pr_xstatement = st-pr_statements;
|
||||
PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name);
|
||||
|
|
|
@ -1950,8 +1950,6 @@ int QCC_PR_CheakCompConst(void)
|
|||
strncpy(pr_token, pr_file_p, end-pr_file_p);
|
||||
pr_token[end-pr_file_p]='\0';
|
||||
|
||||
if (!strcmp(pr_token, "varkeyword"))
|
||||
printf("varkeyword!!!\n");
|
||||
// printf("%s\n", pr_token);
|
||||
c = pHash_Get(&compconstantstable, pr_token);
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ typedef struct {
|
|||
// the server looks at a sharedEntity, which is the start of the game's gentity_t structure
|
||||
typedef struct {
|
||||
q3entityState_t s; // communicated by server to clients
|
||||
q3entityShared_t r; // shared by both the server system and game
|
||||
q3entityShared_t r; // shared by both the server system and game - I *really* don't understand this, it looks like a bug.
|
||||
} q3sharedEntity_t;
|
||||
|
||||
|
||||
|
|
|
@ -664,6 +664,18 @@ typedef struct levelcache_s {
|
|||
gametype_e gametype;
|
||||
} levelcache_t;
|
||||
|
||||
#ifdef TCPCONNECT
|
||||
typedef struct svtcpstream_s {
|
||||
int socketnum;
|
||||
int inlen;
|
||||
qboolean waitingforprotocolconfirmation;
|
||||
char inbuffer[1500];
|
||||
float timeouttime;
|
||||
netadr_t remoteaddr;
|
||||
struct svtcpstream_s *next;
|
||||
} svtcpstream_t;
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gametype_e gametype;
|
||||
|
@ -674,6 +686,11 @@ typedef struct
|
|||
int socketip6;
|
||||
int socketipx;
|
||||
|
||||
#ifdef TCPCONNECT
|
||||
int sockettcp;
|
||||
svtcpstream_t *tcpstreams;
|
||||
#endif
|
||||
|
||||
client_t clients[MAX_CLIENTS];
|
||||
int serverflags; // episode completion information
|
||||
|
||||
|
@ -919,6 +936,8 @@ qboolean SVQ3_InitGame(void);
|
|||
qboolean SVQ3_ConsoleCommand(void);
|
||||
void SVQ3_HandleClient(void);
|
||||
void SVQ3_DirectConnect(void);
|
||||
void SVQ3_DropClient(client_t *cl);
|
||||
int SVQ3_AddBot(void);
|
||||
void SVQ3_RunFrame(void);
|
||||
void SVQ3_SendMessage(client_t *client);
|
||||
qboolean SVQ3_Command(void);
|
||||
|
@ -942,6 +961,7 @@ void SV_SetMoveVars(void);
|
|||
//
|
||||
// sv_send.c
|
||||
//
|
||||
qboolean SV_ChallengePasses(int challenge);
|
||||
void SV_QCStat(int type, char *name, int statnum);
|
||||
void SV_ClearQCStats(void);
|
||||
|
||||
|
|
|
@ -584,7 +584,7 @@ void SV_Map_f (void)
|
|||
SV_SpawnServer (level, startspot, false, cinematic);
|
||||
}
|
||||
|
||||
SV_BroadcastCommand ("reconnect\n");
|
||||
SV_BroadcastCommand ("cmd new\n");
|
||||
|
||||
if (!issamelevel)
|
||||
{
|
||||
|
@ -944,7 +944,7 @@ void SV_Status_f (void)
|
|||
avg = 1000*svs.stats.latched_active / STATFRAMES;
|
||||
pak = (float)svs.stats.latched_packets/ STATFRAMES;
|
||||
|
||||
if (net_local_sv_ipadr.type != NA_LOOPBACK)
|
||||
if (svs.socketip != INVALID_SOCKET && net_local_sv_ipadr.type != NA_LOOPBACK)
|
||||
{
|
||||
extern cvar_t pr_imitatemvdsv;
|
||||
if (pr_imitatemvdsv.value)
|
||||
|
@ -952,6 +952,13 @@ void SV_Status_f (void)
|
|||
else
|
||||
Con_Printf ("ip address : %s\n",NET_AdrToString (net_local_sv_ipadr));
|
||||
}
|
||||
if (svs.socketip6 != INVALID_SOCKET && net_local_sv_ip6adr.type != NA_LOOPBACK)
|
||||
Con_Printf ("ipv6 address : %s\n",NET_AdrToString (net_local_sv_ip6adr));
|
||||
if (svs.socketipx != INVALID_SOCKET && net_local_sv_ipxadr.type != NA_LOOPBACK)
|
||||
Con_Printf ("ipx address : %s\n",NET_AdrToString (net_local_sv_ipxadr));
|
||||
if (svs.sockettcp != INVALID_SOCKET && net_local_sv_tcpipadr.type != NA_LOOPBACK)
|
||||
Con_Printf ("tcp address : %s\n",NET_AdrToString (net_local_sv_tcpipadr));
|
||||
|
||||
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.
|
||||
|
@ -1273,39 +1280,14 @@ void SV_Localinfo_f (void)
|
|||
Con_DPrintf("Localinfo %s changed (%s -> %s)\n", Cmd_Argv(1), old, Cmd_Argv(2));
|
||||
}
|
||||
|
||||
void SV_SaveInfo(FILE *f, char *info, char *commandname)
|
||||
{
|
||||
char *command;
|
||||
char *value;
|
||||
|
||||
while(*info == '\\')
|
||||
{
|
||||
command = info+1;
|
||||
value = strchr(command, '\\');
|
||||
info = strchr(value+1, '\\');
|
||||
if (!info) //eot..
|
||||
info = value+strlen(value);
|
||||
|
||||
if (*command == '*') //unsettable, so don't write it for later setting.
|
||||
continue;
|
||||
|
||||
fwrite(commandname, strlen(commandname), 1, f);
|
||||
fwrite(" ", 1, 1, f);
|
||||
fwrite(command, value-command, 1, f);
|
||||
fwrite(" ", 1, 1, f);
|
||||
fwrite(value+1, info-(value+1), 1, f);
|
||||
fwrite("\n", 1, 1, f);
|
||||
}
|
||||
}
|
||||
|
||||
void SV_SaveInfos(FILE *f)
|
||||
{
|
||||
fwrite("\n", 1, 1, f);
|
||||
fwrite("serverinfo * \"\"\n", 16, 1, f);
|
||||
SV_SaveInfo(f, svs.info, "serverinfo");
|
||||
Info_WriteToFile(f, svs.info, "serverinfo", CVAR_SERVERINFO);
|
||||
fwrite("\n", 1, 1, f);
|
||||
fwrite("localinfo * \"\"\n", 15, 1, f);
|
||||
SV_SaveInfo(f, localinfo, "localinfo");
|
||||
Info_WriteToFile(f, localinfo, "localinfo", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -123,6 +123,7 @@ cvar_t sv_masterport = {"sv_masterport", "0"};
|
|||
cvar_t sv_voicechat = {"sv_voicechat", "0"}; //still development.
|
||||
cvar_t sv_gamespeed = {"sv_gamespeed", "1"};
|
||||
cvar_t sv_csqcdebug = {"sv_csqcdebug", "0"};
|
||||
cvar_t sv_tcpport = {"sv_tcpport", "0"};
|
||||
|
||||
cvar_t pausable = {"pausable", "1"};
|
||||
|
||||
|
@ -3007,6 +3008,7 @@ void SV_InitLocal (void)
|
|||
|
||||
Cvar_Register (&sv_public, cvargroup_servercontrol);
|
||||
Cvar_Register (&sv_listen, cvargroup_servercontrol);
|
||||
Cvar_Register (&sv_tcpport, cvargroup_servercontrol);
|
||||
Cvar_Register (&sv_reportheartbeats, cvargroup_servercontrol);
|
||||
|
||||
#ifndef SERVERONLY
|
||||
|
@ -3085,6 +3087,7 @@ void SV_InitLocal (void)
|
|||
#ifdef PEXT_BULLETENS
|
||||
svs.fteprotocolextensions |= PEXT_BULLETENS;
|
||||
#endif
|
||||
svs.fteprotocolextensions |= PEXT_ACCURATETIMINGS;
|
||||
#ifdef PEXT_ZLIBDL
|
||||
svs.fteprotocolextensions |= PEXT_ZLIBDL;
|
||||
#endif
|
||||
|
|
|
@ -995,13 +995,23 @@ void SV_WriteClientdataToMessage (client_t *client, sizebuf_t *msg)
|
|||
// every now and then, send an update so that extrapolation
|
||||
// on client side doesn't stray too far off
|
||||
if (ISQWCLIENT(client))
|
||||
if (client->zquake_extensions & Z_EXT_SERVERTIME && sv.physicstime - client->nextservertimeupdate > 0)
|
||||
{
|
||||
MSG_WriteByte (msg, svc_updatestatlong);
|
||||
MSG_WriteByte (msg, STAT_TIME);
|
||||
MSG_WriteLong (msg, (int)(sv.physicstime * 1000));
|
||||
if (client->fteprotocolextensions & PEXT_ACCURATETIMINGS && sv.physicstime - client->nextservertimeupdate > 0)
|
||||
{ //the fte pext causes the server to send out accurate timings, allowing for perfect interpolation.
|
||||
MSG_WriteByte (msg, svc_updatestatlong);
|
||||
MSG_WriteByte (msg, STAT_TIME);
|
||||
MSG_WriteLong (msg, (int)(sv.physicstime * 1000));
|
||||
|
||||
client->nextservertimeupdate = sv.physicstime;//+10;
|
||||
client->nextservertimeupdate = sv.physicstime;//+10;
|
||||
}
|
||||
else if (client->zquake_extensions & Z_EXT_SERVERTIME && sv.physicstime - client->nextservertimeupdate > 0)
|
||||
{ //the zquake ext causes the server to send out peridoic timings, allowing for moderatly accurate game time.
|
||||
MSG_WriteByte (msg, svc_updatestatlong);
|
||||
MSG_WriteByte (msg, STAT_TIME);
|
||||
MSG_WriteLong (msg, (int)(sv.physicstime * 1000));
|
||||
|
||||
client->nextservertimeupdate = sv.physicstime+10;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NQPROT
|
||||
|
|
|
@ -132,7 +132,7 @@ void SV_New_f (void)
|
|||
// host_client->sendinfo = true;
|
||||
|
||||
gamedir = Info_ValueForKey (svs.info, "*gamedir");
|
||||
if (!gamedir[0])
|
||||
if (!gamedir[0] || !strcmp(gamedir, "fte"))
|
||||
gamedir = "qw";
|
||||
|
||||
//NOTE: This doesn't go through ClientReliableWrite since it's before the user
|
||||
|
|
Loading…
Reference in a new issue