Lateset set of changes make it more easily configurable. Connect to it as localhost and use the admin alias.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1976 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2006-02-20 01:33:13 +00:00
parent 482758c91c
commit cb3f383214
7 changed files with 432 additions and 19 deletions

View File

@ -35,7 +35,17 @@ void NET_SendPacket(cluster_t *cluster, SOCKET sock, int length, char *data, net
}
}
int Netchan_IsLocal (netadr_t adr)
{
struct sockaddr_in *sadr = (struct sockaddr_in *)adr;
if (sadr->sin_addr.S_un.S_un_b.s_b1 == 127 &&
sadr->sin_addr.S_un.S_un_b.s_b2 == 0 &&
sadr->sin_addr.S_un.S_un_b.s_b3 == 0 &&
sadr->sin_addr.S_un.S_un_b.s_b4 == 1)
return true;
return false;
}

View File

@ -939,6 +939,22 @@ void ParseLightstyle(sv_t *tv, netmsg_t *m)
Multicast(tv, m->data+m->startpos, m->readpos - m->startpos, dem_read, (unsigned)-1);
}
void ParseNails2(sv_t *tv, netmsg_t *m)
{
int count;
int nailnum;
int i;
unsigned char bits[6];
count = (unsigned char)ReadByte(m);
while(count-- > 0)
{
nailnum = ReadByte(m);
for (i = 0; i < 6; i++)
bits[i] = ReadByte(m);
}
//qwe - [qbyte] num [52 bits] nxyzpy 8 12 12 12 4 8
}
void ParseMessage(sv_t *tv, char *buffer, int length, int to, int mask)
{
netmsg_t buf;
@ -1139,9 +1155,9 @@ void ParseMessage(sv_t *tv, char *buffer, int length, int to, int mask)
case svc_updatepl:
ParsePacketloss(tv, &buf, to, mask);
break;
//#define svc_nails2 54 //qwe - [qbyte] num [52 bits] nxyzpy 8 12 12 12 4 8
case svc_nails2:
ParseNails2(tv, &buf);
break;
default:
buf.readpos = buf.startpos;
Sys_Printf(tv->cluster, "Can't handle svc %i\n", (unsigned int)ReadByte(&buf));

View File

@ -259,6 +259,9 @@ typedef struct viewer_s {
float origin[3];
int isadmin;
char expectcommand[16];
sv_t *server;
int menunum;
@ -500,8 +503,7 @@ void ReadString(netmsg_t *b, char *string, int maxlen);
#define svc_setinfo 51 // setinfo on a client
#define svc_serverinfo 52 // serverinfo
#define svc_updatepl 53 // [qbyte] [qbyte]
//#define svc_nails2 54 //qwe - [qbyte] num [52 bits] nxyzpy 8 12 12 12 4 8
#define svc_nails2 54 //qwe - [qbyte] num [52 bits] nxyzpy 8 12 12 12 4 8
@ -587,12 +589,16 @@ void QW_UpdateUDPStuff(cluster_t *qtv);
unsigned int Sys_Milliseconds(void);
void Prox_SendInitialEnts(sv_t *qtv, oproxy_t *prox, netmsg_t *msg);
qboolean QTV_Connect(sv_t *qtv, char *serverurl);
void QTV_Shutdown(sv_t *qtv);
qboolean NET_StringToAddr (char *s, netadr_t *sadr);
void SendBufferToViewer(viewer_t *v, const char *buffer, int length, qboolean reliable);
void QW_PrintfToViewer(viewer_t *v, char *format, ...);
void QW_StuffcmdToViewer(viewer_t *v, char *format, ...);
void Netchan_Setup (SOCKET sock, netchan_t *chan, netadr_t adr, int qport);
void Netchan_OutOfBandPrint (cluster_t *cluster, SOCKET sock, netadr_t adr, char *format, ...);
int Netchan_IsLocal (netadr_t adr);
void NET_SendPacket(cluster_t *cluster, SOCKET sock, int length, char *data, netadr_t adr);
qboolean Net_CompareAddress(netadr_t *s1, netadr_t *s2, int qp1, int qp2);
qboolean Netchan_Process (netchan_t *chan, netmsg_t *msg);

View File

@ -39,6 +39,7 @@ RSC=rc.exe
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c

View File

@ -261,6 +261,10 @@ int SendCurrentUserinfos(sv_t *tv, int cursize, netmsg_t *msg, int i)
if (i >= MAX_CLIENTS)
return i;
WriteByte(msg, svc_updateuserinfo);
WriteByte(msg, MAX_CLIENTS-1);
WriteLong(msg, MAX_CLIENTS-1);
WriteString(msg, "\\*spectator\\1\\name\\YOU!");
for (; i < MAX_CLIENTS-1; i++)
{
@ -272,12 +276,19 @@ int SendCurrentUserinfos(sv_t *tv, int cursize, netmsg_t *msg, int i)
WriteByte(msg, i);
WriteLong(msg, i);
WriteString(msg, tv->players[i].userinfo);
}
WriteByte(msg, svc_updateuserinfo);
WriteByte(msg, MAX_CLIENTS-1);
WriteLong(msg, MAX_CLIENTS-1);
WriteString(msg, "\\*spectator\\1\\name\\YOU!");
WriteByte(msg, svc_updatefrags);
WriteByte(msg, i);
WriteShort(msg, tv->players[i].frags);
WriteByte(msg, svc_updateping);
WriteByte(msg, i);
WriteShort(msg, tv->players[i].ping);
WriteByte(msg, svc_updatepl);
WriteByte(msg, i);
WriteByte(msg, tv->players[i].packetloss);
}
i++;
@ -464,6 +475,10 @@ void NewQWClient(cluster_t *cluster, netadr_t *addr, char *connectmessage)
Info_ValueForKey(infostring, "name", viewer->name, sizeof(viewer->name));
Netchan_OutOfBandPrint(cluster, cluster->qwdsocket, *addr, "j");
QW_PrintfToViewer(viewer, "Welcome to FTEQTV\n");
QW_StuffcmdToViewer(viewer, "alias admin \"cmd admin\"\n");
QW_PrintfToViewer(viewer, "Type admin for the admin menu\n");
}
void QTV_Rcon(cluster_t *cluster, char *message, netadr_t *from)
@ -1037,7 +1052,7 @@ void PMove(viewer_t *v, usercmd_t *cmd)
v->origin[i] += (cmd->forwardmove*fwd[i] + cmd->sidemove*rgt[i] + cmd->upmove*up[i])*(cmd->msec/1000.0f);
}
void QTV_Say(cluster_t *cluster, viewer_t *v, char *message)
void QTV_Say(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *message)
{
char buf[1024];
netmsg_t msg;
@ -1045,6 +1060,72 @@ void QTV_Say(cluster_t *cluster, viewer_t *v, char *message)
if (message[strlen(message)-1] == '\"')
message[strlen(message)-1] = '\0';
if (*v->expectcommand && v->menunum)
{
buf[sizeof(buf)-1] = '\0';
if (!strcmp(v->expectcommand, "hostname"))
{
strncpy(cluster->hostname, message, sizeof(cluster->hostname));
cluster->hostname[sizeof(cluster->hostname)-1] = '\0';
}
else if (!strcmp(v->expectcommand, "master"))
{
strncpy(cluster->master, message, sizeof(cluster->master));
cluster->master[sizeof(cluster->master)-1] = '\0';
if (!strcmp(cluster->master, "."))
*cluster->master = '\0';
cluster->mastersendtime = cluster->curtime;
}
else if (!strcmp(v->expectcommand, "addserver"))
{
_snprintf(buf, sizeof(buf), "tcp:%s", message);
qtv = QTV_NewServerConnection(cluster, buf, false);
if (qtv)
{
v->server = qtv;
QW_StuffcmdToViewer(v, "cmd new\n");
QW_PrintfToViewer(v, "Connected\n", message);
}
else
QW_PrintfToViewer(v, "Failed to connect to server \"%s\", connection aborted\n", message);
}
else if (!strcmp(v->expectcommand, "admin"))
{
if (!strcmp(message, cluster->password))
{
v->menunum = 2;
v->isadmin = true;
Sys_Printf(cluster, "Player %s logs in as admin\n", v->name);
}
else
{
QW_PrintfToViewer(v, "Admin password incorrect\n");
Sys_Printf(cluster, "Player %s gets incorrect admin password\n", v->name);
}
}
else if (!strcmp(v->expectcommand, "adddemo"))
{
_snprintf(buf, sizeof(buf), "file:%s", message);
qtv = QTV_NewServerConnection(cluster, buf, false);
if (!qtv)
QW_PrintfToViewer(v, "Failed to play demo \"%s\"\n", message);
else
{
v->server = qtv;
QW_StuffcmdToViewer(v, "cmd new\n");
QW_PrintfToViewer(v, "Opened demo file.\n", message);
}
}
else
{
QW_PrintfToViewer(v, "Command %s was not recognised\n", v->expectcommand);
}
*v->expectcommand = '\0';
return;
}
*v->expectcommand = '\0';
InitNetMsg(&msg, buf, sizeof(buf));
WriteByte(&msg, svc_print);
@ -1089,6 +1170,28 @@ void QW_PrintfToViewer(viewer_t *v, char *format, ...)
SendBufferToViewer(v, buf, strlen(buf)+1, true);
}
void QW_StuffcmdToViewer(viewer_t *v, char *format, ...)
{
va_list argptr;
char buf[1024];
netmsg_t msg;
InitNetMsg(&msg, buf, sizeof(buf));
va_start (argptr, format);
#ifdef _WIN32
_vsnprintf (buf+1, sizeof(buf) - 2, format, argptr);
buf[sizeof(buf) - 2] = '\0';
#else
vsnprintf (buf+1, sizeof(buf)-1, format, argptr);
#endif // _WIN32
va_end (argptr);
buf[0] = svc_stufftext;
SendBufferToViewer(v, buf, strlen(buf)+1, true);
}
static const filename_t ConnectionlessModelList[] = {{""}, {"maps/start.bsp"}, {"progs/player.mdl"}, {""}};
static const filename_t ConnectionlessSoundList[] = {{""}, {""}};
@ -1245,19 +1348,41 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
{
}
else if (!strncmp(buf, "say \"", 5) && !cluster->notalking)
QTV_Say(cluster, v, buf+5);
QTV_Say(cluster, qtv, v, buf+5);
else if (!strncmp(buf, "say ", 4) && !cluster->notalking)
QTV_Say(cluster, v, buf+4);
QTV_Say(cluster, qtv, v, buf+4);
else if (!strncmp(buf, "servers", 7))
{
v->menunum = 1;
}
else if (!strncmp(buf, "reset", 7))
else if (!strncmp(buf, "reset", 5))
{
QW_StuffcmdToViewer(v, "cmd new\n");
v->server = NULL;
v->menunum = 1;
}
else if (!strncmp(buf, "admin", 5))
{
if (!*cluster->password)
{
if (Netchan_IsLocal(v->netchan.remote_address))
{
Sys_Printf(cluster, "Local player %s logs in as admin\n", v->name);
v->menunum = 2;
v->isadmin = true;
}
else
QW_PrintfToViewer(v, "There is no admin password set\nYou may not log in.\n");
}
else if (v->isadmin)
v->menunum = 2;
else
{
strcpy(v->expectcommand, "admin");
QW_StuffcmdToViewer(v, "echo Please enter the rcon password\nmessagemode\n");
}
}
else if (!qtv)
{
@ -1375,6 +1500,27 @@ void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum)
default:
break;
case 3:
if (viewer->server)
{
i = 0;
if (i++ == viewer->menuop)
{ //mvd port
QW_StuffcmdToViewer(viewer, "echo You will need to reconnect\n");
cluster->qwlistenportnum += buttonnum?-1:1;
}
if (i++ == viewer->menuop)
{ //disconnect
QTV_Shutdown(viewer->server);
}
if (i++ == viewer->menuop)
{ //back
viewer->menunum = 2;
viewer->menuop = 0;
}
break;
}
//fallthrough
case 1:
if (!cluster->servers)
{
@ -1415,6 +1561,67 @@ void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum)
}
}
}
break;
case 2:
i = 0;
if (i++ == viewer->menuop)
{ //connection stuff
viewer->menunum = 3;
viewer->menuop = 0;
}
if (i++ == viewer->menuop)
{ //qw port
QW_StuffcmdToViewer(viewer, "echo You will need to reconnect\n");
cluster->qwlistenportnum += buttonnum?-1:1;
}
if (i++ == viewer->menuop)
{ //hostname
strcpy(viewer->expectcommand, "hostname");
QW_StuffcmdToViewer(viewer, "echo Please enter the new hostname\nmessagemode\n");
}
if (i++ == viewer->menuop)
{ //master
strcpy(viewer->expectcommand, "master");
QW_StuffcmdToViewer(viewer, "echo Please enter the master dns or ip\necho Enter '.' for masterless mode\nmessagemode\n");
}
if (i++ == viewer->menuop)
{ //password
strcpy(viewer->expectcommand, "password");
QW_StuffcmdToViewer(viewer, "echo Please enter the new rcon password\nmessagemode\n");
}
if (i++ == viewer->menuop)
{ //add server
strcpy(viewer->expectcommand, "messagemode");
QW_StuffcmdToViewer(viewer, "echo Please enter the new qtv server dns or ip\naddserver\n");
}
if (i++ == viewer->menuop)
{ //add demo
strcpy(viewer->expectcommand, "adddemo");
QW_StuffcmdToViewer(viewer, "echo Please enter the name of the demo to play\nmessagemode\n");
}
if (i++ == viewer->menuop)
{ //choke
cluster->chokeonnotupdated ^= 1;
}
if (i++ == viewer->menuop)
{ //late forwarding
cluster->lateforward ^= 1;
}
if (i++ == viewer->menuop)
{ //no talking
cluster->notalking ^= 1;
}
if (i++ == viewer->menuop)
{ //nobsp
cluster->nobsp ^= 1;
}
if (i++ == viewer->menuop)
{ //back
viewer->menunum = 0;
viewer->menuop = 0;
}
break;
}
}
@ -1435,7 +1642,6 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
WriteString2(&m, "FTEQTV\n");
if (strcmp(cluster->hostname, DEFAULT_HOSTNAME))
WriteString2(&m, cluster->hostname);
WriteString2(&m, "\n\n");
switch(viewer->menunum)
{
@ -1443,8 +1649,48 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
WriteString2(&m, "bad menu");
break;
case 3: //per-connection options
if (viewer->server)
{
sv = viewer->server;
WriteString2(&m, "\n\nConnection Admin\n");
WriteString2(&m, sv->hostname);
if (sv->file)
WriteString2(&m, " (demo)");
WriteString2(&m, "\n\n");
if (viewer->menuop < 0)
viewer->menuop = 0;
i = 0;
WriteString2(&m, " port");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20i", sv->tcplistenportnum);
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " disconnect");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", "...");
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " back");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", "...");
WriteString2(&m, str);
WriteString2(&m, "\n");
if (viewer->menuop >= i)
viewer->menuop = i - 1;
break;
}
//fallthrough
case 1: //connections list
WriteString2(&m, "\n\nServers\n\n");
if (!cluster->servers)
{
WriteString2(&m, "No active connections");
@ -1480,17 +1726,87 @@ void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
break;
case 2: //admin menu
WriteString2(&m, " port");
WriteString2(&m, (viewer->menuop==0)?" \r ":" : ");
WriteString2(&m, "\n\nCluster Admin\n\n");
if (viewer->menuop < 0)
viewer->menuop = 0;
i = 0;
WriteString2(&m, " this connection");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", "...");
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " port");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20i", cluster->qwlistenportnum);
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, "hostname");
WriteString2(&m, (viewer->menuop==1)?" \r ":" : ");
WriteString2(&m, " hostname");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", cluster->hostname);
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " master");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", cluster->master);
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " password");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", "...");
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " add server");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", "...");
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " add demo");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", "...");
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " choke");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", cluster->chokeonnotupdated?"yes":"no");
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, "delay forwarding");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", cluster->lateforward?"yes":"no");
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " talking");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", cluster->notalking?"no":"yes");
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " nobsp");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", cluster->nobsp?"yes":"no");
WriteString2(&m, str);
WriteString2(&m, "\n");
WriteString2(&m, " back");
WriteString2(&m, (viewer->menuop==(i++))?" \r ":" : ");
sprintf(str, "%-20s", "...");
WriteString2(&m, str);
WriteString2(&m, "\n");
if (viewer->menuop >= i)
viewer->menuop = i - 1;
break;
}

View File

@ -554,6 +554,13 @@ char *Server_Rcon_Dispatch(sv_t *qtv, char *arg[MAX_ARGS], char *buffer, int siz
else
return "Failed (will keep trying)\n";
}
else if (!strcmp(arg[0], "disconnect"))
{
QTV_Shutdown(qtv);
return NULL;
}
else if (!strcmp(arg[0], "file") || !strcmp(arg[0], "play") || !strcmp(arg[0], "playdemo"))
{
if (!*arg[1])

View File

@ -862,6 +862,63 @@ qboolean QTV_Connect(sv_t *qtv, char *serverurl)
}
return true;
}
void QTV_Shutdown(sv_t *qtv)
{
return;
/*
viewer_t *v;
sv_t *peer;
cluster_t *cluster;
Sys_Printf(qtv->cluster, "Shutting down %s\n", qtv->server);
if (qtv->sourcesock != INVALID_SOCKET)
{
int err;
err = qerrno;
if (qerrno)
Sys_Printf(qtv->cluster, "Error: source socket error %i\n", qerrno);
else
Sys_Printf(qtv->cluster, "Error: server disconnected\n");
closesocket(qtv->sourcesock);
qtv->sourcesock = INVALID_SOCKET;
}
if (qtv->file)
{
fclose(qtv->file);
qtv->file = NULL;
}
BSP_Free(qtv->bsp);
qtv->bsp = NULL;
cluster = qtv->cluster;
if (cluster->servers == qtv)
cluster->servers = qtv->next;
else
{
for (peer = cluster->servers; peer->next; peer = peer->next)
{
if (peer->next == qtv)
{
peer->next = qtv->next;
break;
}
}
}
for (v = cluster->viewers; v; v = v->next)
{
if (v->server == qtv)
{
v->server = NULL;
v->menunum = 1;
}
}
free(qtv);
*/
}
/*
void QTV_Run(sv_t *qtv)
{