git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@1413 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
driAn
2007-11-10 16:05:08 +00:00
parent dcf47213ba
commit 3df88341c3
4 changed files with 190 additions and 15 deletions
+10
View File
@@ -42,6 +42,16 @@ enum { MM_OPEN, MM_PRIVATE, MM_NUM };
enum { DISC_NONE = 0, DISC_EOP, DISC_CN, DISC_MKICK, DISC_MBAN, DISC_TAGT, DISC_BANREFUSE, DISC_WRONGPW, DISC_SOPLOGINFAIL, DISC_MAXCLIENTS, DISC_MASTERMODE, DISC_AUTOKICK, DISC_NUM };
#define EXT_ACK -1
#define EXT_VERSION 102
#define EXT_ERROR_NONE 0
#define EXT_ERROR 1
#define EXT_PLAYERSTATS_RESP_IDS -10
#define EXT_UPTIME 0
#define EXT_PLAYERSTATS 1
#define EXT_TEAMSCORE 2
#define EXT_PLAYERSTATS_RESP_STATS -11
/* Gamemodes
0 tdm
1 coop edit
+4
View File
@@ -441,6 +441,10 @@ extern char msgsizelookup(int msg);
extern void serverms(int mode, int numplayers, int minremain, char *smapname, int millis, int serverport);
extern void servermsinit(const char *master, char *ip, int serverport, char *sdesc, bool listen);
extern bool serverpickup(int i, int sender);
extern bool valid_client(int cn);
extern void extinfo_cnbuf(ucharbuf &p, int cn);
extern void extinfo_statsbuf(ucharbuf &p, int pid, int bpos, ENetSocket &pongsock, ENetAddress &addr, ENetBuffer &buf, int len);
extern void extinfo_teamscorebuf(ucharbuf &p);
// demo
struct demoheader
+112 -3
View File
@@ -14,7 +14,6 @@
servercontroller *svcctrl = NULL;
#define valid_client(c) (clients.inrange(c) && clients[c]->type!=ST_EMPTY)
#define valid_flag(f) (f >= 0 && f < 2)
static const int DEATHMILLIS = 250;
@@ -124,7 +123,7 @@ struct clientstate : playerstate
int lastshot;
projectilestate<8> grenades;
int akimbos, akimbomillis;
int flagscore, frags;
int flagscore, frags, cleanfrags, teamkills, deaths;
clientstate() : state(CS_DEAD) {}
@@ -148,7 +147,7 @@ struct clientstate : playerstate
akimbos = 0;
akimbomillis = 0;
flagscore = frags = 0;
teamkills = deaths = cleanfrags = 0;
respawn();
}
@@ -234,6 +233,11 @@ struct client // server side version of "dynent" type
vector<client *> clients;
bool valid_client(int cn)
{
return clients.inrange(cn) && clients[cn]->type != ST_EMPTY;
}
struct worldstate
{
enet_uint32 uses;
@@ -1025,6 +1029,13 @@ void serverdamage(client *target, client *actor, int damage, int gun, bool gib,
}
if(ts.health<=0)
{
target->state.deaths++;
if(actor->clientnum != target->clientnum)
{
if(isteam(actor->team, target->team)) actor->state.teamkills++;
else actor->state.cleanfrags++; // frags (excl. teamkills)
}
if(target!=actor && !isteam(target->team, actor->team)) actor->state.frags += gib ? 2 : 1;
else actor->state.frags--;
sendf(-1, 1, "ri4", gib ? SV_GIBDIED : SV_DIED, target->clientnum, actor->clientnum, actor->state.frags);
@@ -1119,6 +1130,7 @@ void processevent(client *c, suicideevent &e)
clientstate &gs = c->state;
if(gs.state!=CS_ALIVE) return;
gs.frags--;
gs.deaths++;
sendf(-1, 1, "ri4", SV_DIED, c->clientnum, c->clientnum, gs.frags);
c->position.setsizenodelete(0);
gs.state = CS_DEAD;
@@ -2190,6 +2202,103 @@ void cleanupserver()
if(svcctrl) svcctrl->stop();
}
void extinfo_cnbuf(ucharbuf &p, int cn)
{
if(cn == -1) // add all available player ids
{
loopv(clients) if(clients[i]->type != ST_EMPTY)
putint(p,clients[i]->clientnum);
}
else if(valid_client(cn)) // add single player only
{
putint(p,clients[cn]->clientnum);
}
}
void extinfo_statsbuf(ucharbuf &p, int pid, int bpos, ENetSocket &pongsock, ENetAddress &addr, ENetBuffer &buf, int len)
{
loopv(clients)
{
if(clients[i]->type == ST_EMPTY) continue;
if(pid>-1 && clients[i]->clientnum!=pid) continue;
putint(p,EXT_PLAYERSTATS_RESP_STATS); // send player stats following
putint(p,clients[i]->clientnum); //add player id
sendstring(clients[i]->name,p); //Name
sendstring(clients[i]->team,p); //Team
putint(p,clients[i]->state.cleanfrags); //Frags
putint(p,clients[i]->state.deaths); //Death
putint(p,clients[i]->state.teamkills); //Teamkills
putint(p,clients[i]->state.health); //Health
putint(p,clients[i]->state.armour); //Armour
putint(p,clients[i]->state.gunselect); //Gun selected
putint(p,clients[i]->role); //Role
putint(p,clients[i]->state.state); //State (Alive,Dead,Spawning,Lagged,Editing)
uint ip = ntohl(clients[i]->peer->address.host) >> 8; // only 3 byte of the ip address (privacy protected)
p.put((uchar*)&ip,3);
buf.dataLength = len + p.length();
enet_socket_send(pongsock, &addr, &buf, 1);
if(pid>-1) break;
p.len=bpos;
}
}
void extinfo_teamscorebuf(ucharbuf &p)
{
if(!m_teammode)
{
putint(p,EXT_ERROR); // send error
putint(p,minremain); //remaining play time
return;
}
putint(p,EXT_ERROR_NONE); // send no error
cvector teams;
bool flag;
loopv(clients)
{
flag = true;
loopvj(teams)
{
if(strcmp(clients[i]->team,teams[j])==0 || !clients[i]->team[0])
{
flag = false;
break;
}
}
if(flag) teams.add(clients[i]->team);
}
putint(p,minremain); //remaining play time
loopv(teams)
{
sendstring(teams[i],p); //team
int fragscore = 0;
int flagscore = 0;
loopvj(clients)
{
if(!(strcmp(clients[j]->team,teams[i])==0)) continue;
fragscore += clients[j]->state.frags;
flagscore += clients[j]->state.flagscore;
}
putint(p,fragscore); //add fragscore per team
if(m_ctf) //when capture mode
{
putint(p,flagscore); //add flagscore per team
}
else //all other team modes
{
putint(p,-1); //flagscore not available
}
putint(p,-1);
}
}
#ifndef STANDALONE
void localdisconnect()
{
+64 -12
View File
@@ -158,24 +158,76 @@ void serverms(int mode, int numplayers, int minremain, char *smapname, int milli
// reply all server info requests
ENetBuffer buf;
ENetAddress addr;
uchar pong[MAXTRANS];
uchar data[MAXTRANS];
buf.data = data;
int len;
enet_uint32 events = ENET_SOCKET_WAIT_RECEIVE;
buf.data = pong;
while(enet_socket_wait(pongsock, &events, 0) >= 0 && events)
{
buf.dataLength = sizeof(pong);
buf.dataLength = sizeof(data);
len = enet_socket_receive(pongsock, &addr, &buf, 1);
if(len < 0) return;
ucharbuf p(&pong[len], sizeof(pong)-len);
putint(p, PROTOCOL_VERSION);
putint(p, mode);
putint(p, numplayers);
putint(p, minremain);
sendstring(smapname, p);
sendstring(serverdesc, p);
putint(p, maxclients);
buf.dataLength = len + p.length();
// ping & pong buf
ucharbuf pi(data, sizeof(data));
ucharbuf po(&data[len], sizeof(data)-len);
if(getint(pi) != 0) // std pong
{
putint(po, PROTOCOL_VERSION);
putint(po, mode);
putint(po, numplayers);
putint(po, minremain);
sendstring(smapname, po);
sendstring(serverdesc, po);
putint(po, maxclients);
}
else // ext pong - additional server infos
{
int extcmd = getint(pi);
putint(po, EXT_ACK);
putint(po, EXT_VERSION);
switch(extcmd)
{
case EXT_UPTIME: // uptime in seconds
{
putint(po, millis/1000);
break;
}
case EXT_PLAYERSTATS: // playerstats
{
int cn = getint(pi); // get requested player, -1 for all
if(!valid_client(cn) && cn != -1)
{
putint(po, EXT_ERROR);
break;
}
putint(po, EXT_ERROR_NONE); // add no error flag
int bpos = po.length(); // remember buffer position
putint(po, EXT_PLAYERSTATS_RESP_IDS); // send player ids following
extinfo_cnbuf(po, cn);
buf.dataLength = len + po.length();
enet_socket_send(pongsock, &addr, &buf, 1); // send all available player ids
po.len = bpos;
extinfo_statsbuf(po, cn, bpos, pongsock, addr, buf, len);
return;
}
case EXT_TEAMSCORE:
extinfo_teamscorebuf(po);
break;
default:
putint(po,EXT_ERROR);
break;
}
}
buf.dataLength = len + po.length();
enet_socket_send(pongsock, &addr, &buf, 1);
}
}