diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 9becf59f..318de8ba 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -338,7 +338,7 @@ void playerinfo(const char *cn, const char *attr) ATTR_INT(cn, p->clientnum); // only useful to get player1's client number. string addr = ""; - if((p->address>>24&0xFF) > 0 || player1->clientrole==CR_ADMIN) + if((p->address>>24&0xFF) != 0 || player1->clientrole==CR_ADMIN) formatstring(addr)("%d.%d.%d.%d", p->address&0xFF, p->address>>8&0xFF, p->address>>16&0xFF, p->address>>24&0xFF); // full IP else formatstring(addr)("%d.%d.%d.x", p->address&0xFF, p->address>>8&0xFF, p->address>>16&0xFF); // censored IP ATTR_STR(ip, addr); @@ -1626,17 +1626,18 @@ void cleanplayervotes(playerent *p) void whois(int cn) { - playerent *pl = getclient(cn); - if(!pl) + playerent *p = getclient(cn); + if(!p) { conoutf(_("invalid player name")); return; } - if(m_teammode) conoutf(_("%c0INFO: %c5%s has %d teamkills."), CC, CC, pl->name, pl->tks); - if((pl->address>>24&0xFF) > 0 || player1->clientrole==CR_ADMIN) - conoutf("WHOIS %2d: %-16s\t%d.%d.%d.%d", cn, pl ? colorname(pl) : "", pl->address&0xFF, pl->address>>8&0xFF, pl->address>>16&0xFF, pl->address>>24&0xFF); // full IP - else conoutf("WHOIS client %d:\n\f5name\t%s\n\f5IP\t%d.%d.%d.x", cn, pl ? colorname(pl) : "", pl->address&0xFF, pl->address>>8&0xFF, pl->address>>16&0xFF); // censored IP + int ip = p->address; + if(m_teammode) conoutf(_("%c0INFO: %c5%s has %d teamkills."), CC, CC, p->name, p->tks); + if((ip>>24&0xFF) > 0 || player1->clientrole==CR_ADMIN) + conoutf("WHOIS client %d:\n\f5name\t%s\n\f5IP\t%d.%d.%d.%d", cn, colorname(p), ip&0xFF, ip>>8&0xFF, ip>>16&0xFF, ip>>24&0xFF); // full IP + else conoutf("WHOIS client %d:\n\f5name\t%s\n\f5IP\t%d.%d.%d.x", cn, colorname(p), ip&0xFF, ip>>8&0xFF, ip>>16&0xFF); // censored IP } COMMAND(whois, ARG_1INT); @@ -1652,20 +1653,6 @@ void findcn(char *name) } COMMAND(findcn, ARG_1STR); -/* moved to /config/compatibility.cfg -void findpn(int cn) -{ - loopv(players) if(players[i] && players[i]->clientnum == cn) - { - result(players[i]->name); - return; - } - if(player1->clientnum == cn) { result(player1->name); return; } - result(""); -} -COMMAND(findpn, ARG_1INT); -*/ - int sessionid = 0; void setadmin(char *claim, char *password) diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 6c083f64..8babc5d5 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -394,6 +394,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p, bool demo = false) if(demo && watchingdemo && demoprotocol == 1132) { + if(type > SV_IPLIST) --type; // SV_WHOIS removed if(type >= SV_TEXTPRIVATE) ++type; // SV_TEXTPRIVATE added if(type == SV_SWITCHNAME) // SV_SPECTCN removed { @@ -596,6 +597,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p, bool demo = false) getstring(text, p); loopi(2) getint(p); getint(p); + if(!demo || !watchingdemo || demoprotocol > 1132) getint(p); break; } getstring(text, p); @@ -619,7 +621,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p, bool demo = false) loopi(2) d->setskin(i, getint(p)); d->team = getint(p); - d->address = getint(p); // partial or complete IP address + if(!demo || !watchingdemo || demoprotocol > 1132) d->address = getint(p); // partial IP address if(m_flags) loopi(2) { @@ -869,7 +871,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p, bool demo = false) if(p.overread() || cn<0) break; int state = getint(p), lifesequence = getint(p), primary = getint(p), gunselect = getint(p), flagscore = getint(p), frags = getint(p), deaths = getint(p), health = getint(p), armour = getint(p), points = getint(p); int teamkills = 0; - if(!demo || !watchingdemo || demoprotocol != 1132) teamkills = getint(p); + if(!demo || !watchingdemo || demoprotocol > 1132) teamkills = getint(p); int ammo[NUMGUNS], mag[NUMGUNS]; loopi(NUMGUNS) ammo[i] = getint(p); loopi(NUMGUNS) mag[i] = getint(p); @@ -1289,11 +1291,16 @@ void parsemessages(int cn, playerent *d, ucharbuf &p, bool demo = false) break; } - case SV_WHOISINFO: + case SV_IPLIST: { - int cn = getint(p), ip = getint(p); - playerent *pl = getclient(cn); - if(pl) pl->address = ip; + int cn; + while((cn = getint(p)) >= 0 && !p.overread()) + { + playerent *pl = getclient(cn); + int ip = getint(p); + if(!pl) continue; + else pl->address = ip; + } break; } diff --git a/source/src/entity.h b/source/src/entity.h index ccf57ed1..b3e19a01 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -414,7 +414,7 @@ public: bool ignored, muted; - playerent() : curskin(0), clientnum(-1), lastupdate(0), plag(0), ping(0), lifesequence(0), frags(0), flagscore(0), deaths(0), points(0), tks(0), lastpain(0), lastvoicecom(0), clientrole(CR_DEFAULT), + playerent() : curskin(0), clientnum(-1), lastupdate(0), plag(0), ping(0), address(0), lifesequence(0), frags(0), flagscore(0), deaths(0), points(0), tks(0), lastpain(0), lastvoicecom(0), clientrole(CR_DEFAULT), team(TEAM_SPECT), spectatemode(SM_NONE), followplayercn(FPCN_VOID), eardamagemillis(0), respawnoffset(0), prevweaponsel(NULL), weaponsel(NULL), nextweaponsel(NULL), primweap(NULL), nextprimweap(NULL), lastattackweapon(NULL), smoothmillis(-1), diff --git a/source/src/protocol.cpp b/source/src/protocol.cpp index 8e17ba9e..85045370 100644 --- a/source/src/protocol.cpp +++ b/source/src/protocol.cpp @@ -335,7 +335,7 @@ static const int msgsizes[] = // size inclusive message token, 0 f SV_SETADMIN, 0, SV_SERVOPINFO, 3, SV_CALLVOTE, 0, SV_CALLVOTESUC, 1, SV_CALLVOTEERR, 2, SV_VOTE, 2, SV_VOTERESULT, 2, SV_SETTEAM, 3, SV_TEAMDENY, 2, SV_SERVERMODE, 2, - SV_WHOIS, 2, SV_WHOISINFO, 3, + SV_IPLIST, 0, SV_LISTDEMOS, 1, SV_SENDDEMOLIST, 0, SV_GETDEMO, 2, SV_SENDDEMO, 0, SV_DEMOPLAYBACK, 3, SV_CONNECT, 0, SV_SWITCHNAME, 0, SV_SWITCHSKIN, 0, SV_SWITCHTEAM, 0, diff --git a/source/src/protocol.h b/source/src/protocol.h index 9891d377..722ddc49 100644 --- a/source/src/protocol.h +++ b/source/src/protocol.h @@ -34,7 +34,7 @@ enum SV_SETADMIN, SV_SERVOPINFO, SV_CALLVOTE, SV_CALLVOTESUC, SV_CALLVOTEERR, SV_VOTE, SV_VOTERESULT, SV_SETTEAM, SV_TEAMDENY, SV_SERVERMODE, - SV_WHOIS, SV_WHOISINFO, + SV_IPLIST, SV_LISTDEMOS, SV_SENDDEMOLIST, SV_GETDEMO, SV_SENDDEMO, SV_DEMOPLAYBACK, SV_CONNECT, SV_SWITCHNAME, SV_SWITCHSKIN, SV_SWITCHTEAM, diff --git a/source/src/server.cpp b/source/src/server.cpp index 9a78a5f5..f02ce1d1 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -2271,18 +2271,7 @@ void changeclientrole(int client, int role, char *pwd, bool force) if(pd.line > -1) logline(ACLOG_INFO,"[%s] player %s used admin password in line %d", clients[client]->hostname, clients[client]->name[0] ? clients[client]->name : "[unnamed]", pd.line); logline(ACLOG_INFO,"[%s] set role of player %s to %s", clients[client]->hostname, clients[client]->name[0] ? clients[client]->name : "[unnamed]", role == CR_ADMIN ? "admin" : "normal player"); // flowtron : connecting players haven't got a name yet (connectadmin) - if(role > CR_DEFAULT) - { - // send complete IP addresses - packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE); - loopv(clients) if(clients[i]->clientnum != client) - { - putint(p, SV_WHOISINFO); - putint(p, clients[i]->clientnum); - putint(p, clients[i]->peer->address.host); - } - sendpacket(client, 1, p.finalize()); - } + if(role > CR_DEFAULT) sendiplist(client); } else if(pwd && pwd[0]) disconnect_client(client, DISC_SOPLOGINFAIL); // avoid brute-force if(curvote) curvote->evaluate(); @@ -2411,21 +2400,19 @@ void answerchallenge(client *cl, uint id, char *val) // :for AUTH -void sendwhois(int sender, int cn) +void sendiplist(int receiver, int cn) { - if( !valid_client(sender) ) return; - if ( cn == -1 && clients[sender]->role == CR_ADMIN ) + if(!valid_client(receiver)) return; + packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE); + putint(p, SV_IPLIST); + loopv(clients) if(valid_client(i) && clients[i]->type == ST_TCPIP && i != receiver + && (clients[i]->clientnum == cn || cn == -1)) { - loopv(clients) if ( valid_client(i) && clients[i]->type == ST_TCPIP && i != sender ) sendwhois(sender, i); - return; - } - if( !valid_client(cn) ) return; - if( clients[cn]->type == ST_TCPIP ) - { - uint ip = clients[cn]->peer->address.host; - if(clients[sender]->role != CR_ADMIN) ip &= 0xFFFFFF; // only admin gets full IP - sendf(sender, 1, "ri3", SV_WHOISINFO, cn, ip); + putint(p, i); + putint(p, clients[i]->peer->address.host); } + putint(p, -1); + sendpacket(receiver, 1, p.finalize()); } void sendresume(client &c, bool broadcast) @@ -2468,7 +2455,7 @@ void sendservinfo(client &c) sendf(c.clientnum, 1, "ri5", SV_SERVINFO, c.clientnum, isdedicated ? SERVER_PROTOCOL_VERSION : PROTOCOL_VERSION, c.salt, scl.serverpassword[0] ? 1 : 0); } -void putinitclient(client &c, packetbuf &p, int n) +void putinitclient(client &c, packetbuf &p) { putint(p, SV_INITCLIENT); putint(p, c.clientnum); @@ -2476,22 +2463,16 @@ void putinitclient(client &c, packetbuf &p, int n) putint(p, c.skin[TEAM_CLA]); putint(p, c.skin[TEAM_RVSF]); putint(p, c.team); - enet_uint32 ip = isdedicated ? ( (n != -1 && clients[n]->role == CR_ADMIN) ? - c.peer->address.host : - c.peer->address.host & 0xFFFFFF - ) : 0; - putint(p, ip); // FIXME ? Maybe the IPs addresses should only be sent with SV_WHOISINFO + enet_uint32 ip = 0; + if(c.type == ST_TCPIP) ip = c.peer->address.host & 0xFFFFFF; + putint(p, ip); } void sendinitclient(client &c) { - loopv(clients) if(clients[i]->clientnum != c.clientnum) - { - packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE); - putinitclient(c, p, clients[i]->clientnum); - sendpacket(clients[i]->clientnum, 1, p.finalize()); - } - + packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE); + putinitclient(c, p); + sendpacket(-1, 1, p.finalize(), c.clientnum); } void welcomeinitclient(packetbuf &p, int exclude = -1) @@ -2500,7 +2481,7 @@ void welcomeinitclient(packetbuf &p, int exclude = -1) { client &c = *clients[i]; if(c.type!=ST_TCPIP || !c.isauthed || c.clientnum == exclude) continue; - putinitclient(c, p, exclude); + putinitclient(c, p); } } @@ -2605,7 +2586,7 @@ int checktype(int type, client *cl) SV_SERVMSG, SV_ITEMLIST, SV_FLAGINFO, SV_FLAGMSG, SV_FLAGCNT, SV_ARENAWIN, SV_SERVOPINFO, SV_CALLVOTESUC, SV_CALLVOTEERR, SV_VOTERESULT, - SV_SETTEAM, SV_TEAMDENY, SV_SERVERMODE, SV_WHOISINFO, + SV_SETTEAM, SV_TEAMDENY, SV_SERVERMODE, SV_IPLIST, SV_SENDDEMOLIST, SV_SENDDEMO, SV_DEMOPLAYBACK, SV_CLIENT, SV_HUDEXTRAS, SV_POINTS }; // only allow edit messages in coop-edit mode @@ -2728,6 +2709,13 @@ void process(ENetPacket *packet, int sender, int chan) sendinitclient(*cl); if(clientrole != CR_DEFAULT) changeclientrole(sender, clientrole, NULL, true); if( curvote && curvote->result == VOTE_NEUTRAL ) callvotepacket (cl->clientnum); + + // send full IPs to admins + loopv(clients) + { + if(clients[i] && clients[i]->clientnum != cl->clientnum && (clients[i]->role == CR_ADMIN || clients[i]->type == ST_LOCAL)) + sendiplist(clients[i]->clientnum, cl->clientnum); + } } if(!cl) { logline(ACLOG_ERROR, " client in process()"); return; } // should never happen anyway @@ -3492,12 +3480,6 @@ void process(ENetPacket *packet, int sender, int chan) break; } - case SV_WHOIS: - { - sendwhois(sender, getint(p)); - break; - } - case SV_LISTDEMOS: listdemos(sender); break; diff --git a/source/src/server.h b/source/src/server.h index f6263770..c9a28712 100644 --- a/source/src/server.h +++ b/source/src/server.h @@ -390,6 +390,7 @@ struct demofile void startgame(const char *newname, int newmode, int newtime = -1, bool notify = true); void disconnect_client(int n, int reason = -1); +void sendiplist(int receiver, int cn = -1); int clienthasflag(int cn); bool refillteams(bool now = false, int ftr = FTR_AUTOTEAM); void changeclientrole(int client, int role, char *pwd = NULL, bool force=false); @@ -430,7 +431,7 @@ const char *messagenames[SV_NUM] = "SV_SETADMIN", "SV_SERVOPINFO", "SV_CALLVOTE", "SV_CALLVOTESUC", "SV_CALLVOTEERR", "SV_VOTE", "SV_VOTERESULT", "SV_SETTEAM", "SV_TEAMDENY", "SV_SERVERMODE", - "SV_WHOIS", "SV_WHOISINFO", + "SV_IPLIST", "SV_LISTDEMOS", "SV_SENDDEMOLIST", "SV_GETDEMO", "SV_SENDDEMO", "SV_DEMOPLAYBACK", "SV_CONNECT", "SV_SWITCHNAME", "SV_SWITCHSKIN", "SV_SWITCHTEAM",