routing is more obvious / usable now (beware some 'cmd cmd new's are required).

reworked the menus (could be a little better).
added qqshka's invisible player fix.
de-spammified the centerprint menus.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2483 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2007-03-18 05:07:10 +00:00
parent 24c2512499
commit 5845dc7e35
5 changed files with 1003 additions and 632 deletions

View file

@ -260,6 +260,56 @@ void Prox_SendPlayerStats(sv_t *qtv, oproxy_t *prox)
}
}
void Prox_SendInitialPlayers(sv_t *qtv, oproxy_t *prox, netmsg_t *msg)
{
int i, j, flags;
char buffer[64];
for (i = 0; i < MAX_CLIENTS; i++)
{
if (!qtv->players[i].active) // interesting, is this set to false if player disconnect from server?
continue;
flags = (DF_ORIGIN << 0) | (DF_ORIGIN << 1) | (DF_ORIGIN << 2)
| (DF_ANGLES << 0) | (DF_ANGLES << 1) | (DF_ANGLES << 2) // angles is something what changed frequently, so may be not send it?
| DF_EFFECTS
| DF_SKINNUM // though it rare thingie, so better send it?
| (qtv->players[i].dead ? DF_DEAD : 0)
| (qtv->players[i].gibbed ? DF_GIB : 0)
| DF_WEAPONFRAME // do we so really need it?
| DF_MODEL; // generally, that why we wrote this function, so YES send this
if (*qtv->players[i].userinfo && atoi(Info_ValueForKey(qtv->players[i].userinfo, "*spectator", buffer, sizeof(buffer))))
flags = DF_MODEL; // oh, that spec, just sent his model, may be even better ignore him?
WriteByte (msg, svc_playerinfo);
WriteByte (msg, i);
WriteShort (msg, flags);
WriteByte (msg, qtv->players[i].current.frame); // always sent
for (j = 0 ; j < 3 ; j++)
if (flags & (DF_ORIGIN << j))
WriteShort (msg, qtv->players[i].current.origin[j]);
for (j = 0 ; j < 3 ; j++)
if (flags & (DF_ANGLES << j))
WriteShort (msg, qtv->players[i].current.angles[j]);
if (flags & DF_MODEL) // generally, that why we wrote this function, so YES send this
WriteByte (msg, qtv->players[i].current.modelindex);
if (flags & DF_SKINNUM)
WriteByte (msg, qtv->players[i].current.skinnum);
if (flags & DF_EFFECTS)
WriteByte (msg, qtv->players[i].current.effects);
if (flags & DF_WEAPONFRAME)
WriteByte (msg, qtv->players[i].current.weaponframe);
}
}
void Net_SendConnectionMVD(sv_t *qtv, oproxy_t *prox)
{
char buffer[MAX_MSGLEN*8];
@ -301,7 +351,10 @@ void Net_SendConnectionMVD(sv_t *qtv, oproxy_t *prox)
msg.cursize = 0;
}
//playerstates arn't actually delta-compressed, so the first send (simply forwarded from server) entirly replaces the old.
//playerstates are delta-compressed, unfortunatly this isn't qwd (thanks to qqshka for showing my folly)
Prox_SendInitialPlayers(qtv, prox, &msg);
Prox_SendMessage(qtv->cluster, prox, msg.data, msg.cursize, dem_read, (unsigned)-1);
msg.cursize = 0;
//we do need to send entity states.
Prox_SendInitialEnts(qtv, prox, &msg);

View file

@ -163,15 +163,6 @@ void WriteData(netmsg_t *b, const char *data, int length)
b->cursize+=length;
}
#define DF_ORIGIN 1
#define DF_ANGLES (1<<3)
#define DF_EFFECTS (1<<6)
#define DF_SKINNUM (1<<7)
#define DF_DEAD (1<<8)
#define DF_GIB (1<<9)
#define DF_WEAPONFRAME (1<<10)
#define DF_MODEL (1<<11)
void SendBufferToViewer(viewer_t *v, const char *buffer, int length, qboolean reliable)
{
if (reliable)
@ -182,7 +173,13 @@ void SendBufferToViewer(viewer_t *v, const char *buffer, int length, qboolean re
else if (v->backbuffered>0 && v->backbuf[v->backbuffered-1].cursize+length < v->backbuf[v->backbuffered-1].maxsize) //try and put it in the current backbuffer
WriteData(&v->backbuf[v->backbuffered-1], buffer, length);
else if (v->backbuffered == MAX_BACK_BUFFERS)
{
v->netchan.message.cursize = 0;
WriteByte(&v->netchan.message, svc_print);
WriteString(&v->netchan.message, "backbuffer overflow\n");
Sys_Printf(NULL, "%s backbuffers overflowed\n", v->name); //FIXME
v->drop = true; //we would need too many backbuffers.
}
else
{
//create a new backbuffer
@ -225,7 +222,7 @@ void Multicast(sv_t *tv, char *buffer, int length, int to, unsigned int playerma
if (v->thinksitsconnected||suitablefor&CONNECTING)
if (v->server == tv)
if (suitablefor&(v->netchan.isnqprotocol?NQ:QW))
SendBufferToViewer(v, buffer, length, true); //FIXME: change the reliable depending on message type
SendBufferToViewer(v, buffer, length, true); //FIXME: change the reliable depending on message type
}
break;
}
@ -341,8 +338,20 @@ static void ParseStufftext(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
ReadString(m, text, sizeof(text));
// Sys_Printf(tv->cluster, "stuffcmd: %s", text);
if (strstr(text, "screenshot"))
return;
if (!strcmp(text, "say proxy:menu\n"))
{ //qizmo's 'previous proxy' message
tv->proxyisselected = true;
if (tv->controller)
QW_SetMenu(tv->controller, MENU_MAIN);
tv->serverisproxy = true; //FIXME: Detect this properly on qizmo
}
else if (!strncmp(text, "//set prox_inmenu ", 18))
{
if (tv->controller)
QW_SetMenu(tv->controller, atoi(text+18)?MENU_FORWARDING:MENU_NONE);
}
else if (strstr(text, "screenshot"))
return; //this was generating far too many screenshots when watching demos
else if (!strcmp(text, "skins\n"))
{
const char newcmd[10] = {svc_stufftext, 'c', 'm', 'd', ' ', 'n','e','w','\n','\0'};
@ -371,12 +380,14 @@ static void ParseStufftext(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
//copy over the server's serverinfo
strncpy(tv->serverinfo, text+16, sizeof(tv->serverinfo)-1);
Info_ValueForKey(tv->serverinfo, "*qtv", value, sizeof(value));
Info_ValueForKey(tv->serverinfo, "*QTV", value, sizeof(value));
if (*value)
fromproxy = true;
else
fromproxy = false;
tv->serverisproxy = fromproxy;
//add on our extra infos
Info_SetValueForStarKey(tv->serverinfo, "*qtv", VERSION, sizeof(tv->serverinfo));
Info_SetValueForStarKey(tv->serverinfo, "*z_ext", Z_EXT_STRING, sizeof(tv->serverinfo));
@ -512,10 +523,42 @@ static void ParsePrint(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
}
static void ParseCenterprint(sv_t *tv, netmsg_t *m, int to, unsigned int mask)
{
viewer_t *v;
char text[1024];
ReadString(m, text, sizeof(text));
Multicast(tv, m->data+m->startpos, m->readpos - m->startpos, to, mask, Q1);
switch(to)
{
case dem_multiple:
case dem_single:
case dem_stats:
//check and send to them only if they're tracking this player(s).
for (v = tv->cluster->viewers; v; v = v->next)
{
if (!v->menunum || v->menunum == MENU_FORWARDING)
if (v->thinksitsconnected)
if (v->server == tv)
if (v->trackplayer>=0)
if ((1<<v->trackplayer)&mask)
{
SendBufferToViewer(v, m->data+m->startpos, m->readpos - m->startpos, true); //FIXME: change the reliable depending on message type
}
}
break;
default:
//send to all
for (v = tv->cluster->viewers; v; v = v->next)
{
if (!v->menunum || v->menunum == MENU_FORWARDING)
if (v->thinksitsconnected)
if (v->server == tv)
SendBufferToViewer(v, m->data+m->startpos, m->readpos - m->startpos, true); //FIXME: change the reliable depending on message type
}
break;
}
}
static int ParseList(sv_t *tv, netmsg_t *m, filename_t *list, int to, unsigned int mask)
{

View file

@ -406,6 +406,7 @@ typedef struct viewer_s {
qboolean chokeme;
qboolean thinksitsconnected;
qboolean conmenussupported;
qboolean isproxy;
int delta_frame;
int servercount;
@ -440,6 +441,7 @@ typedef struct viewer_s {
sv_t *server;
int menuspamtime;
int menunum;
int menuop;
int fwdval; //for scrolling up/down the menu using +forward/+back :)
@ -512,6 +514,11 @@ struct sv_s { //details about a server connection (also known as stream)
netchan_t netchan;
qboolean serverquery;
//proxy chaining
qboolean serverisproxy;
qboolean proxyisselected;
//
unsigned char buffer[MAX_PROXY_BUFFER]; //this doesn't cycle.
int buffersize; //it memmoves down
int forwardpoint; //the point in the stream that we're forwarded up to.
@ -673,13 +680,30 @@ struct cluster_s {
};
#define MENU_NONE 0
#define MENU_SERVERS 1
#define MENU_ADMIN 2
#define MENU_ADMINSERVER 3
#define MENU_DEMOS 4
#define MENU_MAIN MENU_SERVERS
#define MENU_MAIN 1//MENU_SERVERS
#define MENU_SERVERS 2
#define MENU_CLIENTS 3
#define MENU_ADMIN 4
#define MENU_ADMINSERVER 5
#define MENU_DEMOS 6
#define MENU_FORWARDING 7
#define MENU_DEFAULT MENU_MAIN
enum {
MENU_MAIN_STREAMS,
MENU_MAIN_NEWSTREAM,
MENU_MAIN_FIXME,
MENU_MAIN_PREVPROX,
MENU_MAIN_CLIENTLIST,
MENU_MAIN_DEMOS,
MENU_MAIN_ADMIN,
MENU_MAIN_NEXTPROX,
MENU_MAIN_ITEMCOUNT
};
@ -840,6 +864,15 @@ unsigned int BigLong(unsigned int val);
#define PF_DEAD (1<<9) // don't block movement any more
#define PF_GIB (1<<10) // offset the view height differently
//flags on players in mvds
#define DF_ORIGIN 1
#define DF_ANGLES (1<<3)
#define DF_EFFECTS (1<<6)
#define DF_SKINNUM (1<<7)
#define DF_DEAD (1<<8)
#define DF_GIB (1<<9)
#define DF_WEAPONFRAME (1<<10)
#define DF_MODEL (1<<11)
//flags for where a message can be sent, for easy broadcasting

File diff suppressed because it is too large Load diff

View file

@ -1170,7 +1170,7 @@ void QTV_ParseQWStream(sv_t *qtv)
strcpy(qtv->status, "Attemping connection\n");
qtv->challenge = atoi(buffer+5);
if (qtv->controller)
sprintf(buffer, "connect %i %i %i \"%s\\*qtv\\1\"", 28, qtv->qport, qtv->challenge, qtv->controller->userinfo);
sprintf(buffer, "connect %i %i %i \"%s\\*qtv\\1\\Qizmo\\2.9 notimer\"", 28, qtv->qport, qtv->challenge, qtv->controller->userinfo);
else if (qtv->proxyplayer)
sprintf(buffer, "connect %i %i %i \"%s\\name\\%s\"", 28, qtv->qport, qtv->challenge, "\\*ver\\fteqtv\\spectator\\0\\rate\\10000", qtv->cluster->hostname);
else
@ -1194,7 +1194,7 @@ void QTV_ParseQWStream(sv_t *qtv)
qtv->isconnected = true;
qtv->timeout = qtv->curtime + UDPTIMEOUT_LENGTH;
SendClientCommand(qtv, "new\n");
SendClientCommand(qtv, "new");
Sys_Printf(qtv->cluster, "Connected!\n");
continue;
}
@ -1220,8 +1220,8 @@ void QTV_ParseQWStream(sv_t *qtv)
if (qtv->controller)
{
qtv->controller->maysend = true;
if (qtv->controller->netchan.outgoing_sequence != qtv->controller->netchan.incoming_sequence)
printf("bug is here\n");
//if (qtv->controller->netchan.outgoing_sequence != qtv->controller->netchan.incoming_sequence)
//printf("bug is here\n");
qtv->controller->netchan.outgoing_sequence = qtv->controller->netchan.incoming_sequence;
// qtv->controller->netchan.incoming_sequence = qtv->netchan.incoming_acknowledged;
}