rewrote some master server code to isolate games.

servers will subscribe to both ipv4 and ipv6 addresses if a master's name resolves to both types.
handle filename security more cautiously.
avoid some wasted memory with q3bsps. fix crashing bug in dedicated servers.
try fixing OMC's latest issue.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4803 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-12-23 15:26:42 +00:00
parent 100c46a7cc
commit dddee3d76c
30 changed files with 1584 additions and 1056 deletions

View file

@ -488,7 +488,6 @@ CLIENT_OBJS = \
m_mp3.o \
roq_read.o \
clq2_cin.o \
net_master.o \
r_part.o \
p_script.o \
p_null.o \
@ -636,6 +635,7 @@ COMMON_OBJS = \
cmd.o \
crc.o \
net_ssl_gnutls.o \
net_master.o \
fs.o \
fs_stdio.o \
fs_pak.o \

View file

@ -779,21 +779,21 @@ void CL_CheckForResend (void)
if (cls.protocol_nq == CPNQ_ID)
{
net_from = connectinfo.adr;
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\"", NET_PROTOCOL_VERSION, 0, SV_NewChallenge()), false, false);
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\"", NQ_NETCHAN_VERSION, 0, SV_NewChallenge()), false, false);
SVC_DirectConnect();
}
else if (cls.protocol_nq == CPNQ_FITZ666)
{
net_from = connectinfo.adr;
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\\mod\\666\"", NET_PROTOCOL_VERSION, 0, SV_NewChallenge()), false, false);
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\\mod\\666\"", NQ_NETCHAN_VERSION, 0, SV_NewChallenge()), false, false);
SVC_DirectConnect();
}
else if (cls.protocol_nq == CPNQ_PROQUAKE3_4)
{
net_from = connectinfo.adr;
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\\mod\\1\"", NET_PROTOCOL_VERSION, 0, SV_NewChallenge()), false, false);
Cmd_TokenizeString (va("connect %i %i %i \"\\name\\unconnected\\mod\\1\"", NQ_NETCHAN_VERSION, 0, SV_NewChallenge()), false, false);
SVC_DirectConnect();
}
@ -901,10 +901,10 @@ void CL_CheckForResend (void)
sb.data = data;
sb.maxsize = sizeof(data);
MSG_WriteLong(&sb, LongSwap(NETFLAG_CTL | (strlen(NET_GAMENAME_NQ)+7)));
MSG_WriteLong(&sb, LongSwap(NETFLAG_CTL | (strlen(NQ_NETCHAN_GAMENAME)+7)));
MSG_WriteByte(&sb, CCREQ_CONNECT);
MSG_WriteString(&sb, NET_GAMENAME_NQ);
MSG_WriteByte(&sb, NET_PROTOCOL_VERSION);
MSG_WriteString(&sb, NQ_NETCHAN_GAMENAME);
MSG_WriteByte(&sb, NQ_NETCHAN_VERSION);
/*NQ engines have a few extra bits on the end*/
/*proquake servers wait for us to send them a packet before anything happens,
@ -2078,14 +2078,19 @@ void CL_SetInfo_f (void)
void CL_SaveInfo(vfsfile_t *f)
{
int i;
VFS_WRITE(f, "\n", 1);
for (i = 0; i < MAX_SPLITS; i++)
{
VFS_WRITE(f, "\n", 1);
if (i)
{
VFS_WRITE(f, va("p%i setinfo * \"\"\n", i+1), 16);
Info_WriteToFile(f, cls.userinfo[i], va("p%i setinfo", i+1), 0);
}
else
{
VFS_WRITE(f, "setinfo * \"\"\n", 13);
Info_WriteToFile(f, cls.userinfo[i], "setinfo", CVAR_USERINFO);
Info_WriteToFile(f, cls.userinfo[i], "setinfo", CVAR_USERINFO);
}
}
}
@ -2720,6 +2725,40 @@ void CL_ConnectionlessPacket (void)
return;
}
}
if (c == 'i')
{
if (!strncmp(net_message.data+4, "infoResponse\n", 13))
{
Con_TPrintf ("infoResponse\n");
Info_Print(net_message.data+17, "");
return;
}
}
if (c == 'g')
{
if (!strncmp(net_message.data+4, "getserversResponse", 18))
{
qbyte *b = net_message.data+4+18;
Con_TPrintf ("getserversResponse\n");
while (b+7 <= net_message.data+net_message.cursize)
{
if (*b == '\\')
{
b+=1;
Con_Printf("%u.%u.%u.%u:%u\n", b[0], b[1], b[2], b[3], b[5]|(b[4]<<8));
b+=6;
}
else if (*b == '/')
{
b+=1;
Con_Printf("[%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]:%u\n", (b[0]<<8)|b[1], (b[2]<<8)|b[3], (b[4]<<8)|b[5], (b[6]<<8)|b[7], (b[8]<<8)|b[9], (b[10]<<8)|b[11], (b[12]<<8)|b[13], (b[14]<<8)|b[15], b[17]|(b[16]<<8));
b+=18;
}
}
return;
}
}
#endif
if (c == 'd') //note - this conflicts with qw masters, our browser uses a different socket.
@ -4756,6 +4795,8 @@ void CL_StartCinematicOrMenu(void)
realtime+=1;
Cbuf_Execute (); //server may have been waiting for the renderer
Con_ClearNotify();
//and any startup cinematics
#ifndef NOMEDIA
#ifndef CLIENTONLY
@ -4852,6 +4893,7 @@ void CL_ArgumentOverrides(void)
void CL_ExecInitialConfigs(char *resetcommand)
{
int qrc, hrc, def;
extern cvar_t fs_gamename, com_protocolname; //these come from the manifest, so shouldn't be reset by cvarreset
Cbuf_Execute (); //make sure any pending console commands are done with. mostly, anyway...
SCR_ShowPic_Clear(true);

View file

@ -1,13 +1,19 @@
#define SS_GENERICQUAKEWORLD 0
#define SS_FTESERVER 1 //hehehe...
#define SS_QUAKE2 2 //useful (and cool). Could be blamed for swamping.
#define SS_NETQUAKE 4
#define SS_FAVORITE 8 //filter all others.
#define SS_KEEPINFO 16
#define SS_DARKPLACES 32
#define SS_QUAKE3 64
#define SS_PROXY 128
#define SS_PROTOCOLMASK 0xf
#define SS_UNKNOWN 0
#define SS_QUAKEWORLD 1
#define SS_NETQUAKE 2
#define SS_DARKPLACES 3
#define SS_QUAKE2 4
#define SS_QUAKE3 5
//#define SS_UNUSED 6
//#define SS_UNUSED 7
#define SS_LOCAL (1<<3u) //local servers are ones we detected without being listed on a master server (masters will report public ips, so these may appear as dupes if they're also public)
#define SS_FTESERVER (1<<4u) //hehehe...
#define SS_FAVORITE (1<<5u) //filter all others.
#define SS_KEEPINFO (1<<6u)
#define SS_PROXY (1<<7u)
//despite not supporting nq or q2, we still load them. We just filter them. This is to make sure we properly write the listing files.
@ -23,11 +29,11 @@ enum mastertype_e
enum masterprotocol_e
{
MP_UNSPECIFIED,
MP_QW,
MP_Q2,
MP_Q3,
MP_NQ,
MP_DP
MP_QUAKEWORLD,
MP_QUAKE2,
MP_QUAKE3,
MP_NETQUAKE,
MP_DPMASTER
};
@ -43,6 +49,7 @@ typedef enum
SLKEY_FREEPLAYERS,
SLKEY_BASEGAME,
SLKEY_FLAGS,
SLKEY_TIMELIMIT,
SLKEY_FRAGLIMIT,
@ -53,6 +60,8 @@ typedef enum
SLKEY_QCSTATUS,
// SLKEY_PLAYERS, //eep!
SLKEY_ISFAVORITE,//eep!
SLKEY_ISLOCAL,
SLKEY_ISPROXY,
SLKEY_TOOMANY,
@ -136,6 +145,7 @@ typedef struct master_s
netadr_t adr;
char *address; //text based address (http servers)
struct dl_download *dl;
qbyte nosave;
qbyte mastertype;
qbyte protocoltype;
int sends; /*needs to resend?*/

View file

@ -275,7 +275,7 @@ static char *scr_centerstring;
char *Get_Q2ConfigString(int i);
#define MAX_PINGREQUESTS 16
#define MAX_PINGREQUESTS 32
netadr_t ui_pings[MAX_PINGREQUESTS];
@ -799,11 +799,13 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
if (ui_pings[i].type == NA_INVALID)
{
serverinfo_t *info;
NET_StringToAdr(cmdtext + 5, 0, &ui_pings[i]);
COM_Parse(cmdtext + 5);
NET_StringToAdr(com_token, 0, &ui_pings[i]);
info = Master_InfoForServer(&ui_pings[i]);
if (info)
{
info->special |= SS_KEEPINFO;
info->sends++;
Master_QueryServer(info);
}
break;
@ -811,7 +813,12 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
}
else if (!strncmp(cmdtext, "localservers", 12))
{
extern void NET_SendPollPacket(int len, void *data, netadr_t to);
netadr_t na;
MasterInfo_Refresh();
NET_StringToAdr("255.255.255.255", PORT_Q3SERVER, &na);
NET_SendPollPacket (14, va("%c%c%c%cgetstatus\n", 255, 255, 255, 255), na);
}
else
#endif
@ -1059,7 +1066,7 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break;
case UI_LAN_CLEARPING: //clear ping
//void (int pingnum)
if (VM_LONG(arg[0])>= 0 && VM_LONG(arg[0]) <= MAX_PINGREQUESTS)
if (VM_LONG(arg[0])>= 0 && VM_LONG(arg[0]) < MAX_PINGREQUESTS)
ui_pings[VM_LONG(arg[0])].type = NA_INVALID;
break;
case UI_LAN_GETPING:
@ -1070,12 +1077,12 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break; //out of bounds.
Master_CheckPollSockets();
if (VM_LONG(arg[0])>= 0 && VM_LONG(arg[0]) <= MAX_PINGREQUESTS)
if (VM_LONG(arg[0])>= 0 && VM_LONG(arg[0]) < MAX_PINGREQUESTS)
{
char *buf = VM_POINTER(arg[1]);
char *adr;
serverinfo_t *info = Master_InfoForServer(&ui_pings[VM_LONG(arg[0])]);
if (info)
if (info && info->ping != 0xffff)
{
adr = NET_AdrToString(adrbuf, sizeof(adrbuf), &info->adr);
if (strlen(adr) < VM_LONG(arg[2]))
@ -1097,12 +1104,12 @@ static qintptr_t UI_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con
break; //out of bounds.
Master_CheckPollSockets();
if (VM_LONG(arg[0])>= 0 && VM_LONG(arg[0]) <= MAX_PINGREQUESTS)
if (VM_LONG(arg[0])>= 0 && VM_LONG(arg[0]) < MAX_PINGREQUESTS)
{
char *buf = VM_POINTER(arg[1]);
char *adr;
serverinfo_t *info = Master_InfoForServer(&ui_pings[VM_LONG(arg[0])]);
if (info)
if (info && info->ping != 0xffff)
{
adr = info->moreinfo->info;
if (!adr)
@ -1597,12 +1604,16 @@ void UI_Stop (void)
void UI_Start (void)
{
int i;
int apiversion;
if (qrenderer == QR_NONE)
return;
UI_Stop();
for (i = 0; i < MAX_PINGREQUESTS; i++)
ui_pings[i].type = NA_INVALID;
uivm = VM_Create("vm/ui", com_nogamedirnativecode.ival?NULL:UI_SystemCallsNative, UI_SystemCallsVM);
if (uivm)
{

View file

@ -1277,6 +1277,16 @@ void Con_DrawNotifyOne (console_t *con)
Font_EndString(font_console);
}
void Con_ClearNotify(void)
{
console_t *con;
conline_t *l;
for (con = &con_main; con; con = con->next)
{
for (l = con->current; l; l = l->older)
l->time = 0;
}
}
void Con_DrawNotify (void)
{
console_t *con;

View file

@ -529,12 +529,12 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu
if (!R_GetShaderSizes(p, &pw, &ph, false))
p = R2D_SafeCachePic(option->picture.picturename);
R_GetShaderSizes(p, &pw, &ph, false);
R2D_ScalePic(xpos+option->common.posx, ypos+option->common.posy, option->common.width?option->common.width:pw, option->common.height?option->common.height:ph, p);
if (R_GetShaderSizes(p, &pw, &ph, false)>0)
R2D_ScalePic(xpos+option->common.posx, ypos+option->common.posy, option->common.width?option->common.width:pw, option->common.height?option->common.height:ph, p);
break;
case mt_picture:
p = R2D_SafeCachePic(option->picture.picturename);
if (R_GetShaderSizes(p, NULL, NULL, false)>=0) R2D_ScalePic(xpos+option->common.posx, ypos+option->common.posy, option->common.width, option->common.height, p);
if (R_GetShaderSizes(p, NULL, NULL, false)>0) R2D_ScalePic(xpos+option->common.posx, ypos+option->common.posy, option->common.width, option->common.height, p);
break;
case mt_childwindow:
MenuDrawItems(xpos+option->common.posx, ypos+option->common.posy, ((menu_t *)option->custom.dptr)->options, (menu_t *)option->custom.dptr);

View file

@ -8,10 +8,9 @@ static cvar_t sb_hideempty = SCVARF("sb_hideempty", "0", CVAR_ARCHIVE);
static cvar_t sb_hidenotempty = SCVARF("sb_hidenotempty", "0", CVAR_ARCHIVE);
static cvar_t sb_hidefull = SCVARF("sb_hidefull", "0", CVAR_ARCHIVE);
static cvar_t sb_hidedead = SCVARF("sb_hidedead", "1", CVAR_ARCHIVE);
extern cvar_t sb_hidequake2;
extern cvar_t sb_hidequake3;
extern cvar_t sb_hidenetquake;
extern cvar_t sb_hidequakeworld;
static cvar_t sb_hidenetquake = SCVARF("sb_hidenetquake", "0", CVAR_ARCHIVE);
static cvar_t sb_hidequakeworld = SCVARF("sb_hidequakeworld","0", CVAR_ARCHIVE);
static cvar_t sb_hideproxies = SCVARF("sb_hideproxies", "0", CVAR_ARCHIVE);
static cvar_t sb_showping = SCVARF("sb_showping", "1", CVAR_ARCHIVE);
static cvar_t sb_showaddress = SCVARF("sb_showaddress", "0", CVAR_ARCHIVE);
@ -33,10 +32,9 @@ void M_Serverlist_Init(void)
Cvar_Register(&sb_hidenotempty, grp);
Cvar_Register(&sb_hidefull, grp);
Cvar_Register(&sb_hidedead, grp);
Cvar_Register(&sb_hidequake2, grp);
Cvar_Register(&sb_hidequake3, grp);
Cvar_Register(&sb_hidenetquake, grp);
Cvar_Register(&sb_hidequakeworld, grp);
Cvar_Register(&sb_hideproxies, grp);
Cvar_Register(&sb_showping, grp);
Cvar_Register(&sb_showaddress, grp);
@ -211,14 +209,24 @@ static servertypes_t flagstoservertype(int flags)
if (flags & SS_FTESERVER)
return ST_FTESERVER;
#endif
if ((flags & SS_NETQUAKE) || (flags & SS_DARKPLACES))
return ST_NETQUAKE;
if (flags & SS_QUAKE2)
return ST_QUAKE2;
if (flags & SS_QUAKE3)
return ST_QUAKE3;
return ST_NORMALQW;
switch(flags & SS_PROTOCOLMASK)
{
case SS_NETQUAKE:
case SS_DARKPLACES:
return ST_NETQUAKE;
case SS_QUAKE2:
return ST_QUAKE2;
case SS_QUAKE3:
return ST_QUAKE3;
case SS_QUAKEWORLD:
return ST_NORMALQW;
case SS_UNKNOWN:
return ST_NORMALQW;
default:
return ST_FTESERVER; //bug
}
}
static void SL_ServerDraw (int x, int y, menucustom_t *ths, menu_t *menu)
@ -287,7 +295,7 @@ static qboolean SL_ServerKey (menucustom_t *ths, menu_t *menu, int key)
if (server)
{
snprintf(info->mappic->picturename, 32, "levelshots/%s", server->map);
if (!R2D_SafeCachePic(info->mappic->picturename))
if (!*server->map || !R2D_SafeCachePic(info->mappic->picturename))
snprintf(info->mappic->picturename, 32, "levelshots/nomap");
}
else
@ -329,7 +337,7 @@ joinserver:
Cbuf_AddText("spectator 0\n", RESTRICT_LOCAL);
}
if (server->special & SS_NETQUAKE)
if ((server->special & SS_PROTOCOLMASK) == SS_NETQUAKE)
Cbuf_AddText(va("nqconnect %s\n", NET_AdrToString(adr, sizeof(adr), &server->adr)), RESTRICT_LOCAL);
else
Cbuf_AddText(va("connect %s\n", NET_AdrToString(adr, sizeof(adr), &server->adr)), RESTRICT_LOCAL);
@ -347,7 +355,7 @@ static void SL_PreDraw (menu_t *menu)
CL_QueryServers();
snprintf(info->refreshtext, sizeof(info->refreshtext), "Refresh - %u of %u\n", Master_NumPolled(), Master_TotalCount());
snprintf(info->refreshtext, sizeof(info->refreshtext), "Refresh - %u/%u/%u\n", Master_NumSorted(), Master_NumPolled(), Master_TotalCount());
info->numslots = Master_NumSorted();
}
static qboolean SL_Key (int key, menu_t *menu)
@ -391,7 +399,7 @@ static qboolean SL_Key (int key, menu_t *menu)
if (server)
{
snprintf(info->mappic->picturename, 32, "levelshots/%s", server->map);
if (!R2D_SafeCachePic(info->mappic->picturename))
if (!*server->map || !R2D_SafeCachePic(info->mappic->picturename))
snprintf(info->mappic->picturename, 32, "levelshots/nomap");
}
else
@ -532,12 +540,18 @@ static void CalcFilters(menu_t *menu)
Master_ClearMasks();
Master_SetMaskInteger(false, SLKEY_PING, 0, SLIST_TEST_LESS);
if (info->filter[1]) Master_SetMaskInteger(true, SLKEY_BASEGAME, SS_NETQUAKE|SS_DARKPLACES, SLIST_TEST_CONTAINS);
if (info->filter[2]) Master_SetMaskInteger(true, SLKEY_BASEGAME, SS_NETQUAKE|SS_DARKPLACES|SS_QUAKE2|SS_QUAKE3, SLIST_TEST_NOTCONTAIN);
if (info->filter[3]) Master_SetMaskInteger(true, SLKEY_BASEGAME, SS_QUAKE2, SLIST_TEST_CONTAINS);
if (info->filter[4]) Master_SetMaskInteger(true, SLKEY_BASEGAME, SS_QUAKE3, SLIST_TEST_CONTAINS);
if (info->filter[5]) Master_SetMaskInteger(false, SLKEY_BASEGAME, SS_FAVORITE, SLIST_TEST_CONTAINS);
// Master_SetMaskInteger(false, SLKEY_PING, 0, SLIST_TEST_GREATEREQUAL);
Master_SetMaskInteger(false, SLKEY_BASEGAME, SS_UNKNOWN, SLIST_TEST_NOTEQUAL);
if (info->filter[1] && info->filter[2])
Master_SetMaskInteger(false, SLKEY_FLAGS, SS_PROXY, SLIST_TEST_CONTAINS);
else
{
if (info->filter[1]) Master_SetMaskInteger(false, SLKEY_BASEGAME, SS_NETQUAKE, SLIST_TEST_NOTEQUAL);
if (info->filter[1]) Master_SetMaskInteger(false, SLKEY_BASEGAME, SS_DARKPLACES, SLIST_TEST_NOTEQUAL);
if (info->filter[2]) Master_SetMaskInteger(false, SLKEY_BASEGAME, SS_QUAKEWORLD, SLIST_TEST_NOTEQUAL);
}
if (info->filter[3]) Master_SetMaskInteger(false, SLKEY_FLAGS, SS_PROXY, SLIST_TEST_NOTCONTAIN);
if (info->filter[5]) Master_SetMaskInteger(false, SLKEY_FLAGS, SS_FAVORITE, SLIST_TEST_CONTAINS);
if (info->filter[6]) Master_SetMaskInteger(false, SLKEY_NUMPLAYERS, 0, SLIST_TEST_NOTEQUAL);
if (info->filter[7]) Master_SetMaskInteger(false, SLKEY_FREEPLAYERS, 0, SLIST_TEST_NOTEQUAL);
}
@ -553,10 +567,9 @@ static qboolean SL_ReFilter (menucheck_t *option, menu_t *menu, chk_set_t set)
if (option->bits>0)
{
info->filter[option->bits] ^= 1;
Cvar_Set(&sb_hidenetquake, info->filter[1]?"0":"1");
Cvar_Set(&sb_hidequakeworld, info->filter[2]?"0":"1");
Cvar_Set(&sb_hidequake2, info->filter[3]?"0":"1");
Cvar_Set(&sb_hidequake3, info->filter[4]?"0":"1");
Cvar_Set(&sb_hidenetquake, info->filter[1]?"1":"0");
Cvar_Set(&sb_hidequakeworld, info->filter[2]?"1":"0");
Cvar_Set(&sb_hideproxies, info->filter[3]?"1":"0");
Cvar_Set(&sb_hideempty, info->filter[6]?"1":"0");
Cvar_Set(&sb_hidefull, info->filter[7]?"1":"0");
@ -574,11 +587,9 @@ static void SL_Remove (menu_t *menu)
{
serverlist_t *info = (serverlist_t*)(menu + 1);
Cvar_Set(&sb_hidenetquake, info->filter[1]?"0":"1");
Cvar_Set(&sb_hidequakeworld, info->filter[2]?"0":"1");
Cvar_Set(&sb_hidequake2, info->filter[3]?"0":"1");
Cvar_Set(&sb_hidequake3, info->filter[4]?"0":"1");
Cvar_Set(&sb_hidenetquake, info->filter[1]?"1":"0");
Cvar_Set(&sb_hidequakeworld, info->filter[2]?"1":"0");
Cvar_Set(&sb_hideproxies, info->filter[3]?"1":"0");
Cvar_Set(&sb_hideempty, info->filter[6]?"1":"0");
Cvar_Set(&sb_hidefull, info->filter[7]?"1":"0");
}
@ -663,25 +674,22 @@ void M_Menu_ServerList2_f(void)
MC_AddCheckBox(menu, 0, 72, vid.height - 64+8*7, "Timelimit", &sb_showtimelimit, 1);
#ifdef NQPROT
MC_AddCheckBoxFunc(menu, 128, 208, vid.height - 64+8*1, "List NQ ", SL_ReFilter, 1);
#endif
MC_AddCheckBoxFunc(menu, 128, 208, vid.height - 64+8*2, "List QW ", SL_ReFilter, 2);
#ifdef Q2CLIENT
MC_AddCheckBoxFunc(menu, 128, 208, vid.height - 64+8*3, "List Q2 ", SL_ReFilter, 3);
#endif
#ifdef Q3CLIENT
MC_AddCheckBoxFunc(menu, 128, 208, vid.height - 64+8*4, "List Q3 ", SL_ReFilter, 4);
if (M_GameType() == MGT_QUAKE1)
{
MC_AddCheckBoxFunc(menu, 128, 208, vid.height - 64+8*1, "Hide NQ ", SL_ReFilter, 1);
MC_AddCheckBoxFunc(menu, 128, 208, vid.height - 64+8*2, "Hide QW ", SL_ReFilter, 2);
}
#endif
MC_AddCheckBoxFunc(menu, 128, 208, vid.height - 64+8*3, "Hide Proxies", SL_ReFilter, 3);
MC_AddCheckBoxFunc(menu, 128, 208, vid.height - 64+8*5, "Only Favs ", SL_ReFilter, 5);
MC_AddCheckBoxFunc(menu, 128, 208, vid.height - 64+8*6, "Hide Empty", SL_ReFilter, 6);
MC_AddCheckBoxFunc(menu, 128, 208, vid.height - 64+8*7, "Hide Full ", SL_ReFilter, 7);
MC_AddCommand(menu, 64, 208, 0, info->refreshtext, SL_DoRefresh);
MC_AddCommand(menu, 64, 320, 0, info->refreshtext, SL_DoRefresh);
info->filter[1] = !sb_hidenetquake.value;
info->filter[2] = !sb_hidequakeworld.value;
info->filter[3] = !sb_hidequake2.value;
info->filter[4] = !sb_hidequake3.value;
info->filter[1] = !!sb_hidenetquake.value;
info->filter[2] = !!sb_hidequakeworld.value;
info->filter[3] = !!sb_hideproxies.value;
info->filter[6] = !!sb_hideempty.value;
info->filter[7] = !!sb_hidefull.value;
@ -731,7 +739,7 @@ static void M_QuickConnect_PreDraw(menu_t *menu)
{
Con_Printf("Quick connect found %s (gamedir %s, players %i/%i, ping %ims)\n", best->name, best->gamedir, best->players, best->maxplayers, best->ping);
if (best->special & SS_NETQUAKE)
if ((best->special & SS_PROTOCOLMASK) == SS_NETQUAKE)
Cbuf_AddText(va("nqconnect %s\n", NET_AdrToString(adr, sizeof(adr), &best->adr)), RESTRICT_LOCAL);
else
Cbuf_AddText(va("join %s\n", NET_AdrToString(adr, sizeof(adr), &best->adr)), RESTRICT_LOCAL);

File diff suppressed because it is too large Load diff

View file

@ -5564,7 +5564,7 @@ qbyte *PDECL CSQC_PRLoadFile (const char *path, void *buffer, int bufsize, size_
}
return COM_LoadStackFile(path, buffer, bufsize, NULL);
return COM_LoadStackFile(path, buffer, bufsize, sz);
}
int QDECL CSQC_PRFileSize (const char *path)

View file

@ -253,7 +253,6 @@ extern quakeparms_t host_parms;
extern cvar_t fs_gamename;
extern cvar_t fs_gamemanifest;
extern cvar_t com_protocolname;
extern cvar_t com_modname;
extern cvar_t com_nogamedirnativecode;
extern cvar_t com_parseutf8;
extern cvar_t com_parseezquake;

View file

@ -2935,6 +2935,7 @@ void Cmd_WriteConfig_f(void)
char *filename;
char fname[MAX_OSPATH];
char sysname[MAX_OSPATH];
qboolean all = true;
if (Cmd_IsInsecure())
{
@ -2953,6 +2954,8 @@ void Cmd_WriteConfig_f(void)
FS_NativePath(fname, FS_GAMEONLY, sysname, sizeof(sysname));
FS_CreatePath(fname, FS_GAMEONLY);
f = FS_OpenVFS(fname, "wbp", FS_GAMEONLY);
all = false;
}
else
{
@ -2967,6 +2970,8 @@ void Cmd_WriteConfig_f(void)
FS_NativePath(fname, FS_BASEGAMEONLY, sysname, sizeof(sysname));
FS_CreatePath(fname, FS_BASEGAMEONLY);
f = FS_OpenVFS(fname, "wbp", FS_BASEGAMEONLY);
all = true;
}
if (!f)
{
@ -2987,7 +2992,7 @@ void Cmd_WriteConfig_f(void)
SV_SaveInfos(f);
#endif
Alias_WriteAliases (f);
Cvar_WriteVariables (f, true);
Cvar_WriteVariables (f, all);
VFS_CLOSE(f);
Cvar_Saved();

View file

@ -89,10 +89,9 @@ cvar_t registered = CVARD("registered","0","Set if quake's pak1.pak is available
cvar_t gameversion = CVARFD("gameversion","", CVAR_SERVERINFO, "gamecode version for server browsers");
cvar_t gameversion_min = CVARD("gameversion_min","", "gamecode version for server browsers");
cvar_t gameversion_max = CVARD("gameversion_max","", "gamecode version for server browsers");
cvar_t fs_gamename = CVARFD("fs_gamename", "", CVAR_NOSET, "The filesystem is trying to run this game");
cvar_t fs_gamename = CVARAFD("com_fullgamename", NULL, "fs_gamename", CVAR_NOSET, "The filesystem is trying to run this game");
cvar_t fs_gamemanifest = CVARFD("fs_gamemanifest", "", CVAR_NOSET, "A small updatable file containing a description of the game, including download mirrors.");
cvar_t com_protocolname = CVARD("com_gamename", "", "The game name used for dpmaster queries");
cvar_t com_modname = CVARD("com_modname", "", "dpmaster information");
cvar_t com_protocolname = CVARAD("com_protocolname", NULL, "com_gamename", "The protocol game name used for dpmaster queries. For compatibility with DP, you can set this to 'DarkPlaces-Quake' in order to be listed in DP's master server, and to list DP servers.");
cvar_t com_parseutf8 = CVARD("com_parseutf8", "0", "Interpret console messages/playernames/etc as UTF-8. Requires special fonts. -1=iso 8859-1. 0=quakeascii(chat uses high chars). 1=utf8, revert to ascii on decode errors. 2=utf8 ignoring errors"); //1 parse. 2 parse, but stop parsing that string if a char was malformed.
cvar_t com_parseezquake = CVARD("com_parseezquake", "0", "Treat chevron chars from configs as a per-character flag. You should use this only for compat with nquake's configs.");
cvar_t com_highlightcolor = CVARD("com_highlightcolor", STRINGIFY(COLOR_RED), "ANSI colour to be used for highlighted text, used when com_parseutf8 is active.");
@ -5759,9 +5758,12 @@ void Info_WriteToFile(vfsfile_t *f, char *info, char *commandname, int cvarflags
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.
if (cvarflags)
{
var = Cvar_FindVar(command);
if (var && var->flags & cvarflags)
continue; //this is saved via a cvar.
}
VFS_WRITE(f, commandname, strlen(commandname));
VFS_WRITE(f, " ", 1);

View file

@ -90,7 +90,7 @@ typedef struct cvar_s
#define CVARAFDC(ConsoleName,Value,ConsoleName2,Flags,Description,Callback) {ConsoleName, NULL, NULL, Flags, 0, 0, 0, ConsoleName2, Callback, Description, Value}
#endif
#define CVARAFD(ConsoleName,Value,ConsoleName2,Flags,Description)CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, Description, NULL)
#define CVARAFC(ConsoleName,Value,ConsoleName2,Flags,Callback) CVARAFC(ConsoleName, Value, ConsoleName2, Flags, NULL, Callback)
#define CVARAFC(ConsoleName,Value,ConsoleName2,Flags,Callback) CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, NULL, Callback)
#define CVARAF(ConsoleName,Value,ConsoleName2,Flags) CVARAFDC(ConsoleName, Value, ConsoleName2, Flags, NULL, NULL)
#define CVARFDC(ConsoleName,Value,Flags,Description,Callback) CVARAFDC(ConsoleName, Value, NULL, Flags, Description, Callback)
#define CVARFC(ConsoleName,Value,Flags,Callback) CVARAFDC(ConsoleName, Value, NULL, Flags, NULL, Callback)

View file

@ -164,6 +164,7 @@ char pubgamedirfile[MAX_OSPATH]; //like gamedirfile, but not set to the fte-only
char com_gamepath[MAX_OSPATH]; //c:\games\quake
char com_homepath[MAX_OSPATH]; //c:\users\foo\my docs\fte\quake
qboolean com_homepathenabled;
qboolean com_homepathusable; //com_homepath is safe, even if not enabled.
char com_configdir[MAX_OSPATH]; //homedir/fte/configs
@ -1200,59 +1201,102 @@ void FS_ReferenceControl(unsigned int refflag, unsigned int resetflags)
//outbuf might not be written into
static const char *FS_GetCleanPath(const char *pattern, char *outbuf, int outlen)
{
char *s;
const char *s;
char *o;
char *seg;
if (strchr(pattern, '\\'))
s = pattern;
seg = o = outbuf;
for(;;)
{
Q_strncpyz(outbuf, pattern, outlen);
pattern = outbuf;
Con_DPrintf("Warning: \\ characters in filename %s\n", pattern);
while((s = strchr(pattern, '\\')))
if (*s == ':')
{
*s = '/';
if (s == pattern+1 && (s[1] == '/' || s[1] == '\\'))
Con_Printf("Error: absolute path in filename %s\n", pattern);
else
Con_Printf("Error: alternative data stream in filename %s\n", pattern);
return NULL;
}
}
if (strstr(pattern, "//"))
{
//amiga uses // as equivelent to /../
//so strip those out
//any other system ignores the extras
Q_strncpyz(outbuf, pattern, outlen);
pattern = outbuf;
Con_DPrintf("Warning: // characters in filename %s\n", pattern);
while ((s=strstr(pattern, "//")))
{
s++;
while (*s)
else if (*s == '\\' || *s == '/' || !*s)
{ //end of segment
if (o == seg && *s)
{
*s = *(s+1);
if (o == outbuf)
{
Con_Printf("Error: absolute path in filename %s\n", pattern);
return NULL;
}
Con_Printf("Error: empty directory name (%s)\n", pattern);
s++;
continue;
}
//ignore any leading spaces in the name segment
//it should just make more stuff invalid
while (*seg == ' ')
seg++;
if (seg[0] == '.')
{
if (o == seg+1)
Con_Printf("Error: source directory (%s)\n", pattern);
else if (seg[1] == '.')
Con_Printf("Error: parent directory (%s)\n", pattern);
else
Con_Printf("Error: hidden name (%s)\n", pattern);
return NULL;
}
#if defined(_WIN32) || defined(__CYGWIN__)
//in win32, we use the //?/ trick to get around filename length restrictions.
//4-letter reserved paths: comX, lptX
//we'll allow this elsewhere to save cycles, just try to avoid running it on a fat32 or ntfs filesystem from linux
if (((seg[0] == 'c' || seg[0] == 'C') &&
(seg[1] == 'o' || seg[1] == 'O') &&
(seg[2] == 'm' || seg[2] == 'M') &&
(seg[3] >= '0' && seg[3] <= '9')) ||
((seg[0] == 'l' || seg[0] == 'L') &&
(seg[1] == 'p' || seg[1] == 'P') &&
(seg[2] == 't' || seg[2] == 'T') &&
(seg[3] >= '0' && seg[3] <= '9')))
{
if (o == seg+4 || seg[4] == ' '|| seg[4] == '\t' || seg[4] == '.')
{
Con_Printf("Error: reserved name in path (%c%c%c%c in %s)\n", seg[0], seg[1], seg[2], seg[3], pattern);
return NULL;
}
}
//3 letter reserved paths: con, nul, prn
if (((seg[0] == 'c' || seg[0] == 'C') &&
(seg[1] == 'o' || seg[1] == 'O') &&
(seg[2] == 'n' || seg[2] == 'N')) ||
((seg[0] == 'p' || seg[0] == 'P') &&
(seg[1] == 'r' || seg[1] == 'R') &&
(seg[2] == 'n' || seg[2] == 'N')) ||
((seg[0] == 'n' || seg[0] == 'N') &&
(seg[1] == 'u' || seg[1] == 'U') &&
(seg[2] == 'l' || seg[2] == 'L')))
{
if (o == seg+3 || seg[3] == ' '|| seg[3] == '\t' || seg[3] == '.')
{
Con_Printf("Error: reserved name in path (%c%c%c in %s)\n", seg[0], seg[1], seg[2], pattern);
return NULL;
}
}
#endif
if (*s++)
*o++ = '/';
else
{
*o++ = '\0';
break;
}
seg = o;
}
}
if (*pattern == '/')
{
/*'fix up' and ignore, compat with q3*/
Con_DPrintf("Error: absolute path in filename %s\n", pattern);
pattern++;
else
*o++ = *s++;
}
if (strstr(pattern, ".."))
Con_Printf("Error: '..' characters in filename %s\n", pattern);
else if (strstr(pattern, ":")) //win32 drive seperator (or mac path seperator, but / works there and they're used to it) (or amiga device separator)
Con_Printf("Error: absolute path in filename %s\n", pattern);
else if (strlen(pattern) > outlen)
Con_Printf("Error: path %s too long\n", pattern);
else
{
return pattern;
}
return NULL;
// Sys_Printf("%s changed to %s\n", pattern, outbuf);
return outbuf;
}
vfsfile_t *VFS_Filter(const char *filename, vfsfile_t *handle)
@ -3258,6 +3302,11 @@ void FS_Shutdown(void)
FS_FreePaths();
Sys_DestroyMutex(fs_thread_mutex);
fs_thread_mutex = NULL;
Z_Free(fs_gamename.enginevalue);
fs_gamename.enginevalue = NULL;
Z_Free(com_protocolname.enginevalue);
fs_gamename.enginevalue = NULL;
}
//returns false if the directory is not suitable.
@ -3846,7 +3895,7 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs)
}
}
if (!man->protocolname && *gamemode_info[i].protocolname)
if (!man->protocolname)
{
Cmd_TokenizeString(va("protocolname \"%s\"", gamemode_info[i].protocolname), false, false);
FS_Manifest_ParseTokens(man);
@ -3876,8 +3925,21 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs)
//make sure it has a trailing slash, or is empty. woo.
FS_CleanDir(com_gamepath, sizeof(com_gamepath));
if (man->disablehomedir && !COM_CheckParm("-usehome"))
com_homepathenabled = false;
{
qboolean oldhome = com_homepathenabled;
com_homepathenabled = com_homepathusable;
if (man->disablehomedir && !COM_CheckParm("-usehome"))
com_homepathenabled = false;
if (com_homepathenabled != oldhome)
{
if (com_homepathenabled)
Con_TPrintf("Using home directory \"%s\"\n", com_homepath);
else
Con_TPrintf("Disabled home directory suport\n");
}
}
#ifdef ANDROID
{
@ -3915,9 +3977,13 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs)
if (reloadconfigs)
{
Z_Free(fs_gamename.enginevalue);
fs_gamename.enginevalue = Z_StrDup(man->formalname?man->formalname:"FTE");
Z_Free(com_protocolname.enginevalue);
com_protocolname.enginevalue = Z_StrDup(man->protocolname?man->protocolname:"FTE");
//FIXME: flag this instead and do it after a delay
Cvar_ForceSet(&fs_gamename, man->formalname?man->formalname:"FTE");
Cvar_ForceSet(&com_protocolname, man->protocolname?man->protocolname:"FTE");
Cvar_ForceSet(&fs_gamename, fs_gamename.enginevalue);
Cvar_ForceSet(&com_protocolname, com_protocolname.enginevalue);
if (isDedicated)
{
@ -4243,7 +4309,6 @@ void COM_InitFilesystem (void)
Cvar_Register(&fs_gamename, "Filesystem");
Cvar_Register(&fs_gamemanifest, "Filesystem");
Cvar_Register(&com_protocolname, "Server Info");
Cvar_Register(&com_modname, "Server Info");
Cvar_Register(&fs_game, "Filesystem");
#ifdef Q2SERVER
Cvar_Register(&fs_gamedir, "Filesystem");
@ -4350,20 +4415,18 @@ void COM_InitFilesystem (void)
*com_homepath = '\0';
#endif
com_homepathenabled = usehome;
com_homepathusable = usehome;
com_homepathenabled = false;
if (COM_CheckParm("-usehome"))
com_homepathenabled = true;
com_homepathusable = true;
if (COM_CheckParm("-nohome"))
com_homepathenabled = false;
com_homepathusable = false;
if (!*com_homepath)
com_homepathenabled = false;
com_homepathusable = false;
fs_readonly = COM_CheckParm("-readonly");
if (com_homepathenabled)
Con_TPrintf("Using home directory \"%s\"\n", com_homepath);
fs_thread_mutex = Sys_CreateMutex();
#ifdef PLUGINS

View file

@ -400,8 +400,6 @@ static int numfaces;
static index_t *map_surfindexes;
static int map_numsurfindexes;
static int *map_leaffaces;
static int numleaffaces;
@ -3003,46 +3001,6 @@ qboolean CModRBSP_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l)
}
#endif
qboolean CModQ3_LoadLeafFaces (model_t *mod, qbyte *mod_base, lump_t *l)
{
int i, j, count;
int *in;
int *out;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size\n");
return false;
}
count = l->filelen / sizeof(*in);
if (count > SANITY_MAX_MAP_LEAFFACES)
{
Con_Printf (CON_ERROR "Map has too many leaffaces\n");
return false;
}
out = BZ_Malloc ( count*sizeof(*out) );
map_leaffaces = out;
numleaffaces = count;
for ( i=0 ; i<count ; i++)
{
j = LittleLong ( in[i] );
if (j < 0 || j >= numfaces)
{
Con_Printf (CON_ERROR "CMod_LoadLeafFaces: bad surface number\n");
return false;
}
out[i] = j;
}
return true;
}
qboolean CModQ3_LoadNodes (model_t *loadmodel, qbyte *mod_base, lump_t *l)
{
int i, j, count, p;
@ -3957,7 +3915,6 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
*/
map_faces = NULL;
map_leaffaces = NULL;
Q1BSPX_Setup(mod, mod_base, filelen, header.lumps, Q3LUMPS_TOTAL);
@ -4009,8 +3966,6 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
facesize = sizeof(q3dface_t);
mod->lightmaps.surfstyles = 1;
}
noerrors = noerrors && CModQ3_LoadMarksurfaces (mod, mod_base, &header.lumps[Q3LUMP_LEAFSURFACES]); //fixme: duplicated loading.
if (noerrors && mod->fromgame == fg_quake3)
{
i = header.lumps[Q3LUMP_LIGHTMAPS].filelen / (mod->lightmaps.width*mod->lightmaps.height*3);
@ -4028,8 +3983,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
CModQ3_LoadLighting (mod, mod_base, &header.lumps[Q3LUMP_LIGHTMAPS]); //fixme: duplicated loading.
}
#endif
noerrors = noerrors && CModQ3_LoadLeafFaces (mod, mod_base, &header.lumps[Q3LUMP_LEAFSURFACES]);
noerrors = noerrors && CModQ3_LoadLeafs (mod, mod_base, &header.lumps[Q3LUMP_LEAFS]);
noerrors = noerrors && CModQ3_LoadMarksurfaces (mod, mod_base, &header.lumps[Q3LUMP_LEAFSURFACES]); noerrors = noerrors && CModQ3_LoadLeafs (mod, mod_base, &header.lumps[Q3LUMP_LEAFS]);
noerrors = noerrors && CModQ3_LoadNodes (mod, mod_base, &header.lumps[Q3LUMP_NODES]);
noerrors = noerrors && CModQ3_LoadSubmodels (mod, mod_base, &header.lumps[Q3LUMP_MODELS]);
noerrors = noerrors && CModQ3_LoadVisibility (mod, mod_base, &header.lumps[Q3LUMP_VISIBILITY]);
@ -4040,8 +3994,6 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
{
if (map_faces)
BZ_Free(map_faces);
if (map_leaffaces)
BZ_Free(map_leaffaces);
return NULL;
}
@ -4089,7 +4041,6 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
if (!CM_CreatePatchesForLeafs (mod)) //for clipping
{
BZ_Free(map_faces);
BZ_Free(map_leaffaces);
return NULL;
}
#ifndef CLIENTONLY
@ -4097,7 +4048,6 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
#endif
// BZ_Free(map_verts);
BZ_Free(map_faces);
BZ_Free(map_leaffaces);
break;
#endif
case Q2BSPVERSION:

View file

@ -104,8 +104,10 @@ qboolean NET_CompareAdr (netadr_t *a, netadr_t *b);
qboolean NET_CompareBaseAdr (netadr_t *a, netadr_t *b);
char *NET_AdrToString (char *s, int len, netadr_t *a);
char *NET_BaseAdrToString (char *s, int len, netadr_t *a);
qboolean NET_StringToSockaddr (const char *s, int defaultport, struct sockaddr_qstorage *sadr, int *addrfamily, int *addrsize);
qboolean NET_StringToAdr (const char *s, int defaultport, netadr_t *a);
size_t NET_StringToSockaddr2 (const char *s, int defaultport, struct sockaddr_qstorage *sadr, int *addrfamily, int *addrsize, size_t addrcount);
#define NET_StringToSockaddr(s,p,a,f,z) (NET_StringToSockaddr2(s,p,a,f,z,1)>0)
size_t NET_StringToAdr2 (const char *s, int defaultport, netadr_t *a, size_t addrcount);
#define NET_StringToAdr(s,p,a) (NET_StringToAdr2(s,p,a,1)>0)
qboolean NET_PortToAdr (int adrfamily, const char *s, netadr_t *a);
qboolean NET_IsClientLegal(netadr_t *adr);
@ -194,6 +196,8 @@ typedef struct
extern int net_drop; // packets dropped before this one
void Net_Master_Init(void);
void Netchan_Init (void);
int Netchan_Transmit (netchan_t *chan, int length, qbyte *data, int rate);
void Netchan_OutOfBand (netsrc_t sock, netadr_t *adr, int length, qbyte *data);
@ -237,8 +241,8 @@ void Huff_EmitByte(int ch, qbyte *buffer, int *count);
#define NETFLAG_UNRELIABLE 0x00100000
#define NETFLAG_CTL 0x80000000
#define NET_GAMENAME_NQ "QUAKE"
#define NET_PROTOCOL_VERSION 3
#define NQ_NETCHAN_GAMENAME "QUAKE"
#define NQ_NETCHAN_VERSION 3
#define CCREQ_CONNECT 0x01

View file

@ -728,14 +728,15 @@ idnewt:28000
any form of ipv6, including port number.
=============
*/
qboolean NET_StringToSockaddr (const char *s, int defaultport, struct sockaddr_qstorage *sadr, int *addrfamily, int *addrsize)
size_t NET_StringToSockaddr2 (const char *s, int defaultport, struct sockaddr_qstorage *sadr, int *addrfamily, int *addrsize, size_t addresses)
{
struct hostent *h;
char *colon;
char copy[128];
size_t result = 0;
if (!(*s))
return false;
if (!(*s) || !addresses)
return result;
memset (sadr, 0, sizeof(*sadr));
@ -772,6 +773,7 @@ qboolean NET_StringToSockaddr (const char *s, int defaultport, struct sockaddr_q
*addrfamily = AF_IPX;
if (addrsize)
*addrsize = sizeof(struct sockaddr_ipx);
result++;
}
else
#endif
@ -789,6 +791,7 @@ qboolean NET_StringToSockaddr (const char *s, int defaultport, struct sockaddr_q
char *port;
char dupbase[256];
int len;
size_t i;
memset(&udp6hint, 0, sizeof(udp6hint));
udp6hint.ai_family = 0;//Any... we check for AF_INET6 or 4
@ -838,42 +841,45 @@ qboolean NET_StringToSockaddr (const char *s, int defaultport, struct sockaddr_q
switch(pos->ai_family)
{
case AF_INET6:
if (((struct sockaddr_in *)sadr)->sin_family == AF_INET6)
break; //first one should be best...
//fallthrough
if (result < addresses)
memcpy(&sadr[result++], pos->ai_addr, pos->ai_addrlen);
break;
#ifdef HAVE_IPV4
case AF_INET:
memcpy(sadr, pos->ai_addr, pos->ai_addrlen);
if (pos->ai_family == AF_INET)
goto dblbreak; //don't try finding any more, this is quake, they probably prefer ip4...
//ipv4 addresses have a higher priority than ipv6 ones.
if (result && ((struct sockaddr_in *)&sadr[0])->sin_family == AF_INET6)
{
if (result < addresses)
memcpy(&sadr[result++], &sadr[0], sizeof(sadr[0]));
memcpy(&sadr[0], pos->ai_addr, pos->ai_addrlen);
}
else if (result < addresses)
memcpy(&sadr[result++], pos->ai_addr, pos->ai_addrlen);
break;
#else
memcpy(sadr, pos->ai_addr, pos->ai_addrlen);
goto dblbreak;
#endif
}
}
dblbreak:
pfreeaddrinfo (addrinfo);
if (!((struct sockaddr*)sadr)->sa_family) //none suitablefound
return false;
if (addrfamily)
*addrfamily = ((struct sockaddr*)sadr)->sa_family;
if (((struct sockaddr*)sadr)->sa_family == AF_INET)
for (i = 0; i < result; i++)
{
if (!((struct sockaddr_in *)sadr)->sin_port)
((struct sockaddr_in *)sadr)->sin_port = htons(defaultport);
if (addrsize)
*addrsize = sizeof(struct sockaddr_in);
}
else
{
if (!((struct sockaddr_in6 *)sadr)->sin6_port)
((struct sockaddr_in6 *)sadr)->sin6_port = htons(defaultport);
if (addrsize)
*addrsize = sizeof(struct sockaddr_in6);
if (addrfamily)
addrfamily[i] = ((struct sockaddr*)sadr)->sa_family;
if (((struct sockaddr*)&sadr[i])->sa_family == AF_INET)
{
if (!((struct sockaddr_in *)&sadr[i])->sin_port)
((struct sockaddr_in *)&sadr[i])->sin_port = htons(defaultport);
if (addrsize)
addrsize[i] = sizeof(struct sockaddr_in);
}
else if (((struct sockaddr*)&sadr[i])->sa_family == AF_INET6)
{
if (!((struct sockaddr_in6 *)&sadr[i])->sin6_port)
((struct sockaddr_in6 *)&sadr[i])->sin6_port = htons(defaultport);
if (addrsize)
addrsize[i] = sizeof(struct sockaddr_in6);
}
}
}
else
@ -914,33 +920,36 @@ dblbreak:
*addrfamily = AF_INET;
if (addrsize)
*addrsize = sizeof(struct sockaddr_in);
#else
return false;
result++;
#endif
}
return true;
return result;
}
/*
accepts anything that NET_StringToSockaddr accepts plus certain url schemes
including: tcp, irc
*/
qboolean NET_StringToAdr (const char *s, int defaultport, netadr_t *a)
size_t NET_StringToAdr2 (const char *s, int defaultport, netadr_t *a, size_t numaddresses)
{
struct sockaddr_qstorage sadr;
size_t result = 0, i;
struct sockaddr_qstorage sadr[8];
memset(a, 0, sizeof(*a)*numaddresses);
Con_DPrintf("Resolving address: %s\n", s);
if (!numaddresses)
return false;
if (!strcmp (s, "internalserver"))
{
memset (a, 0, sizeof(*a));
a->type = NA_LOOPBACK;
return true;
}
if (!strncmp(s, "QLoopBack", 9))
{
memset (a, 0, sizeof(*a));
a->type = NA_LOOPBACK;
if (s[9] == ':')
a->port = atoi(s+10);
@ -952,7 +961,6 @@ qboolean NET_StringToAdr (const char *s, int defaultport, netadr_t *a)
#ifdef HAVE_WEBSOCKCL
if (!strncmp (s, "ws://", 5) || !strncmp (s, "wss://", 6))
{
memset (a, 0, sizeof(*a));
a->type = NA_WEBSOCKET;
Q_strncpyz(a->address.websocketurl, s, sizeof(a->address.websocketurl));
return true;
@ -966,7 +974,6 @@ qboolean NET_StringToAdr (const char *s, int defaultport, netadr_t *a)
Con_Printf("Note: Assuming ws:// prefix\n");
warned = realtime + 1;
}
memset (a, 0, sizeof(*a));
a->type = NA_WEBSOCKET;
memcpy(a->address.websocketurl, "ws://", 5);
Q_strncpyz(a->address.websocketurl+5, s, sizeof(a->address.websocketurl)-5);
@ -978,13 +985,13 @@ qboolean NET_StringToAdr (const char *s, int defaultport, netadr_t *a)
{
//make sure that the rest of the address is a valid ip address (4 or 6)
if (!NET_StringToSockaddr (s+6, defaultport, &sadr, NULL, NULL))
if (!NET_StringToSockaddr (s+6, defaultport, &sadr[0], NULL, NULL))
{
a->type = NA_INVALID;
return false;
}
SockadrToNetadr (&sadr, a);
SockadrToNetadr (&sadr[0], a);
if (a->type == NA_IP)
{
@ -1002,13 +1009,13 @@ qboolean NET_StringToAdr (const char *s, int defaultport, netadr_t *a)
{
//make sure that the rest of the address is a valid ip address (4 or 6)
if (!NET_StringToSockaddr (s+6, defaultport, &sadr, NULL, NULL))
if (!NET_StringToSockaddr (s+6, defaultport, &sadr[0], NULL, NULL))
{
a->type = NA_INVALID;
return false;
}
SockadrToNetadr (&sadr, a);
SockadrToNetadr (&sadr[0], a);
if (a->type == NA_IP)
{
@ -1068,23 +1075,25 @@ qboolean NET_StringToAdr (const char *s, int defaultport, netadr_t *a)
}
#endif
if (!NET_StringToSockaddr (s, defaultport, &sadr, NULL, NULL))
result = NET_StringToSockaddr2 (s, defaultport, sadr, NULL, NULL, min(numaddresses, sizeof(sadr)/sizeof(sadr[0])));
for (i = 0; i < result; i++)
{
a->type = NA_INVALID;
return false;
}
SockadrToNetadr (&sadr, a);
SockadrToNetadr (&sadr[i], &a[i]);
#if !defined(HAVE_PACKET) && defined(HAVE_TCP)
//bump over protocols that cannot work in the first place.
if (a->type == NA_IP)
a->type = NA_TCP;
if (a->type == NA_IPV6)
a->type = NA_TCPV6;
//bump over protocols that cannot work in the first place.
if (a[i].type == NA_IP)
a[i].type = NA_TCP;
if (a[i].type == NA_IPV6)
a[i].type = NA_TCPV6;
#endif
}
return true;
//invalidate any others
for (; i < numaddresses; i++)
a[i].type = NA_INVALID;
return result;
}
// NET_IntegerToMask: given a source address pointer, a mask address pointer, and
@ -3061,10 +3070,10 @@ closesvstream:
net_message.packing = SZ_RAWBYTES;
net_message.currentbit = 0;
net_from = st->remoteaddr;
MSG_WriteLong(&net_message, LongSwap(NETFLAG_CTL | (strlen(NET_GAMENAME_NQ)+7)));
MSG_WriteLong(&net_message, LongSwap(NETFLAG_CTL | (strlen(NQ_NETCHAN_GAMENAME)+7)));
MSG_WriteByte(&net_message, CCREQ_CONNECT);
MSG_WriteString(&net_message, NET_GAMENAME_NQ);
MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION);
MSG_WriteString(&net_message, NQ_NETCHAN_GAMENAME);
MSG_WriteByte(&net_message, NQ_NETCHAN_VERSION);
return true;
}
}
@ -5182,9 +5191,9 @@ int maxport = port + 100;
// _true = true;
// if (setsockopt(newsocket, SOL_SOCKET, IP_ADD_MEMBERSHIP, (char *)&_true, sizeof(_true)) == -1)
// {
Con_Printf("Cannot create broadcast socket\n");
closesocket(newsocket);
return (int)INVALID_SOCKET;
// Con_Printf("Cannot create broadcast socket\n");
// closesocket(newsocket);
// return (int)INVALID_SOCKET;
// }
}
@ -5546,6 +5555,8 @@ void NET_Init (void)
Cvar_Register (&net_upnpigp, "networking");
net_upnpigp.restriction = RESTRICT_MAX;
Net_Master_Init();
}
#ifndef SERVERONLY
void NET_InitClient(void)

View file

@ -45,6 +45,20 @@ void PF_Common_RegisterCvars(void)
WPhys_Init();
}
//just prints out a warning with stack trace. so I can throttle spammy stack traces.
static void PF_Warningf(pubprogfuncs_t *prinst, const char *fmt, ...)
{
va_list argptr;
char string[1024];
va_start (argptr, fmt);
vsnprintf (string, sizeof(string)-1, fmt, argptr);
va_end (argptr);
Con_Printf("%s", string);
PR_StackTrace(prinst, false);
}
char *PF_VarString (pubprogfuncs_t *prinst, int first, struct globalvars_s *pr_globals)
{
#define VARSTRINGLEN 16384+8
@ -1700,13 +1714,13 @@ void QCBUILTIN PF_fclose (pubprogfuncs_t *prinst, struct globalvars_s *pr_global
if (fnum < 0 || fnum >= MAX_QC_FILES)
{
Con_Printf("PF_fclose: File out of range (%g)\n", G_FLOAT(OFS_PARM0));
PF_Warningf(prinst, "PF_fclose: File out of range (%g)\n", G_FLOAT(OFS_PARM0));
return; //out of range
}
if (pf_fopen_files[fnum].prinst != prinst)
{
Con_Printf("PF_fclose: File is from wrong instance\n");
PF_Warningf(prinst, "PF_fclose: File is from wrong instance\n");
return; //this just isn't ours.
}
@ -1796,19 +1810,19 @@ static void PF_fwrite (pubprogfuncs_t *prinst, int fnum, char *msg, int len)
{
if (fnum < 0 || fnum >= MAX_QC_FILES)
{
Con_Printf("PF_fwrite: File out of range\n");
PF_Warningf(prinst, "PF_fwrite: File out of range\n");
return; //out of range
}
if (!pf_fopen_files[fnum].data)
{
Con_Printf("PF_fwrite: File is not open\n");
PF_Warningf(prinst, "PF_fwrite: File is not open\n");
return; //not open
}
if (pf_fopen_files[fnum].prinst != prinst)
{
Con_Printf("PF_fwrite: File is from wrong instance\n");
PF_Warningf(prinst, "PF_fwrite: File is from wrong instance\n");
return; //this just isn't ours.
}
@ -1920,7 +1934,7 @@ void search_close (pubprogfuncs_t *prinst, int handle)
{ //close it down.
if (s->fromprogs != prinst)
{
Con_Printf("Handle wasn't valid with that progs\n");
PF_Warningf(prinst, "Handle wasn't valid with that progs\n");
return;
}
if (prev)
@ -2041,7 +2055,7 @@ void QCBUILTIN PF_search_getsize (pubprogfuncs_t *prinst, struct globalvars_s *p
{ //close it down.
if (s->fromprogs != prinst)
{
Con_Printf("Handle wasn't valid with that progs\n");
PF_Warningf(prinst, "Handle wasn't valid with that progs\n");
return;
}
@ -2064,7 +2078,7 @@ void QCBUILTIN PF_search_getfilename (pubprogfuncs_t *prinst, struct globalvars_
{ //close it down.
if (s->fromprogs != prinst)
{
Con_Printf("Search handle wasn't valid with that progs\n");
PF_Warningf(prinst, "Search handle wasn't valid with that progs\n");
return;
}
@ -2075,7 +2089,7 @@ void QCBUILTIN PF_search_getfilename (pubprogfuncs_t *prinst, struct globalvars_
}
}
Con_Printf("Search handle wasn't valid\n");
PF_Warningf(prinst, "Search handle wasn't valid\n");
}
//closes filesystem type stuff for when a progs has stopped needing it.
@ -2183,14 +2197,14 @@ void QCBUILTIN PF_parseentitydata(pubprogfuncs_t *prinst, struct globalvars_s *p
}
if (!prinst->restoreent(prinst, file, &size, ed))
Con_Printf("parseentitydata: missing opening data\n");
PF_Warningf(prinst, "parseentitydata: missing opening data\n");
else
{
file += size;
while(*file < ' ' && *file)
file++;
if (*file)
Con_Printf("parseentitydata: too much data\n");
PF_Warningf(prinst, "parseentitydata: too much data\n");
}
G_FLOAT(OFS_RETURN) = 0;

View file

@ -10940,194 +10940,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\client\net_master.c"
>
<FileConfiguration
Name="MinGLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\client\p_classic.c"
>
@ -27239,6 +27051,190 @@
RelativePath="..\common\net_ice.c"
>
</File>
<File
RelativePath="..\client\net_master.c"
>
<FileConfiguration
Name="MinGLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\common\net_ssl_winsspi.c"
>

View file

@ -11,12 +11,12 @@ vfsfile_t *IWebGenerateFile(char *name)
}
#else
char lastrecordedmvd[MAX_QPATH];
static char lastrecordedmvd[MAX_QPATH];
IWeb_FileGen_t *IWeb_GenerationBuffer;
size_t IWeb_GenerationBufferTotal;
static IWeb_FileGen_t *IWeb_GenerationBuffer;
static size_t IWeb_GenerationBufferTotal;
void IWeb_MoreGeneratedResize(size_t newsize)
static void IWeb_MoreGeneratedResize(size_t newsize)
{
IWeb_FileGen_t *ob;
@ -37,7 +37,7 @@ void IWeb_MoreGeneratedResize(size_t newsize)
IWeb_GenerationBufferTotal = newsize;
}
void IWeb_Generate(const char *buf)
static void IWeb_Generate(const char *buf)
{
size_t count = strlen(buf);
if (!IWeb_GenerationBuffer || IWeb_GenerationBuffer->len + count >= IWeb_GenerationBufferTotal)
@ -72,7 +72,7 @@ void IWeb_Generate(const char *buf)
int Rank_Enumerate (unsigned int first, unsigned int last, void (*callback) (const rankinfo_t *ri)); //leader first.
void IWeb_ParseForm(char *info, int infolen, char *text)
static void IWeb_ParseForm(char *info, int infolen, char *text)
{
char *eq, *and;
char *token, *out;
@ -141,7 +141,7 @@ void IWeb_ParseForm(char *info, int infolen, char *text)
}
}
void IWeb_GenerateAdminFile(char *parms, char *content, int contentlength)
static void IWeb_GenerateAdminFile(char *parms, char *content, int contentlength)
{
extern char outputbuf[]; //redirected buffer - always null termed.
char info[16384];
@ -198,7 +198,7 @@ void IWeb_GenerateAdminFile(char *parms, char *content, int contentlength)
}
void IWeb_GenerateRankingsFileCallback(const rankinfo_t *ri)
static void IWeb_GenerateRankingsFileCallback(const rankinfo_t *ri)
{
IWeb_Generate("<TR><TD ALIGN = \"center\">");
IWeb_Generate(ri->h.name);
@ -210,7 +210,7 @@ void IWeb_GenerateRankingsFileCallback(const rankinfo_t *ri)
IWeb_Generate("</TR>");
}
void IWeb_GenerateRankingsFile (char *parms, char *content, int contentlength)
static void IWeb_GenerateRankingsFile (char *parms, char *content, int contentlength)
{
IWeb_Generate("<HTML><HEAD></HEAD><BODY>");
@ -241,7 +241,7 @@ void IWeb_GenerateRankingsFile (char *parms, char *content, int contentlength)
IWeb_Generate("</BODY></HTML>");
}
void IWeb_GenerateIndexFile (char *parms, char *content, int contentlength)
static void IWeb_GenerateIndexFile (char *parms, char *content, int contentlength)
{
extern cvar_t rcon_password;
char *s, *o;
@ -343,7 +343,7 @@ typedef struct {
int genid;
} IWebFile_t;
IWebFile_t IWebFiles[] = {
static IWebFile_t IWebFiles[] = {
{"allplayers.html", IWeb_GenerateRankingsFile},
{"index.html", IWeb_GenerateIndexFile},
//code is too flawed for this {"admin.html", IWeb_GenerateAdminFile}
@ -356,7 +356,7 @@ typedef struct {
int pos;
} vfsgen_t;
int QDECL VFSGen_ReadBytes(vfsfile_t *f, void *buffer, int bytes)
static int QDECL VFSGen_ReadBytes(vfsfile_t *f, void *buffer, int bytes)
{
vfsgen_t *g = (vfsgen_t*)f;
if (bytes + g->pos >= g->buffer->len)
@ -372,13 +372,13 @@ int QDECL VFSGen_ReadBytes(vfsfile_t *f, void *buffer, int bytes)
return bytes;
}
int QDECL VFSGen_WriteBytes(vfsfile_t *f, const void *buffer, int bytes)
static int QDECL VFSGen_WriteBytes(vfsfile_t *f, const void *buffer, int bytes)
{
Sys_Error("VFSGen_WriteBytes: Readonly\n");
return 0;
}
qboolean QDECL VFSGen_Seek(vfsfile_t *f, qofs_t newpos)
static qboolean QDECL VFSGen_Seek(vfsfile_t *f, qofs_t newpos)
{
vfsgen_t *g = (vfsgen_t*)f;
if (newpos < 0 || newpos >= g->buffer->len)
@ -389,19 +389,19 @@ qboolean QDECL VFSGen_Seek(vfsfile_t *f, qofs_t newpos)
return true;
}
qofs_t QDECL VFSGen_Tell(vfsfile_t *f)
static qofs_t QDECL VFSGen_Tell(vfsfile_t *f)
{
vfsgen_t *g = (vfsgen_t*)f;
return g->pos;
}
qofs_t QDECL VFSGen_GetLen(vfsfile_t *f)
static qofs_t QDECL VFSGen_GetLen(vfsfile_t *f)
{
vfsgen_t *g = (vfsgen_t*)f;
return g->buffer->len;
}
qboolean QDECL VFSGen_Close(vfsfile_t *f)
static qboolean QDECL VFSGen_Close(vfsfile_t *f)
{
int fnum;
vfsgen_t *g = (vfsgen_t*)f;
@ -420,7 +420,7 @@ qboolean QDECL VFSGen_Close(vfsfile_t *f)
}
vfsfile_t *VFSGen_Create(IWeb_FileGen_t *gen)
static vfsfile_t *VFSGen_Create(IWeb_FileGen_t *gen)
{
vfsgen_t *ret;
ret = Z_Malloc(sizeof(vfsgen_t));

View file

@ -5,7 +5,7 @@ void EditFile(char *name, int line);
void GUI_SetDefaultOpts(void);
int GUI_BuildParms(char *args, char **argv);
unsigned char *QCC_ReadFile (const char *fname, void *buffer, int len);
unsigned char *PDECL QCC_ReadFile (const char *fname, void *buffer, int len, size_t *sz);
int QCC_FileSize (const char *fname);
pbool QCC_WriteFile (const char *name, void *data, int len);
void GUI_DialogPrint(char *title, char *text);

View file

@ -226,7 +226,7 @@ static pbool QCC_RegSetValue(HKEY base, char *keyname, char *valuename, int type
LoadFile
==============
*/
unsigned char *PDECL QCC_ReadFile (const char *fname, void *buffer, int len)
unsigned char *PDECL QCC_ReadFile (const char *fname, void *buffer, int len, size_t *sz)
{
long length;
FILE *f;
@ -239,6 +239,8 @@ unsigned char *PDECL QCC_ReadFile (const char *fname, void *buffer, int len)
if (length != len)
return NULL;
if (sz)
*sz = length;
return buffer;
}
int PDECL QCC_FileSize (const char *fname)
@ -470,9 +472,9 @@ void GUIPrint(HWND wnd, char *msg);
char finddef[256];
char greptext[256];
char enginebinary[MAX_PATH];
char enginebasedir[MAX_PATH];
char enginecommandline[8192];
extern char enginebinary[MAX_PATH];
extern char enginebasedir[MAX_PATH];
extern char enginecommandline[8192];
void RunCompiler(char *args);
void RunEngine(void);
@ -1640,7 +1642,7 @@ void EditorReload(editor_t *editor)
{
file = malloc(flen+1);
QCC_ReadFile(editor->filename, file, flen);
QCC_ReadFile(editor->filename, file, flen, NULL);
file[flen] = 0;
}
@ -1868,7 +1870,7 @@ void EditorsRun(void)
}
char *GUIReadFile(const char *fname, void *buffer, int blen)
char *GUIReadFile(const char *fname, void *buffer, int blen, size_t *sz)
{
editor_t *e;
for (e = editors; e; e = e->next)
@ -1908,7 +1910,7 @@ char *GUIReadFile(const char *fname, void *buffer, int blen)
}
}
return QCC_ReadFile(fname, buffer, blen);
return QCC_ReadFile(fname, buffer, blen, NULL);
}
int GUIFileSize(const char *fname)

View file

@ -13,6 +13,9 @@ pbool fl_log;
char parameters[16384];
char progssrcname[256];
char progssrcdir[256];
char enginebinary[MAX_PATH];
char enginebasedir[MAX_PATH];
char enginecommandline[8192];
int qccpersisthunk = 1;
int Grep(char *filename, char *string)
@ -29,7 +32,7 @@ int Grep(char *filename, char *string)
return foundcount;
buf = malloc(sz+1);
buf[sz] = 0;
QCC_ReadFile(filename, buf, sz);
QCC_ReadFile(filename, buf, sz, NULL);
linestart = last = found = buf;
while ((found = strstr(found, string)))
@ -248,6 +251,27 @@ void GUI_ParseCommandLine(char *args)
{
fl_log = true;
}
else if (!strnicmp(parameters+paramlen, "-engine", 7) || !strnicmp(parameters+paramlen, "/engine", 7))
{
while (*next == ' ')
next++;
l = 0;
while (*next != ' ' && *next)
enginebinary[l++] = *next++;
enginebinary[l] = 0;
}
else if (!strnicmp(parameters+paramlen, "-basedir", 8) || !strnicmp(parameters+paramlen, "/basedir", 8))
{
while (*next == ' ')
next++;
l = 0;
while (*next != ' ' && *next)
enginebasedir[l++] = *next++;
enginebasedir[l] = 0;
}
//strcpy(enginecommandline, "-window +map start -nohome");
else if (!strnicmp(parameters+paramlen, "-srcfile", 8) || !strnicmp(parameters+paramlen, "/srcfile", 8))
{
while (*next == ' ')
@ -258,6 +282,16 @@ void GUI_ParseCommandLine(char *args)
progssrcname[l++] = *next++;
progssrcname[l] = 0;
}
else if (!strnicmp(parameters+paramlen, "-src ", 5) || !strnicmp(parameters+paramlen, "/src ", 5))
{
while (*next == ' ')
next++;
l = 0;
while (*next != ' ' && *next)
progssrcdir[l++] = *next++;
progssrcdir[l] = 0;
}
else if (!strnicmp(parameters+paramlen, "-T", 2) || !strnicmp(parameters+paramlen, "/T", 2)) //the target
{
if (!strnicmp(parameters+paramlen+2, "h2", 2))

View file

@ -6497,28 +6497,28 @@ static void QCBUILTIN PF_vectorvectors (pubprogfuncs_t *prinst, struct globalvar
//executes a command string as if it came from the specified client
static void QCBUILTIN PF_clientcommand (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
client_t *temp_client;
client_t *oldhostclient = host_client;
edict_t *oldsvplayer = sv_player;
int i;
//find client for this entity
i = NUM_FOR_EDICT(prinst, G_EDICT(prinst, OFS_PARM0)) - 1;
if (i < 0 || i >= sv.allocated_client_slots)
{
PR_BIError(prinst, "PF_clientcommand: entity is not a client");
return;
else
{
host_client = &svs.clients[i];
sv_player = host_client->edict;
if (host_client->state == cs_connected || host_client->state == cs_spawned)
{
SV_ExecuteUserCommand (PF_VarString(prinst, 1, pr_globals), true);
}
else
Con_Printf("PF_clientcommand: client is not active\n");
}
temp_client = host_client;
host_client = &svs.clients[i];
if (host_client->state == cs_connected || host_client->state == cs_spawned)
{
SV_ExecuteUserCommand (PF_VarString(prinst, 1, pr_globals), true);
}
else
Con_Printf("PF_clientcommand: client is not active\n");
host_client = temp_client;
if (host_client)
sv_player = host_client->edict;
host_client = oldhostclient;
sv_player = oldsvplayer;
}

View file

@ -21,8 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define QW_SERVER
#define MAX_MASTERS 8 // max recipients for heartbeat packets
#define MAX_SIGNON_BUFFERS 16
typedef enum {
@ -942,7 +940,9 @@ extern cvar_t sv_maxspeed;
extern cvar_t sv_antilag;
extern cvar_t sv_antilag_frac;
extern netadr_t master_adr[MAX_MASTERS]; // address of the master server
void SV_Master_ReResolve(void);
void SV_Master_Shutdown(void);
void SV_Master_Heartbeat (void);
extern cvar_t pr_ssqc_progs;
extern cvar_t spawn;
@ -1008,10 +1008,6 @@ void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose);
void SV_SaveInfos(vfsfile_t *f);
void Master_Heartbeat (void);
void Master_Packet (void);
void SV_FixupName(char *in, char *out, unsigned int outlen);
#ifdef SUBSERVERS

View file

@ -124,39 +124,6 @@ These commands can only be entered from stdin or by a remote operator datagram
===============================================================================
*/
/*
====================
SV_SetMaster_f
Make a master server current
====================
*/
void Master_ClearAll(void);
void Master_ReResolve(void);
void Master_Add(char *stringadr);
static void SV_SetMaster_f (void)
{
int i;
Cvar_Set(&sv_public, "1"); //go public.
Master_ClearAll();
if (!strcmp(Cmd_Argv(1), "none"))
{
Con_Printf ("Entering no-master mode\n");
return;
}
for (i=1 ; i<Cmd_Argc() ; i++)
{
Master_Add(Cmd_Argv(i));
}
svs.last_heartbeat = -99999;
}
/*
==================
SV_Quit_f
@ -1956,8 +1923,7 @@ SV_Heartbeat_f
*/
static void SV_Heartbeat_f (void)
{
Master_ReResolve();
svs.last_heartbeat = -9999;
SV_Master_ReResolve();
}
#define FOREACHCLIENT(i,cl) \
@ -2666,7 +2632,6 @@ void SV_InitOperatorCommands (void)
Cmd_AddCommand ("changelevel", SV_Map_f);
Cmd_AddCommand ("listmaps", SV_MapList_f);
Cmd_AddCommand ("maplist", SV_MapList_f);
Cmd_AddCommand ("setmaster", SV_SetMaster_f);
Cmd_AddCommand ("heartbeat", SV_Heartbeat_f);

View file

@ -39,46 +39,12 @@ int host_hunklevel;
#endif
// callbacks
void SV_Masterlist_Callback(struct cvar_s *var, char *oldvalue);
void SV_Tcpport_Callback(struct cvar_s *var, char *oldvalue);
void SV_Tcpport6_Callback(struct cvar_s *var, char *oldvalue);
void SV_Port_Callback(struct cvar_s *var, char *oldvalue);
void SV_PortIPv6_Callback(struct cvar_s *var, char *oldvalue);
void SV_PortIPX_Callback(struct cvar_s *var, char *oldvalue);
typedef struct {
enum {
MP_NONE,
MP_QUAKEWORLD,
MP_DARKPLACES,
} protocol;
cvar_t cv;
qboolean needsresolve; //set any time the cvar is modified
netadr_t adr;
} sv_masterlist_t;
sv_masterlist_t sv_masterlist[] = {
{MP_QUAKEWORLD, CVARC("sv_master1", "", SV_Masterlist_Callback)},
{MP_QUAKEWORLD, CVARC("sv_master2", "", SV_Masterlist_Callback)},
{MP_QUAKEWORLD, CVARC("sv_master3", "", SV_Masterlist_Callback)},
{MP_QUAKEWORLD, CVARC("sv_master4", "", SV_Masterlist_Callback)},
{MP_QUAKEWORLD, CVARC("sv_master5", "", SV_Masterlist_Callback)},
{MP_QUAKEWORLD, CVARC("sv_master6", "", SV_Masterlist_Callback)},
{MP_QUAKEWORLD, CVARC("sv_master7", "", SV_Masterlist_Callback)},
{MP_QUAKEWORLD, CVARC("sv_master8", "", SV_Masterlist_Callback)},
{MP_QUAKEWORLD, CVARC("sv_qwmasterextra1", "qwmaster.ocrana.de:27000", SV_Masterlist_Callback)}, //german. admin unknown
{MP_QUAKEWORLD, CVARC("sv_qwmasterextra2", ""/*"masterserver.exhale.de:27000" seems dead*/, SV_Masterlist_Callback)}, //german. admin unknown
{MP_QUAKEWORLD, CVARC("sv_qwmasterextra3", "asgaard.morphos-team.net:27000", SV_Masterlist_Callback)}, //germany. admin bigfoot
{MP_QUAKEWORLD, CVARC("sv_qwmasterextra4", "master.quakeservers.net:27000", SV_Masterlist_Callback)}, //european. admin: raz0?
{MP_QUAKEWORLD, CVARC("sv_qwmasterextra5", "qwmaster.fodquake.net:27000", SV_Masterlist_Callback)},
{MP_DARKPLACES, CVARC("sv_masterextra1", "ghdigital.com:27950", SV_Masterlist_Callback)}, //69.59.212.88 (admin: LordHavoc)
{MP_DARKPLACES, CVARC("sv_masterextra2", "dpmaster.deathmask.net:27950", SV_Masterlist_Callback)}, //209.164.24.243 (admin: Willis)
{MP_DARKPLACES, CVARC("sv_masterextra3", "dpmaster.tchr.no:27950", SV_Masterlist_Callback)}, // (admin: tChr)
{MP_NONE, CVAR(NULL, NULL)}
};
client_t *host_client; // current client
// bound the size of the physics time tic
@ -213,7 +179,6 @@ vfsfile_t *sv_fraglogfile;
void SV_FixupName(char *in, char *out, unsigned int outlen);
void SV_AcceptClient (netadr_t *adr, int userid, char *userinfo);
void Master_Shutdown (void);
void PRH2_SetPlayerClass(client_t *cl, int classnum, qboolean fromqc);
char *SV_BannedReason (netadr_t *a);
void SV_EvaluatePenalties(client_t *cl);
@ -240,7 +205,7 @@ Quake calls this before calling Sys_Quit or Sys_Error
*/
void SV_Shutdown (void)
{
Master_Shutdown ();
SV_Master_Shutdown ();
if (sv_fraglogfile)
{
VFS_CLOSE (sv_fraglogfile);
@ -1178,11 +1143,12 @@ void SVC_GetInfo (char *challenge, int fullstatus)
//first line is the serverinfo
Q_strncpyz(resp, svs.info, sizeof(response) - (resp-response));
//this is a DP protocol query, so some QW fields are not needed
Info_RemoveKey(resp, "maxclients");
Info_RemoveKey(resp, "map");
Info_RemoveKey(resp, "maxclients"); //replaced with sv_maxclients
Info_RemoveKey(resp, "map"); //replaced with mapname
Info_SetValueForKey(resp, "gamename", com_protocolname.string, sizeof(response) - (resp-response));
Info_SetValueForKey(resp, "modname", com_modname.string, sizeof(response) - (resp-response));
Info_SetValueForKey(resp, "protocol", va("%d", NET_PROTOCOL_VERSION), sizeof(response) - (resp-response));
Info_SetValueForKey(resp, "modname", FS_GetGamedir(true), sizeof(response) - (resp-response));
// Info_SetValueForKey(resp, "gamedir", FS_GetGamedir(true), sizeof(response) - (resp-response));
Info_SetValueForKey(resp, "protocol", va("%d", NQ_NETCHAN_VERSION), sizeof(response) - (resp-response));
Info_SetValueForKey(resp, "clients", va("%d", numclients), sizeof(response) - (resp-response));
Info_SetValueForKey(resp, "sv_maxclients", maxclients.string, sizeof(response) - (resp-response));
Info_SetValueForKey(resp, "mapname", Info_ValueForKey(svs.info, "map"), sizeof(response) - (resp-response));
@ -3297,7 +3263,7 @@ qboolean SVNQ_ConnectionlessPacket(void)
client_t *newcl;
Cmd_TokenizeString(MSG_ReadStringLine(), false, false);
/*okay, so this is a reliable packet from a client, containing a 'cmd challengeconnect $challenge' response*/
str = va("connect %i %i %s \"\\name\\unconnected\\mod\\%s\\modver\\%s\\flags\\%s\\password\\%s\"", NET_PROTOCOL_VERSION, 0, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3), Cmd_Argv(4), Cmd_Argv(5));
str = va("connect %i %i %s \"\\name\\unconnected\\mod\\%s\\modver\\%s\\flags\\%s\\password\\%s\"", NQ_NETCHAN_VERSION, 0, Cmd_Argv(1), Cmd_Argv(2), Cmd_Argv(3), Cmd_Argv(4), Cmd_Argv(5));
Cmd_TokenizeString (str, false, false);
newcl = SVC_DirectConnect();
@ -3361,7 +3327,7 @@ qboolean SVNQ_ConnectionlessPacket(void)
case CCREQ_CONNECT:
sb.maxsize = sizeof(buffer);
sb.data = buffer;
if (strcmp(MSG_ReadString(), NET_GAMENAME_NQ))
if (strcmp(MSG_ReadString(), NQ_NETCHAN_GAMENAME))
{
SZ_Clear(&sb);
MSG_WriteLong(&sb, 0);
@ -3371,7 +3337,7 @@ qboolean SVNQ_ConnectionlessPacket(void)
NET_SendPacket(NS_SERVER, sb.cursize, sb.data, &net_from);
return false; //not our game.
}
if (MSG_ReadByte() != NET_PROTOCOL_VERSION)
if (MSG_ReadByte() != NQ_NETCHAN_VERSION)
{
SZ_Clear(&sb);
MSG_WriteLong(&sb, 0);
@ -3433,7 +3399,7 @@ qboolean SVNQ_ConnectionlessPacket(void)
}
else
{
str = va("connect %i %i %i \"\\name\\unconnected\\mod\\%i\\modver\\%i\\flags\\%i\\password\\%i\"", NET_PROTOCOL_VERSION, 0, SV_NewChallenge(), mod, modver, flags, passwd);
str = va("connect %i %i %i \"\\name\\unconnected\\mod\\%i\\modver\\%i\\flags\\%i\\password\\%i\"", NQ_NETCHAN_VERSION, 0, SV_NewChallenge(), mod, modver, flags, passwd);
Cmd_TokenizeString (str, false, false);
SVC_DirectConnect();
@ -3443,7 +3409,7 @@ qboolean SVNQ_ConnectionlessPacket(void)
case CCREQ_SERVER_INFO:
if (SV_BannedReason (&net_from))
return false;
if (Q_strcmp (MSG_ReadString(), NET_GAMENAME_NQ) != 0)
if (Q_strcmp (MSG_ReadString(), NQ_NETCHAN_GAMENAME) != 0)
return false;
sb.maxsize = sizeof(buffer);
@ -3464,7 +3430,7 @@ qboolean SVNQ_ConnectionlessPacket(void)
MSG_WriteString (&sb, sv.name);
MSG_WriteByte (&sb, active);
MSG_WriteByte (&sb, maxclients.value);
MSG_WriteByte (&sb, NET_PROTOCOL_VERSION);
MSG_WriteByte (&sb, NQ_NETCHAN_VERSION);
*(int*)sb.data = BigLong(NETFLAG_CTL+sb.cursize);
NET_SendPacket(NS_SERVER, sb.cursize, sb.data, &net_from);
return true;
@ -4358,7 +4324,7 @@ void SV_MVDStream_Poll(void);
// svs.stats.demo += demo_end - demo_start;
// send a heartbeat to the master if needed
Master_Heartbeat ();
SV_Master_Heartbeat ();
#ifdef Q2SERVER
@ -4577,226 +4543,6 @@ void SV_InitLocal (void)
svs.free_lagged_packet = NULL;
}
//============================================================================
void SV_Masterlist_Callback(struct cvar_s *var, char *oldvalue)
{
int i;
for (i = 0; sv_masterlist[i].cv.name; i++)
{
if (var == &sv_masterlist[i].cv)
break;
}
if (!sv_masterlist[i].cv.name)
return;
if (!*var->string)
{
sv_masterlist[i].adr.port = 0;
return;
}
sv_masterlist[i].needsresolve = true;
}
/*
================
Master_Heartbeat
Send a message to the master every few minutes to
let it know we are alive, and log information
================
*/
#define HEARTBEAT_SECONDS 300
void Master_Heartbeat (void)
{
char string[2048];
int active;
int i, j;
qboolean madeqwstring = false;
char adr[MAX_ADR_SIZE];
if (!sv_public.ival || SSV_IsSubServer())
return;
if (realtime-HEARTBEAT_SECONDS - svs.last_heartbeat < HEARTBEAT_SECONDS)
return; // not time to send yet
svs.last_heartbeat = realtime-HEARTBEAT_SECONDS;
svs.heartbeat_sequence++;
// send to group master
for (i = 0; sv_masterlist[i].cv.name; i++)
{
if (sv_masterlist[i].needsresolve)
{
sv_masterlist[i].needsresolve = false;
if (!*sv_masterlist[i].cv.string)
sv_masterlist[i].adr.port = 0;
else if (!NET_StringToAdr(sv_masterlist[i].cv.string, 0, &sv_masterlist[i].adr))
{
sv_masterlist[i].adr.port = 0;
Con_TPrintf ("Couldn't resolve master \"%s\"\n", sv_masterlist[i].cv.string);
}
else
{
if (sv_masterlist[i].adr.type == NA_TCP || sv_masterlist[i].adr.type == NA_TCPV6 || sv_masterlist[i].adr.type == NA_TLSV4 || sv_masterlist[i].adr.type == NA_TLSV6)
NET_EnsureRoute(svs.sockets, sv_masterlist[i].cv.name, sv_masterlist[i].cv.string, false);
//choose default port
switch (sv_masterlist[i].protocol)
{
case MP_DARKPLACES:
if (sv_masterlist[i].adr.port == 0)
sv_masterlist[i].adr.port = BigShort (27950);
break;
case MP_QUAKEWORLD:
if (sv_masterlist[i].adr.port == 0)
sv_masterlist[i].adr.port = BigShort (27000);
//qw does this for some reason, keep the behaviour even though its unreliable thus pointless
string[0] = A2A_PING;
string[1] = 0;
if (sv.state)
NET_SendPacket (NS_SERVER, 2, string, &sv_masterlist[i].adr);
break;
default:
break;
}
}
}
if (sv_masterlist[i].adr.port)
{
switch(sv_masterlist[i].protocol)
{
case MP_QUAKEWORLD:
if (sv_listen_qw.value)
{
if (!madeqwstring)
{
// count active users
active = 0;
for (j=0 ; j<svs.allocated_client_slots ; j++)
if (svs.clients[j].state == cs_connected ||
svs.clients[j].state == cs_spawned )
active++;
sprintf (string, "%c\n%i\n%i\n", S2M_HEARTBEAT,
svs.heartbeat_sequence, active);
madeqwstring = true;
}
if (sv_reportheartbeats.value)
Con_TPrintf ("Sending heartbeat to %s (%s)\n", NET_AdrToString (adr, sizeof(adr), &sv_masterlist[i].adr), sv_masterlist[i].cv.string);
NET_SendPacket (NS_SERVER, strlen(string), string, &sv_masterlist[i].adr);
}
break;
case MP_DARKPLACES:
if (sv_listen_dp.value || sv_listen_nq.value) //set listen to 1 to allow qw connections, 2 to allow nq connections too.
{
if (sv_reportheartbeats.value)
Con_TPrintf ("Sending heartbeat to %s (%s)\n", NET_AdrToString (adr, sizeof(adr), &sv_masterlist[i].adr), sv_masterlist[i].cv.string);
{
char *str = "\377\377\377\377heartbeat DarkPlaces\x0A";
NET_SendPacket (NS_SERVER, strlen(str), str, &sv_masterlist[i].adr);
}
}
break;
default:
break;
}
}
}
}
void Master_Add(char *stringadr)
{
int i;
for (i = 0; sv_masterlist[i].cv.name; i++)
{
if (!*sv_masterlist[i].cv.string)
break;
}
if (!sv_masterlist[i].cv.name)
{
Con_Printf ("Too many masters\n");
return;
}
Cvar_Set(&sv_masterlist[i].cv, stringadr);
svs.last_heartbeat = -99999;
}
void Master_ReResolve(void)
{
int i;
for (i = 0; sv_masterlist[i].cv.name; i++)
{
sv_masterlist[i].needsresolve = true;
}
}
void Master_ClearAll(void)
{
int i;
for (i = 0; sv_masterlist[i].cv.name; i++)
{
Cvar_Set(&sv_masterlist[i].cv, "");
}
}
/*
=================
Master_Shutdown
Informs all masters that this server is going down
=================
*/
void Master_Shutdown (void)
{
char string[2048];
char adr[MAX_ADR_SIZE];
int i;
//note that if a master server actually blindly listens to this then its exploitable.
//we send it out anyway as for us its all good.
//master servers ought to try and check up on the status of the server first, if they listen to this.
sprintf (string, "%c\n", S2M_SHUTDOWN);
// send to group master
for (i = 0; sv_masterlist[i].cv.name; i++)
{
if (sv_masterlist[i].adr.port)
{
switch(sv_masterlist[i].protocol)
{
case MP_QUAKEWORLD:
if (sv_reportheartbeats.value)
Con_TPrintf ("Sending shutdown to %s\n", NET_AdrToString (adr, sizeof(adr), &sv_masterlist[i].adr));
NET_SendPacket (NS_SERVER, strlen(string), string, &sv_masterlist[i].adr);
break;
//dp has no shutdown
default:
break;
}
}
}
}
#define iswhite(c) ((c) == ' ' || (unsigned char)(c) == (unsigned char)INVIS_CHAR1 || (unsigned char)(c) == (unsigned char)INVIS_CHAR2 || (unsigned char)(c) == (unsigned char)INVIS_CHAR3)
#define isinvalid(c) ((c) == ':' || (c) == '\r' || (c) == '\n' || (unsigned char)(c) == (unsigned char)0xff)
//colon is so clients can't get confused while parsing chats
@ -5091,8 +4837,6 @@ SV_InitNet
*/
void SV_InitNet (void)
{
int i;
#ifndef SERVERONLY
if (isDedicated)
#endif
@ -5100,12 +4844,8 @@ void SV_InitNet (void)
Netchan_Init ();
}
for (i = 0; sv_masterlist[i].cv.name; i++)
Cvar_Register(&sv_masterlist[i].cv, "master servers");
Master_ReResolve();
SV_Master_ReResolve();
// heartbeats will always be sent to the id master
svs.last_heartbeat = -99999; // send immediately
// NET_StringToAdr ("192.246.40.70:27000", &idmaster_adr);
}
@ -5123,8 +4863,10 @@ void SV_ExecInitialConfigs(char *defaultexec)
{
if (COM_FileSize("server.cfg") != -1)
Cbuf_InsertText ("exec server.cfg\nexec ftesrv.cfg\n", RESTRICT_LOCAL, false);
else
else if (COM_FileSize("quake.rc") != -1)
Cbuf_InsertText ("cl_warncmd 0\nexec quake.rc\ncl_warncmd 1\nexec ftesrv.cfg\n", RESTRICT_LOCAL, false);
else
Cbuf_InsertText ("cl_warncmd 0\nexec default.cfg\ncl_warncmd 1\nexec ftesrv.cfg\n", RESTRICT_LOCAL, false);
// process command line arguments
Cbuf_Execute ();

View file

@ -1683,8 +1683,9 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest)
{
sizebuf_t buf;
char buf_data[MAX_QWMSGLEN];
int n, i, j;
const char *s;
int i, j;
// int n;
// const char *s;
client_t *player;
char *gamedir;

View file

@ -79,8 +79,8 @@
#define CCREP_REJECT 0x82
#define CCREP_SERVER_INFO 0x83
#define NET_GAMENAME_NQ "QUAKE"
#define NET_PROTOCOL_VERSION 3
#define NQ_NETCHAN_GAMENAME "QUAKE"
#define NQ_NETCHAN_VERSION 3
//end NQ specific

View file

@ -4202,7 +4202,7 @@ void QW_ProcessUDPPacket(cluster_t *cluster, netmsg_t *m, netadr_t from)
{
case CCREQ_SERVER_INFO:
ReadString(m, tempbuffer, sizeof(tempbuffer));
if (!strcmp(tempbuffer, NET_GAMENAME_NQ))
if (!strcmp(tempbuffer, NQ_NETCHAN_GAMENAME))
{
m->cursize = 0;
WriteLong(m, 0);
@ -4212,16 +4212,16 @@ void QW_ProcessUDPPacket(cluster_t *cluster, netmsg_t *m, netadr_t from)
WriteString(m, "Quake TV");
WriteByte(m, cluster->numviewers>255?255:cluster->numviewers);
WriteByte(m, cluster->maxviewers>255?255:cluster->maxviewers);
WriteByte(m, NET_PROTOCOL_VERSION);
WriteByte(m, NQ_NETCHAN_VERSION);
*(int*)m->data = BigLong(NETFLAG_CTL | m->cursize);
NET_SendPacket(cluster, NET_ChooseSocket(cluster->qwdsocket, &from), m->cursize, m->data, from);
}
break;
case CCREQ_CONNECT:
ReadString(m, tempbuffer, sizeof(tempbuffer));
if (!strcmp(tempbuffer, NET_GAMENAME_NQ))
if (!strcmp(tempbuffer, NQ_NETCHAN_GAMENAME))
{
if (ReadByte(m) == NET_PROTOCOL_VERSION)
if (ReadByte(m) == NQ_NETCHAN_VERSION)
{
//proquake extensions
int mod = ReadByte(m);