implement status command for nq clients that expect something to be printed. IP addresses are withheld.

fix stats issue.
support menuqc-based loading screens.
fixed 2d render-to-texture issues.
(finally) throttle 'connection lost or aborted' messages. report the ip address too, because we can.
begun work on nq-style player ip-logging. ip addresses are collected now, but there's still no actual database code yet.
rewrote engine auto-update. now part of the updates menu instead of system-specific special-case code. Still requires a system function to actually invoke the updated engine however.
added sdl audio capture support (requires sdl 2.0.5).
treat q_version like f_version etc. respond to both.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5046 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2017-01-24 10:27:39 +00:00
parent 9055d674eb
commit c68cbfec24
36 changed files with 855 additions and 631 deletions

View file

@ -11508,6 +11508,7 @@ void PR_DumpPlatform_f(void)
{"m_init", "void()", MENU},
{"m_shutdown", "void()", MENU},
{"m_draw", "void(vector screensize)", MENU, "Provides the menuqc with a chance to draw. Will be called even if the menu does not have focus, so be sure to avoid that. COMPAT: screensize is not provided in DP."},
{"m_drawloading", "void(vector screensize)", MENU, "Additional drawing function to draw loading screen overlays."},
{"m_keydown", "void(float scan, float chr)", MENU},
{"m_keyup", "void(float scan, float chr)", MENU},
{"m_toggle", "void(float wantmode)", MENU},

View file

@ -1765,6 +1765,14 @@ static void SV_Status_f (void)
int columns = 80;
extern cvar_t sv_listen_qw, sv_listen_nq, sv_listen_dp, sv_listen_q3;
#ifndef SERVERONLY
if (!sv.state && cls.state >= ca_connected && !cls.demoplayback && cls.protocol == CP_NETQUAKE)
{ //nq can normally forward the request to the server.
Cmd_ForwardToServer();
return;
}
#endif
if (sv_redirected != RD_OBLIVION && (sv_redirected != RD_NONE
#ifndef SERVERONLY
|| (vid.width < 68*8 && qrenderer != QR_NONE)

View file

@ -1537,7 +1537,7 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
MSG_WriteByte (msg, svcfte_updateentities);
if (ISNQCLIENT(client) && (client->fteprotocolextensions2 & PEXT2_PREDINFO))
{
MSG_WriteShort(msg, client->last_sequence);
MSG_WriteShort(msg, client->last_sequence&0xffff);
}
// Con_Printf("Gen sequence %i\n", sequence);
MSG_WriteFloat(msg, sv.world.physicstime);

View file

@ -2199,6 +2199,8 @@ client_t *SVC_DirectConnect(void)
{
{"FITZ", 1u<<SCP_FITZ666}, //dp doesn't support this, but this is for potential compat if other engines use this handshake
{"666", 1u<<SCP_FITZ666}, //dp doesn't support this, but this is for potential compat if other engines use this handshake
{"RMQ", 1u<<SCP_FITZ666}, //fte doesn't distinguish, but assumes clients will support both
{"999", 1u<<SCP_FITZ666}, //fte doesn't distinguish, but assumes clients will support both
{"DP7", 1u<<SCP_DARKPLACES7},
{"DP6", 1u<<SCP_DARKPLACES6},
{"DP5", 0},
@ -2206,10 +2208,10 @@ client_t *SVC_DirectConnect(void)
{"DP3", 0},
{"DP2", 0},
{"DP1", 0},
{"QW", 0}, //mixing protocols doesn't make sense, and would just confuse the client.
{"QUAKEDP", 1u<<SCP_NETQUAKE},
{"QUAKE", 1u<<SCP_NETQUAKE},
{"QW", 0}, //mixing protocols doesn't make sense, and would just confuse the client.
{"NEHAHRAMOVIE", 0},
{"NEHAHRAMOVIE", 1u<<SCP_NETQUAKE},
{"NEHAHRABJP", 0},
{"NEHAHRABJP2", 0},
{"NEHAHRABJP3", 1u<<SCP_BJP3},
@ -3108,6 +3110,9 @@ client_t *SVC_DirectConnect(void)
SSV_SavePlayerStats(newcl, 0);
#endif
if (Q_strncasecmp(newcl->name, "unconnected", 11) && Q_strncasecmp(newcl->name, "connecting", 10))
IPLog_Add(NET_AdrToString(adrbuf,sizeof(adrbuf), &newcl->netchan.remote_address), newcl->name);
return newcl;
}

View file

@ -2484,10 +2484,11 @@ qboolean SV_SendClientDatagram (client_t *client)
qbyte buf[MAX_OVERALLMSGLEN];
sizebuf_t msg;
unsigned int sentbytes;
unsigned int outframeseq = client->netchan.incoming_sequence; //this is so weird... but at least covers nq/qw sequence vs unreliables weirdness...
if (ISQWCLIENT(client) || ISNQCLIENT(client))
{
client_frame_t *frame = &client->frameunion.frames[client->netchan.outgoing_sequence & UPDATE_MASK];
client_frame_t *frame = &client->frameunion.frames[outframeseq & UPDATE_MASK];
frame->numresendstats = 0;
}
@ -2522,11 +2523,11 @@ qboolean SV_SendClientDatagram (client_t *client)
#endif
{
if (!ISQ2CLIENT(client) && Netchan_CanReliable (&client->netchan, SV_RateForClient(client)))
if (!ISQ2CLIENT(client) && ((client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) || Netchan_CanReliable (&client->netchan, SV_RateForClient(client))))
{
int pnum=1;
client_t *c;
client_frame_t *frame = &client->frameunion.frames[client->netchan.outgoing_sequence & UPDATE_MASK];
client_frame_t *frame = &client->frameunion.frames[outframeseq & UPDATE_MASK];
SV_UpdateClientStats (client, 0, &msg, frame);
for (c = client->controlled; c; c = c->controlled,pnum++)

View file

@ -635,6 +635,10 @@ void SVNQ_New_f (void)
if (!gamedir[0])
{
gamedir = FS_GetGamedir(true);
#ifndef NOLEGACY
if (!strcmp(gamedir, "qw")) //hack: hide the qw dir from nq clients.
gamedir = "";
#endif
}
COM_FileBase(sv.modelname, mapname, sizeof(mapname));
@ -5170,7 +5174,7 @@ void SV_CalcNetRates(client_t *cl, double *ftime, int *frames, double *minf, dou
}
}
void Cmd_FPSList_f(void)
static void Cmd_FPSList_f(void)
{
client_t *cl;
int c;
@ -5233,7 +5237,7 @@ static void SV_STFU_f(void)
}
#ifdef NQPROT
void SVNQ_Spawn_f (void)
static void SVNQ_Spawn_f (void)
{
extern cvar_t sv_gravity;
int i;
@ -5331,7 +5335,7 @@ void SVNQ_Spawn_f (void)
host_client->send_message = true;
}
void SVNQ_Begin_f (void)
static void SVNQ_Begin_f (void)
{
unsigned pmodel = 0, emodel = 0;
int i;
@ -5460,7 +5464,7 @@ void SVNQ_Begin_f (void)
SV_RunCmd (&host_client->lastcmd, false);
SV_PostRunCmd();
}
void SVNQ_PreSpawn_f (void)
static void SVNQ_PreSpawn_f (void)
{
if (host_client->prespawn_stage < PRESPAWN_MAPCHECK)
SV_StuffcmdToClient(host_client, va("cmd prespawn %s\n", Cmd_Args()));
@ -5499,13 +5503,13 @@ void SVNQ_PreSpawn_f (void)
host_client->send_message = true;
}
void SVNQ_NQInfo_f (void)
static void SVNQ_NQInfo_f (void)
{
Cmd_TokenizeString(va("setinfo \"%s\" \"%s\"\n", Cmd_Argv(0), Cmd_Argv(1)), false, false);
SV_SetInfo_f();
}
void SVNQ_NQColour_f (void)
static void SVNQ_NQColour_f (void)
{
char *val;
int top;
@ -5576,7 +5580,7 @@ void SVNQ_NQColour_f (void)
SV_ExtractFromUserinfo (host_client, true);
}
void SVNQ_Ping_f(void)
static void SVNQ_Ping_f(void)
{
int i;
client_t *cl;
@ -5592,8 +5596,54 @@ void SVNQ_Ping_f(void)
SV_PrintToClient(host_client, PRINT_HIGH, va("%3i %s\n", SV_CalcPing (cl, false), cl->name));
}
}
static void SVNQ_Status_f(void)
{ //note: numerous NQ clients poll for this...
//so try to ensure that we adhere to various rules...
//we have a different function for server operators to use which contains more info.
int i;
client_t *cl;
int count;
extern cvar_t maxclients, maxspectators;
void SVNQ_Protocols_f(void)
/*
int nummodels, numsounds;
for (nummodels = 1; nummodels < MAX_PRECACHE_MODELS; nummodels++)
if (!sv.strings.model_precache[nummodels])
break;
for (numsounds = 1; numsounds < MAX_PRECACHE_SOUNDS; numsounds++)
if (!sv.strings.sound_precache[numsounds])
break;*/
SV_PrintToClient(host_client, PRINT_HIGH, va("host: %s\n", hostname.string)); //must be first, with same first 9 chars
SV_PrintToClient(host_client, PRINT_HIGH, va("version: %s\n", version_string()));
// SV_PrintToClient(host_client, PRINT_HIGH, va("IPv4: \n", ));
// SV_PrintToClient(host_client, PRINT_HIGH, va("IPv6: \n", ));
SV_PrintToClient(host_client, PRINT_HIGH, va("map: %s\n", svs.name));
/* for (count = 1; count < MAX_PRECACHE_MODELS; count++)
if (!sv.strings.model_precache[count])
break;
SV_PrintToClient(host_client, PRINT_HIGH, va("models: %i/%i\n", count-1, MAX_PRECACHE_MODELS-1));*/
/* for (count = 1; count < MAX_PRECACHE_SOUNDS; count++)
if (!sv.strings.sound_precache[count])
break;
SV_PrintToClient(host_client, PRINT_HIGH, va("sounds: %i/%i\n", count-1, MAX_PRECACHE_SOUNDS-1));*/
// SV_PrintToClient(host_client, PRINT_HIGH, va("entities:%i/%i\n", sv.world.num_edicts, sv.world.max_edicts));
for (count=0,i=0,cl=svs.clients ; i<sv.allocated_client_slots ; i++,cl++)
{
if (cl->state)
count++;
}
SV_PrintToClient(host_client, PRINT_HIGH, va("players: %i active (%i max)\n\n", count, min(maxclients.ival+maxspectators.ival,sv.allocated_client_slots)));//must be last
for (i=0,cl=svs.clients ; i<sv.allocated_client_slots ; i++,cl++)
{
if (!cl->state)
continue;
SV_PrintToClient(host_client, PRINT_HIGH, va("#%i\n", i+1));
SV_PrintToClient(host_client, PRINT_HIGH, va(" %s\n", "WITHHELD"));
}
}
static void SVNQ_Protocols_f(void)
{
int i;
host_client->supportedprotocols = 0;
@ -5841,7 +5891,7 @@ ucmd_t nqucmds[] =
{"begin", SVNQ_Begin_f, true},
{"prespawn", SVNQ_PreSpawn_f, true},
{"status", NULL},
{"status", SVNQ_Status_f},
{"god", Cmd_God_f},