mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-25 21:31:37 +00:00
cameras start at intermission spots, stream change messages for other users, cleaned up the menu code a little
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2458 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
5596b146fe
commit
47f9440a30
6 changed files with 466 additions and 67 deletions
167
fteqtv/bsp.c
167
fteqtv/bsp.c
|
@ -36,8 +36,15 @@ struct bsp_s {
|
|||
|
||||
unsigned char decpvs[(MAX_MAP_LEAFS+7)/8]; //decompressed pvs
|
||||
int pvsbytecount;
|
||||
|
||||
|
||||
|
||||
int numintermissionspots;
|
||||
intermission_t intermissionspot[8];
|
||||
};
|
||||
|
||||
static const intermission_t intermissionspot;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -113,10 +120,152 @@ void DecompressVis(unsigned char *in, unsigned char *out, int bytecount)
|
|||
}
|
||||
}
|
||||
|
||||
void BSP_LoadEntities(bsp_t *bsp, char *entitydata)
|
||||
{
|
||||
char *v;
|
||||
char key[2048];
|
||||
char value[2048];
|
||||
|
||||
enum {et_random, et_startspot, et_primarystart, et_intermission} etype;
|
||||
|
||||
float org[3];
|
||||
float angles[3];
|
||||
|
||||
qboolean foundstartspot = false;
|
||||
float startspotorg[3];
|
||||
float startspotangles[3];
|
||||
|
||||
//char *COM_ParseToken (char *data, char *out, int outsize, const char *punctuation)
|
||||
while (entitydata)
|
||||
{
|
||||
entitydata = COM_ParseToken(entitydata, key, sizeof(key), NULL);
|
||||
if (!entitydata)
|
||||
break;
|
||||
|
||||
if (!strcmp(key, "{"))
|
||||
{
|
||||
org[0] = 0;
|
||||
org[1] = 0;
|
||||
org[2] = 0;
|
||||
|
||||
angles[0] = 0;
|
||||
angles[1] = 0;
|
||||
angles[2] = 0;
|
||||
etype = et_random;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
|
||||
if(!entitydata)
|
||||
{
|
||||
printf("unexpected eof in bsp entities section\n");
|
||||
return;
|
||||
}
|
||||
|
||||
entitydata = COM_ParseToken(entitydata, key, sizeof(key), NULL);
|
||||
if (!strcmp(key, "}"))
|
||||
break;
|
||||
|
||||
entitydata = COM_ParseToken(entitydata, value, sizeof(value), NULL);
|
||||
|
||||
if (!strcmp(key, "origin"))
|
||||
{
|
||||
v = value;
|
||||
v = COM_ParseToken(v, key, sizeof(key), NULL);
|
||||
org[0] = atof(key);
|
||||
v = COM_ParseToken(v, key, sizeof(key), NULL);
|
||||
org[1] = atof(key);
|
||||
v = COM_ParseToken(v, key, sizeof(key), NULL);
|
||||
org[2] = atof(key);
|
||||
}
|
||||
|
||||
if (!strcmp(key, "angles") || !strcmp(key, "angle") || !strcmp(key, "mangle"))
|
||||
{
|
||||
v = value;
|
||||
v = COM_ParseToken(v, key, sizeof(key), NULL);
|
||||
angles[0] = atof(key);
|
||||
v = COM_ParseToken(v, key, sizeof(key), NULL);
|
||||
if (v)
|
||||
{
|
||||
angles[1] = atof(key);
|
||||
v = COM_ParseToken(v, key, sizeof(key), NULL);
|
||||
angles[2] = atof(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
angles[1] = angles[0];
|
||||
angles[0] = 0;
|
||||
angles[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!strcmp(key, "classname"))
|
||||
{
|
||||
if (!strcmp(value, "info_player_start"))
|
||||
etype = et_primarystart;
|
||||
if (!strcmp(value, "info_deathmatch_start"))
|
||||
etype = et_startspot;
|
||||
if (!strcmp(value, "info_intermission"))
|
||||
etype = et_intermission;
|
||||
}
|
||||
}
|
||||
|
||||
switch (etype)
|
||||
{
|
||||
case et_primarystart: //a single player start
|
||||
memcpy(startspotorg, org, sizeof(startspotorg));
|
||||
memcpy(startspotangles, angles, sizeof(startspotangles));
|
||||
foundstartspot = true;
|
||||
break;
|
||||
case et_startspot:
|
||||
if (!foundstartspot)
|
||||
{
|
||||
memcpy(startspotorg, org, sizeof(startspotorg));
|
||||
memcpy(startspotangles, angles, sizeof(startspotangles));
|
||||
foundstartspot = true;
|
||||
}
|
||||
break;
|
||||
case et_intermission:
|
||||
if (bsp->numintermissionspots < sizeof(bsp->intermissionspot)/sizeof(bsp->intermissionspot[0]))
|
||||
{
|
||||
bsp->intermissionspot[bsp->numintermissionspots].pos[0] = org[0];
|
||||
bsp->intermissionspot[bsp->numintermissionspots].pos[1] = org[1];
|
||||
bsp->intermissionspot[bsp->numintermissionspots].pos[2] = org[2];
|
||||
|
||||
bsp->intermissionspot[bsp->numintermissionspots].angle[0] = angles[0];
|
||||
bsp->intermissionspot[bsp->numintermissionspots].angle[1] = angles[1];
|
||||
bsp->intermissionspot[bsp->numintermissionspots].angle[2] = angles[2];
|
||||
bsp->numintermissionspots++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("data not expected here\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundstartspot && !bsp->numintermissionspots)
|
||||
{
|
||||
bsp->intermissionspot[bsp->numintermissionspots].pos[0] = startspotorg[0];
|
||||
bsp->intermissionspot[bsp->numintermissionspots].pos[1] = startspotorg[1];
|
||||
bsp->intermissionspot[bsp->numintermissionspots].pos[2] = startspotorg[2];
|
||||
|
||||
bsp->intermissionspot[bsp->numintermissionspots].angle[0] = startspotangles[0];
|
||||
bsp->intermissionspot[bsp->numintermissionspots].angle[1] = startspotangles[1];
|
||||
bsp->intermissionspot[bsp->numintermissionspots].angle[2] = startspotangles[2];
|
||||
bsp->numintermissionspots++;
|
||||
}
|
||||
}
|
||||
|
||||
bsp_t *BSP_LoadModel(cluster_t *cluster, char *gamedir, char *bspname)
|
||||
{
|
||||
unsigned char *data;
|
||||
unsigned int size;
|
||||
char *entdata;
|
||||
|
||||
dheader_t *header;
|
||||
dplane_t *planes;
|
||||
|
@ -159,10 +308,13 @@ bsp_t *BSP_LoadModel(cluster_t *cluster, char *gamedir, char *bspname)
|
|||
nodes = (dnode_t*)(data+LittleLong(header->lumps[LUMP_NODES].fileofs));
|
||||
leaf = (dleaf_t*)(data+LittleLong(header->lumps[LUMP_LEAFS].fileofs));
|
||||
|
||||
entdata = (char*)(data+LittleLong(header->lumps[LUMP_ENTITIES].fileofs));
|
||||
|
||||
numnodes = LittleLong(header->lumps[LUMP_NODES].filelen)/sizeof(dnode_t);
|
||||
numleafs = LittleLong(header->lumps[LUMP_LEAFS].filelen)/sizeof(dleaf_t);
|
||||
|
||||
bsp = malloc(sizeof(bsp_t) + sizeof(node_t)*numnodes + LittleLong(header->lumps[LUMP_VISIBILITY].filelen) + sizeof(unsigned char *)*numleafs);
|
||||
bsp->numintermissionspots = 0;
|
||||
if (bsp)
|
||||
{
|
||||
bsp->fullchecksum = 0;
|
||||
|
@ -204,6 +356,8 @@ bsp_t *BSP_LoadModel(cluster_t *cluster, char *gamedir, char *bspname)
|
|||
}
|
||||
}
|
||||
|
||||
BSP_LoadEntities(bsp, entdata);
|
||||
|
||||
free(data);
|
||||
|
||||
return bsp;
|
||||
|
@ -318,3 +472,16 @@ void BSP_SetupForPosition(bsp_t *bsp, float x, float y, float z)
|
|||
DecompressVis(bsp->pvsofs[leafnum], bsp->decpvs, bsp->pvsbytecount);
|
||||
}
|
||||
|
||||
const intermission_t *BSP_IntermissionSpot(bsp_t *bsp)
|
||||
{
|
||||
int spotnum;
|
||||
if (bsp)
|
||||
{
|
||||
if (bsp->numintermissionspots>0)
|
||||
{
|
||||
spotnum = rand()%bsp->numintermissionspots;
|
||||
return &bsp->intermissionspot[spotnum];
|
||||
}
|
||||
}
|
||||
return &intermissionspot;
|
||||
}
|
|
@ -1688,7 +1688,7 @@ void ParseMessage(sv_t *tv, char *buffer, int length, int to, int mask)
|
|||
if (tv->bsp)
|
||||
BSP_Free(tv->bsp);
|
||||
|
||||
if (tv->cluster->nobsp || !tv->usequkeworldprotocols)
|
||||
if (tv->cluster->nobsp)// || !tv->usequkeworldprotocols)
|
||||
tv->bsp = NULL;
|
||||
else
|
||||
tv->bsp = BSP_LoadModel(tv->cluster, tv->gamedir, tv->modellist[1].name);
|
||||
|
|
|
@ -496,6 +496,11 @@ typedef struct {
|
|||
char bits[6];
|
||||
} nail_t;
|
||||
|
||||
typedef struct {
|
||||
float pos[3];
|
||||
float angle[3];
|
||||
} intermission_t;
|
||||
|
||||
struct sv_s {
|
||||
char connectpassword[64]; //password given to server
|
||||
netadr_t serveraddress;
|
||||
|
@ -879,7 +884,9 @@ unsigned int BSP_Checksum(bsp_t *bsp);
|
|||
int BSP_SphereLeafNums(bsp_t *bsp, int maxleafs, unsigned short *list, float x, float y, float z, float radius);
|
||||
qboolean BSP_Visible(bsp_t *bsp, int leafcount, unsigned short *list);
|
||||
void BSP_SetupForPosition(bsp_t *bsp, float x, float y, float z);
|
||||
void QW_SetViewersServer(viewer_t *viewer, sv_t *sv);
|
||||
const intermission_t *BSP_IntermissionSpot(bsp_t *bsp);
|
||||
|
||||
void QW_SetViewersServer(cluster_t *cluster, viewer_t *viewer, sv_t *sv);
|
||||
unsigned short QCRC_Block (unsigned char *start, int count);
|
||||
unsigned short QCRC_Value(unsigned short crcvalue);
|
||||
void WriteDeltaUsercmd (netmsg_t *m, const usercmd_t *from, usercmd_t *move);
|
||||
|
|
318
fteqtv/qw.c
318
fteqtv/qw.c
|
@ -23,6 +23,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
static const filename_t ConnectionlessModelList[] = {{""}, {"maps/start.bsp"}, {"progs/player.mdl"}, {""}};
|
||||
static const filename_t ConnectionlessSoundList[] = {{""}, {""}};
|
||||
|
||||
void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean noupwards);
|
||||
|
||||
void QTV_DefaultMovevars(movevars_t *vars)
|
||||
{
|
||||
vars->gravity = 800;
|
||||
|
@ -620,8 +622,26 @@ int SendList(sv_t *qtv, int first, const filename_t *list, int svc, netmsg_t *ms
|
|||
return i;
|
||||
}
|
||||
|
||||
void QW_SetViewersServer(viewer_t *viewer, sv_t *sv)
|
||||
void QW_StreamPrint(cluster_t *cluster, sv_t *server, viewer_t *allbut, char *message)
|
||||
{
|
||||
viewer_t *v;
|
||||
|
||||
for (v = cluster->viewers; v; v = v->next)
|
||||
{
|
||||
if (v->server == server)
|
||||
{
|
||||
if (v == allbut)
|
||||
continue;
|
||||
QW_PrintfToViewer(v, "%s", message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QW_SetViewersServer(cluster_t *cluster, viewer_t *viewer, sv_t *sv)
|
||||
{
|
||||
char buffer[1024];
|
||||
sv_t *oldserver;
|
||||
oldserver = viewer->server;
|
||||
if (viewer->server)
|
||||
viewer->server->numviewers--;
|
||||
viewer->server = sv;
|
||||
|
@ -635,6 +655,17 @@ void QW_SetViewersServer(viewer_t *viewer, sv_t *sv)
|
|||
viewer->origin[0] = 0;
|
||||
viewer->origin[1] = 0;
|
||||
viewer->origin[2] = 0;
|
||||
|
||||
if (sv != oldserver)
|
||||
{
|
||||
if (sv)
|
||||
{
|
||||
snprintf(buffer, sizeof(buffer), "%cQTV%c%s leaves to watch %s (%i)\n", 91+128, 93+128, viewer->name, *sv->hostname?sv->hostname:sv->server, sv->streamid);
|
||||
QW_StreamPrint(cluster, oldserver, viewer, buffer);
|
||||
}
|
||||
snprintf(buffer, sizeof(buffer), "%cQTV%c%s joins the stream\n", 91+128, 93+128, viewer->name);
|
||||
QW_StreamPrint(cluster, sv, viewer, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
//fixme: will these want to have state?..
|
||||
|
@ -655,16 +686,8 @@ void NewClient(cluster_t *cluster, viewer_t *viewer)
|
|||
viewer->timeout = cluster->curtime + 15*1000;
|
||||
viewer->trackplayer = -1;
|
||||
|
||||
|
||||
if (!viewer->server)
|
||||
{
|
||||
QW_SetMenu(viewer, MENU_SERVERS);
|
||||
}
|
||||
else
|
||||
{
|
||||
viewer->menunum = -1;
|
||||
QW_SetMenu(viewer, MENU_NONE);
|
||||
}
|
||||
viewer->menunum = -1;
|
||||
QW_SetMenu(viewer, MENU_NONE);
|
||||
|
||||
|
||||
QW_PrintfToViewer(viewer, "Welcome to FTEQTV build %i\n", cluster->buildnumber);
|
||||
|
@ -682,11 +705,22 @@ void NewClient(cluster_t *cluster, viewer_t *viewer)
|
|||
QW_StuffcmdToViewer(viewer, "alias \"proxy:menu\" \"say proxy:menu\"\n");
|
||||
QW_StuffcmdToViewer(viewer, "alias \"proxy:backspace\" \"say proxy:menu backspace\"\n");
|
||||
|
||||
QW_StuffcmdToViewer(viewer, "alias \".help\" \"say .help\"\n");
|
||||
QW_StuffcmdToViewer(viewer, "alias \".disconnect\" \"say .disconnect\"\n");
|
||||
QW_StuffcmdToViewer(viewer, "alias \".menu\" \"say .menu\"\n");
|
||||
QW_StuffcmdToViewer(viewer, "alias \".admin\" \"say .admin\"\n");
|
||||
QW_StuffcmdToViewer(viewer, "alias \".reset\" \"say .reset\"\n");
|
||||
QW_StuffcmdToViewer(viewer, "alias \".clients\" \"say .clients\"\n");
|
||||
// QW_StuffcmdToViewer(viewer, "alias \".qtv\" \"say .qtv\"\n");
|
||||
// QW_StuffcmdToViewer(viewer, "alias \".join\" \"say .join\"\n");
|
||||
// QW_StuffcmdToViewer(viewer, "alias \".observe\" \"say .observe\"\n");
|
||||
|
||||
QW_PrintfToViewer(viewer, "Type admin for the admin menu\n");
|
||||
}
|
||||
|
||||
void ParseUserInfo(cluster_t *cluster, viewer_t *viewer)
|
||||
{
|
||||
char buf[1024];
|
||||
float rate;
|
||||
char temp[64];
|
||||
Info_ValueForKey(viewer->userinfo, "name", temp, sizeof(temp));
|
||||
|
@ -695,6 +729,27 @@ void ParseUserInfo(cluster_t *cluster, viewer_t *viewer)
|
|||
strcpy(temp, "unnamed");
|
||||
if (!*viewer->name)
|
||||
Sys_Printf(cluster, "Viewer %s connected\n", temp);
|
||||
|
||||
if (strcmp(viewer->name, temp))
|
||||
{
|
||||
if (*viewer->name)
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%cQTV%c%s changed name to %cQTV%c%s\n",
|
||||
91+128, 93+128, viewer->name,
|
||||
91+128, 93+128, temp
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "%cQTV%c%s joins the stream\n",
|
||||
91+128, 93+128, temp
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
QW_StreamPrint(cluster, viewer->server, NULL, buf);
|
||||
}
|
||||
|
||||
Q_strncpyz(viewer->name, temp, sizeof(viewer->name));
|
||||
|
||||
Info_ValueForKey(viewer->userinfo, "rate", temp, sizeof(temp));
|
||||
|
@ -855,6 +910,8 @@ void QW_SetMenu(viewer_t *v, int menunum)
|
|||
{
|
||||
if (menunum != MENU_NONE)
|
||||
{
|
||||
QW_StuffcmdToViewer(v, "//set prox_inmenu 1\n");
|
||||
|
||||
QW_StuffcmdToViewer(v, "alias \"+proxfwd\" \"proxy:up\"\n");
|
||||
QW_StuffcmdToViewer(v, "alias \"+proxback\" \"proxy:down\"\n");
|
||||
QW_StuffcmdToViewer(v, "alias \"+proxleft\" \"proxy:left\"\n");
|
||||
|
@ -867,6 +924,8 @@ void QW_SetMenu(viewer_t *v, int menunum)
|
|||
}
|
||||
else
|
||||
{
|
||||
QW_StuffcmdToViewer(v, "//set prox_inmenu 0\n");
|
||||
|
||||
QW_StuffcmdToViewer(v, "alias \"+proxfwd\" \"+forward\"\n");
|
||||
QW_StuffcmdToViewer(v, "alias \"+proxback\" \"+back\"\n");
|
||||
QW_StuffcmdToViewer(v, "alias \"+proxleft\" \"+moveleft\"\n");
|
||||
|
@ -1419,7 +1478,6 @@ void SendNQClientData(sv_t *tv, viewer_t *v, netmsg_t *msg)
|
|||
|
||||
void SendNQPlayerStates(cluster_t *cluster, sv_t *tv, viewer_t *v, netmsg_t *msg)
|
||||
{
|
||||
int miss;
|
||||
int e;
|
||||
int i;
|
||||
usercmd_t to;
|
||||
|
@ -2139,7 +2197,7 @@ void PMove(viewer_t *v, usercmd_t *cmd)
|
|||
v->velocity[2] = pmove.velocity[2];
|
||||
}
|
||||
|
||||
void QW_SetCommentator(viewer_t *v, viewer_t *commentator)
|
||||
void QW_SetCommentator(cluster_t *cluster, viewer_t *v, viewer_t *commentator)
|
||||
{
|
||||
// if (v->commentator == commentator)
|
||||
// return;
|
||||
|
@ -2154,7 +2212,7 @@ void QW_SetCommentator(viewer_t *v, viewer_t *commentator)
|
|||
QW_PrintfToViewer(v, "Following commentator %s\n", commentator->name);
|
||||
|
||||
if (v->server != commentator->server)
|
||||
QW_SetViewersServer(v, commentator->server);
|
||||
QW_SetViewersServer(cluster, v, commentator->server);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2195,7 +2253,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
qtv = QTV_NewServerConnection(cluster, buf, "", false, false, false);
|
||||
if (qtv)
|
||||
{
|
||||
QW_SetViewersServer(v, qtv);
|
||||
QW_SetViewersServer(cluster, v, qtv);
|
||||
QW_PrintfToViewer(v, "Connected\n", message);
|
||||
}
|
||||
else
|
||||
|
@ -2215,6 +2273,19 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
Sys_Printf(cluster, "Player %s gets incorrect admin password\n", v->name);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(v->expectcommand, "insecadddemo"))
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "file:%s", message);
|
||||
qtv = QTV_NewServerConnection(cluster, buf, "", false, false, false);
|
||||
if (!qtv)
|
||||
QW_PrintfToViewer(v, "Failed to play demo \"%s\"\n", message);
|
||||
else
|
||||
{
|
||||
QW_SetViewersServer(cluster, v, qtv);
|
||||
QW_PrintfToViewer(v, "Opened demo file.\n", message);
|
||||
}
|
||||
}
|
||||
|
||||
else if (!strcmp(v->expectcommand, "adddemo"))
|
||||
{
|
||||
snprintf(buf, sizeof(buf), "file:%s", message);
|
||||
|
@ -2223,7 +2294,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
QW_PrintfToViewer(v, "Failed to play demo \"%s\"\n", message);
|
||||
else
|
||||
{
|
||||
QW_SetViewersServer(v, qtv);
|
||||
QW_SetViewersServer(cluster, v, qtv);
|
||||
QW_PrintfToViewer(v, "Opened demo file.\n", message);
|
||||
}
|
||||
}
|
||||
|
@ -2277,11 +2348,41 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
".bind\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if (!strncmp(message, ".menu", 5))
|
||||
{
|
||||
message += 5;
|
||||
|
||||
if (v->conmenussupported)
|
||||
goto guimenu;
|
||||
else
|
||||
goto tuimenu;
|
||||
}
|
||||
|
||||
else if (!strncmp(message, ".tuimenu", 8))
|
||||
{
|
||||
message += 8;
|
||||
|
||||
tuimenu:
|
||||
if (v->menunum)
|
||||
QW_SetMenu(v, MENU_NONE);
|
||||
else
|
||||
QW_SetMenu(v, MENU_SERVERS);
|
||||
}
|
||||
else if (!strncmp(message, ".guimenu", 8))
|
||||
{
|
||||
sv_t *sv;
|
||||
int y;
|
||||
qboolean shownheader = false;
|
||||
qboolean shownheader;
|
||||
|
||||
message += 8;
|
||||
|
||||
guimenu:
|
||||
|
||||
QW_SetMenu(v, MENU_NONE);
|
||||
|
||||
shownheader = false;
|
||||
|
||||
QW_StuffcmdToViewer(v,
|
||||
|
||||
"alias menucallback\n"
|
||||
|
@ -2402,16 +2503,9 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
}
|
||||
else if (!strncmp(message, ".reset", 6))
|
||||
{
|
||||
QW_SetViewersServer(v, NULL);
|
||||
QW_SetViewersServer(cluster, v, NULL);
|
||||
QW_SetMenu(v, MENU_SERVERS);
|
||||
}
|
||||
else if (!strncmp(message, ".menu", 5))
|
||||
{
|
||||
if (v->menunum)
|
||||
QW_SetMenu(v, MENU_NONE);
|
||||
else
|
||||
QW_SetMenu(v, MENU_SERVERS);
|
||||
}
|
||||
else if (!strncmp(message, ".admin", 6))
|
||||
{
|
||||
if (!*cluster->adminpassword)
|
||||
|
@ -2444,7 +2538,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
if (qtv)
|
||||
{
|
||||
QW_SetMenu(v, MENU_NONE);
|
||||
QW_SetViewersServer(v, qtv);
|
||||
QW_SetViewersServer(cluster, v, qtv);
|
||||
QW_PrintfToViewer(v, "Connected\n", message);
|
||||
}
|
||||
else
|
||||
|
@ -2458,7 +2552,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
if (qtv)
|
||||
{
|
||||
QW_SetMenu(v, MENU_NONE);
|
||||
QW_SetViewersServer(v, qtv);
|
||||
QW_SetViewersServer(cluster, v, qtv);
|
||||
qtv->controller = v;
|
||||
QW_PrintfToViewer(v, "Connected\n", message);
|
||||
}
|
||||
|
@ -2473,7 +2567,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
if (qtv)
|
||||
{
|
||||
QW_SetMenu(v, MENU_NONE);
|
||||
QW_SetViewersServer(v, qtv);
|
||||
QW_SetViewersServer(cluster, v, qtv);
|
||||
QW_PrintfToViewer(v, "Connected\n", message);
|
||||
}
|
||||
else
|
||||
|
@ -2494,7 +2588,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
if (qtv)
|
||||
{
|
||||
QW_SetMenu(v, MENU_NONE);
|
||||
QW_SetViewersServer(v, qtv);
|
||||
QW_SetViewersServer(cluster, v, qtv);
|
||||
QW_PrintfToViewer(v, "Connected\n", message);
|
||||
}
|
||||
else
|
||||
|
@ -2510,7 +2604,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
if (qtv)
|
||||
{
|
||||
QW_SetMenu(v, MENU_NONE);
|
||||
QW_SetViewersServer(v, qtv);
|
||||
QW_SetViewersServer(cluster, v, qtv);
|
||||
QW_PrintfToViewer(v, "Connected\n", message);
|
||||
}
|
||||
else
|
||||
|
@ -2519,7 +2613,7 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
else if (!strncmp(message, ".disconnect", 11))
|
||||
{
|
||||
QW_SetMenu(v, MENU_SERVERS);
|
||||
QW_SetViewersServer(v, NULL);
|
||||
QW_SetViewersServer(cluster, v, NULL);
|
||||
QW_PrintfToViewer(v, "Connected\n", message);
|
||||
}
|
||||
else if (!strncmp(message, "admin", 11))
|
||||
|
@ -2544,12 +2638,12 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
if (ov->server)
|
||||
{
|
||||
if (ov->server->controller == ov)
|
||||
QW_PrintfToViewer(v, "%s: %s\n", ov->name, ov->server->server);
|
||||
QW_PrintfToViewer(v, "%i: %s: %s\n", ov->userid, ov->name, ov->server->server);
|
||||
else
|
||||
QW_PrintfToViewer(v, "%s: %s\n", ov->name, ov->server->server);
|
||||
QW_PrintfToViewer(v, "%i: %s: %s\n", ov->userid, ov->name, ov->server->server);
|
||||
}
|
||||
else
|
||||
QW_PrintfToViewer(v, "%s: %s\n", ov->name, "None");
|
||||
QW_PrintfToViewer(v, "%i: %s: %s\n", ov->userid, ov->name, "None");
|
||||
}
|
||||
else
|
||||
remaining++;
|
||||
|
@ -2557,21 +2651,21 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
if (remaining)
|
||||
QW_PrintfToViewer(v, "%i clients not shown\n", remaining);
|
||||
}
|
||||
else if (!strncmp(message, ".followid ", 8))
|
||||
else if (!strncmp(message, ".followid ", 10))
|
||||
{
|
||||
int id = atoi(message+8);
|
||||
int id = atoi(message+10);
|
||||
viewer_t *cv;
|
||||
|
||||
for (cv = cluster->viewers; cv; cv = cv->next)
|
||||
{
|
||||
if (cv->userid == id)
|
||||
{
|
||||
QW_SetCommentator(v, cv);
|
||||
QW_SetCommentator(cluster, v, cv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
QW_PrintfToViewer(v, "Couldn't find that player\n");
|
||||
QW_SetCommentator(v, NULL);
|
||||
QW_SetCommentator(cluster, v, NULL);
|
||||
}
|
||||
else if (!strncmp(message, ".follow ", 8))
|
||||
{
|
||||
|
@ -2582,16 +2676,16 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
{
|
||||
if (!strcmp(cv->name, id))
|
||||
{
|
||||
QW_SetCommentator(v, cv);
|
||||
QW_SetCommentator(cluster, v, cv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
QW_PrintfToViewer(v, "Couldn't find that player\n");
|
||||
QW_SetCommentator(v, NULL);
|
||||
QW_SetCommentator(cluster, v, NULL);
|
||||
}
|
||||
else if (!strncmp(message, ".follow", 7))
|
||||
{
|
||||
QW_SetCommentator(v, NULL);
|
||||
QW_SetCommentator(cluster, v, NULL);
|
||||
}
|
||||
else if (!strncmp(message, "proxy:menu up", 13))
|
||||
{
|
||||
|
@ -2659,6 +2753,52 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
|
||||
QW_PrintfToViewer(v, "All keys bound not recognised\n");
|
||||
}
|
||||
else if (!strncmp(message, ".bsay ", 6))
|
||||
{
|
||||
viewer_t *ov;
|
||||
if (cluster->notalking)
|
||||
return;
|
||||
|
||||
message += 6;
|
||||
|
||||
for (ov = cluster->viewers; ov; ov = ov->next)
|
||||
{
|
||||
InitNetMsg(&msg, buf, sizeof(buf));
|
||||
|
||||
WriteByte(&msg, svc_print);
|
||||
|
||||
if (ov->netchan.isnqprotocol)
|
||||
WriteByte(&msg, 1);
|
||||
else
|
||||
{
|
||||
if (ov->conmenussupported)
|
||||
{
|
||||
WriteByte(&msg, 3); //PRINT_CHAT
|
||||
WriteString2(&msg, "[^sBQTV^s]^s^5");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteByte(&msg, 2); //PRINT_HIGH
|
||||
WriteByte(&msg, 91+128);
|
||||
WriteString2(&msg, "BQTV");
|
||||
WriteByte(&msg, 93+128);
|
||||
WriteByte(&msg, 0);
|
||||
|
||||
WriteByte(&msg, svc_print);
|
||||
WriteByte(&msg, 3); //PRINT_CHAT
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
WriteString2(&msg, v->name);
|
||||
WriteString2(&msg, ": ");
|
||||
// WriteString2(&msg, "\x8d ");
|
||||
WriteString2(&msg, message);
|
||||
WriteString(&msg, "\n");
|
||||
|
||||
SendBufferToViewer(ov, msg.data, msg.cursize, true);
|
||||
}
|
||||
}
|
||||
else if (!strncmp(message, ".", 1) && strncmp(message, "..", 2))
|
||||
{
|
||||
QW_PrintfToViewer(v, "Proxy command not recognised\n");
|
||||
|
@ -2709,16 +2849,25 @@ void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message, qboolean
|
|||
if (ov->conmenussupported)
|
||||
{
|
||||
WriteByte(&msg, 3); //PRINT_CHAT
|
||||
WriteString2(&msg, "^s^5");
|
||||
WriteString2(&msg, "[^sQTV^s]^s^5");
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteByte(&msg, 2); //PRINT_HIGH
|
||||
WriteByte(&msg, 91+128);
|
||||
WriteString2(&msg, "QTV");
|
||||
WriteByte(&msg, 93+128);
|
||||
WriteByte(&msg, 0);
|
||||
|
||||
WriteByte(&msg, svc_print);
|
||||
WriteByte(&msg, 3); //PRINT_CHAT
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
WriteString2(&msg, v->name);
|
||||
WriteString2(&msg, "\x8d ");
|
||||
WriteString2(&msg, ": ");
|
||||
// WriteString2(&msg, "\x8d ");
|
||||
WriteString2(&msg, message);
|
||||
WriteString(&msg, "\n");
|
||||
|
||||
|
@ -2767,6 +2916,37 @@ void QW_StuffcmdToViewer(viewer_t *v, char *format, ...)
|
|||
SendBufferToViewer(v, buf, strlen(buf)+1, true);
|
||||
}
|
||||
|
||||
void QW_PositionAtIntermission(sv_t *qtv, viewer_t *v)
|
||||
{
|
||||
netmsg_t msg;
|
||||
char buf[4];
|
||||
const intermission_t *spot;
|
||||
|
||||
|
||||
if (qtv)
|
||||
spot = BSP_IntermissionSpot(qtv->bsp);
|
||||
else
|
||||
spot = BSP_IntermissionSpot(NULL);
|
||||
|
||||
|
||||
v->origin[0] = spot->pos[0];
|
||||
v->origin[1] = spot->pos[1];
|
||||
v->origin[2] = spot->pos[2];
|
||||
|
||||
|
||||
msg.data = buf;
|
||||
msg.maxsize = sizeof(buf);
|
||||
msg.cursize = 0;
|
||||
msg.overflowed = 0;
|
||||
|
||||
WriteByte (&msg, svc_setangle);
|
||||
WriteByte (&msg, (spot->angle[0]/360) * 256);
|
||||
WriteByte (&msg, (spot->angle[1]/360) * 256);
|
||||
WriteByte (&msg, 0);//spot->angle[2]);
|
||||
|
||||
SendBufferToViewer(v, msg.data, msg.cursize, true);
|
||||
}
|
||||
|
||||
void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
||||
{
|
||||
char buf[MAX_NQMSGLEN];
|
||||
|
@ -2861,11 +3041,21 @@ void ParseNQC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
|||
SendNQSpawnInfoToViewer(cluster, v, &msg);
|
||||
SendBufferToViewer(v, msg.data, msg.cursize, true);
|
||||
|
||||
QW_PositionAtIntermission(qtv, v);
|
||||
|
||||
v->thinksitsconnected = true;
|
||||
}
|
||||
else if (!strncmp(buf, "begin", 5))
|
||||
{
|
||||
int oldmenu;
|
||||
v->thinksitsconnected = true;
|
||||
|
||||
oldmenu = v->menunum;
|
||||
QW_SetMenu(v, MENU_NONE);
|
||||
QW_SetMenu(v, oldmenu);
|
||||
|
||||
if (!v->server)
|
||||
QTV_Say(cluster, v->server, v, ".menu", false);
|
||||
}
|
||||
|
||||
else if (!strncmp(buf, "say \"", 5))
|
||||
|
@ -2930,12 +3120,14 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
|||
// usercmd_t oldest, oldcmd, newcmd;
|
||||
char buf[1024];
|
||||
netmsg_t msg;
|
||||
int i;
|
||||
|
||||
v->delta_frame = -1;
|
||||
|
||||
while (m->readpos < m->cursize)
|
||||
{
|
||||
switch (ReadByte(m))
|
||||
i = ReadByte(m);
|
||||
switch (i)
|
||||
{
|
||||
case clc_nop:
|
||||
return;
|
||||
|
@ -3075,9 +3267,12 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
|||
char skin[64];
|
||||
sprintf(skin, "%cskins\n", svc_stufftext);
|
||||
SendBufferToViewer(v, skin, strlen(skin)+1, true);
|
||||
|
||||
QW_PositionAtIntermission(qtv, v);
|
||||
}
|
||||
else if (!strncmp(buf, "begin", 5))
|
||||
{
|
||||
int oldmenu;
|
||||
viewer_t *com;
|
||||
if (atoi(buf+6) != v->servercount)
|
||||
SendServerData(qtv, v); //this is unfortunate!
|
||||
|
@ -3089,11 +3284,20 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
|||
char msgb[] = {svc_setpause, 1};
|
||||
SendBufferToViewer(v, msgb, sizeof(msgb), true);
|
||||
}
|
||||
}
|
||||
|
||||
com = v->commentator;
|
||||
v->commentator = NULL;
|
||||
QW_SetCommentator(v, com);
|
||||
oldmenu = v->menunum;
|
||||
QW_SetMenu(v, MENU_NONE);
|
||||
QW_SetMenu(v, oldmenu);
|
||||
|
||||
|
||||
com = v->commentator;
|
||||
v->commentator = NULL;
|
||||
QW_SetCommentator(cluster, v, com);
|
||||
|
||||
|
||||
if (!v->server)
|
||||
QTV_Say(cluster, v->server, v, ".menu", false);
|
||||
}
|
||||
}
|
||||
else if (!strncmp(buf, "download", 8))
|
||||
{
|
||||
|
@ -3132,7 +3336,7 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
|||
else if (!strncmp(buf, "ptrack", 6))
|
||||
{
|
||||
v->trackplayer = -1;
|
||||
QW_SetCommentator(v, NULL);
|
||||
QW_SetCommentator(cluster, v, NULL);
|
||||
}
|
||||
else if (!strncmp(buf, "pings", 5))
|
||||
{
|
||||
|
@ -3259,6 +3463,7 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
|||
return;
|
||||
|
||||
default:
|
||||
Sys_Printf(cluster, "bad clc from %s\n", v->name);
|
||||
v->drop = true;
|
||||
return;
|
||||
}
|
||||
|
@ -3326,7 +3531,7 @@ void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum)
|
|||
}
|
||||
else*/
|
||||
{
|
||||
QW_SetViewersServer(viewer, sv);
|
||||
QW_SetViewersServer(cluster, viewer, sv);
|
||||
QW_SetMenu(viewer, MENU_NONE);
|
||||
viewer->thinksitsconnected = false;
|
||||
}
|
||||
|
@ -3406,6 +3611,10 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
|
|||
unsigned char *s;
|
||||
|
||||
netmsg_t m;
|
||||
|
||||
if (viewer->backbuffered)
|
||||
return;
|
||||
|
||||
InitNetMsg(&m, buffer, sizeof(buffer));
|
||||
|
||||
WriteByte(&m, svc_centerprint);
|
||||
|
@ -3594,11 +3803,15 @@ static const char dropcmd[] = {svc_stufftext, 'd', 'i', 's', 'c', 'o', 'n', 'n',
|
|||
|
||||
void QW_FreeViewer(cluster_t *cluster, viewer_t *viewer)
|
||||
{
|
||||
char buf[1024];
|
||||
viewer_t *oview;
|
||||
int i;
|
||||
//note: unlink them yourself.
|
||||
|
||||
// Sys_Printf(cluster, "Dropping viewer %s\n", viewer->name);
|
||||
snprintf(buf, sizeof(buf), "%cQTV%c%s leaves the proxy\n", 91+128, 93+128, viewer->name);
|
||||
QW_StreamPrint(cluster, viewer->server, NULL, buf);
|
||||
|
||||
Sys_Printf(cluster, "Dropping viewer %s\n", viewer->name);
|
||||
|
||||
//spam them thrice, then forget about them
|
||||
Netchan_Transmit(cluster, &viewer->netchan, strlen(dropcmd)+1, dropcmd);
|
||||
|
@ -3622,7 +3835,7 @@ void QW_FreeViewer(cluster_t *cluster, viewer_t *viewer)
|
|||
for (oview = cluster->viewers; oview; oview = oview->next)
|
||||
{
|
||||
if (oview->commentator == viewer)
|
||||
QW_SetCommentator(oview, NULL);
|
||||
QW_SetCommentator(cluster, oview, NULL);
|
||||
}
|
||||
|
||||
free(viewer);
|
||||
|
@ -3803,6 +4016,7 @@ void QW_UpdateUDPStuff(cluster_t *cluster)
|
|||
{
|
||||
if (Net_CompareAddress(&v->netchan.remote_address, &from, 0, 0))
|
||||
{
|
||||
Sys_Printf(cluster, "Dup connect from %s\n", v->name);
|
||||
v->drop = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -527,6 +527,14 @@ char *Cmd_Status(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffe
|
|||
catbuffer(buffer, sizeofbuffer, " Talking allowed\n");
|
||||
if (cluster->nobsp)
|
||||
catbuffer(buffer, sizeofbuffer, " No BSP loading\n");
|
||||
if (cluster->tcpsocket != INVALID_SOCKET)
|
||||
{
|
||||
catbuffer(buffer, sizeofbuffer, " tcp port %i\n", cluster->tcplistenportnum);
|
||||
}
|
||||
if (cluster->tcpsocket != INVALID_SOCKET)
|
||||
{
|
||||
catbuffer(buffer, sizeofbuffer, " udp port %i\n", cluster->qwlistenportnum);
|
||||
}
|
||||
catbuffer(buffer, sizeofbuffer, "\n");
|
||||
|
||||
|
||||
|
@ -557,6 +565,9 @@ char *Cmd_Status(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buffe
|
|||
if (*qtv->connectpassword)
|
||||
catbuffer(buffer, sizeofbuffer, "Using a password\n");
|
||||
|
||||
if (qtv->disconnectwhennooneiswatching)
|
||||
catbuffer(buffer, sizeofbuffer, "Stream is temporary\n");
|
||||
|
||||
if (qtv->tcpsocket != INVALID_SOCKET)
|
||||
{
|
||||
catbuffer(buffer, sizeofbuffer, "Listening for proxies (%i)\n", qtv->tcplistenportnum);
|
||||
|
@ -762,11 +773,11 @@ char *Cmd_MVDPort(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buff
|
|||
|
||||
if (!newp)
|
||||
{
|
||||
if (qtv->tcpsocket != INVALID_SOCKET)
|
||||
if (cluster->tcpsocket != INVALID_SOCKET)
|
||||
{
|
||||
closesocket(qtv->tcpsocket);
|
||||
qtv->tcpsocket = INVALID_SOCKET;
|
||||
qtv->tcplistenportnum = 0;
|
||||
closesocket(cluster->tcpsocket);
|
||||
cluster->tcpsocket = INVALID_SOCKET;
|
||||
cluster->tcplistenportnum = 0;
|
||||
|
||||
return "mvd port is now closed\n";
|
||||
}
|
||||
|
@ -778,11 +789,10 @@ char *Cmd_MVDPort(cluster_t *cluster, sv_t *qtv, char *arg[MAX_ARGS], char *buff
|
|||
|
||||
if (news != INVALID_SOCKET)
|
||||
{
|
||||
if (qtv->tcpsocket != INVALID_SOCKET)
|
||||
closesocket(qtv->tcpsocket);
|
||||
qtv->tcpsocket = news;
|
||||
qtv->disconnectwhennooneiswatching = false;
|
||||
qtv->tcplistenportnum = newp;
|
||||
if (cluster->tcpsocket != INVALID_SOCKET)
|
||||
closesocket(cluster->tcpsocket);
|
||||
cluster->tcpsocket = news;
|
||||
cluster->tcplistenportnum = newp;
|
||||
return "Opened tcp port\n";
|
||||
}
|
||||
else
|
||||
|
@ -859,8 +869,8 @@ const rconcommands_t rconcommands[] =
|
|||
{"disconnect", 1, 0, Cmd_Disconnect},
|
||||
{"record", 1, 0, Cmd_Record},
|
||||
{"stop", 1, 0, Cmd_Stop},
|
||||
{"tcpport", 1, 0, Cmd_MVDPort},
|
||||
{"mvdport", 1, 0, Cmd_MVDPort},
|
||||
{"tcpport", 0, 1, Cmd_MVDPort},
|
||||
{"mvdport", 0, 1, Cmd_MVDPort},
|
||||
|
||||
#ifdef VIEWER
|
||||
{"watch", 1, 0, Cmd_Watch},
|
||||
|
|
|
@ -864,8 +864,9 @@ void QTV_Shutdown(sv_t *qtv)
|
|||
{
|
||||
if (v->server == qtv)
|
||||
{
|
||||
QW_SetViewersServer(v, NULL);
|
||||
QW_SetMenu(v, MENU_SERVERS);
|
||||
QW_SetViewersServer(qtv->cluster, v, NULL);
|
||||
QW_SetMenu(v, MENU_NONE);
|
||||
QTV_Say(cluster, v->server, v, ".menu", false);
|
||||
QW_PrintfToViewer(v, "Stream %s is closing\n", qtv->server);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue