From 7f9c99a6150148d60a79ab1b39279fcf8e5ba54e Mon Sep 17 00:00:00 2001 From: ac_stef Date: Fri, 3 Apr 2009 16:20:37 +0000 Subject: [PATCH] detect and log remote flag pickups git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@4314 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/server.cpp | 48 ++++++++++++++++++++++++++++++++++++++++--- source/src/tools.cpp | 4 ++-- source/src/world.h | 1 + 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/source/src/server.cpp b/source/src/server.cpp index 5efb8825..ab8b2f6c 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -941,6 +941,7 @@ struct sflaginfo float pos[3]; int lastupdate; int stolentime; + short x, y; // flag entity location } sflaginfos[2]; void putflaginfo(ucharbuf &p, int flag) @@ -960,6 +961,31 @@ void putflaginfo(ucharbuf &p, int flag) } } +bool flagdistance(sflaginfo &f, int cn) +{ + if(!valid_client(cn)) return false; + client &c = *clients[cn]; + vec v(-1, -1, c.state.o.z); + switch(f.state) + { + case CTFF_INBASE: + v.x = f.x; v.y = f.y; + break; + case CTFF_DROPPED: + v.x = f.pos[0]; v.y = f.pos[1]; + break; + } + if(v.x < 0) return true; + float dist = c.state.o.dist(v); + if(dist > 10) // <2.5 would be normal, LAG may increase the value + { + c.farpickups++; + logger->writeline(log::info, "[%s] %s touched the %s flag at distance %.2f (%d)", c.hostname, c.name, team_string(&f == sflaginfos + 1), dist, c.farpickups); + return false; + } + return true; +} + void sendflaginfo(int flag = -1, int cn = -1) { ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE); @@ -995,6 +1021,7 @@ void flagaction(int flag, int action, int actor) case FA_PICKUP: // ctf: f = enemy team htf: f = own team { if(deadactor || f.state == CTFF_STOLEN) return; + flagdistance(f, actor); int team = team_int(clients[actor]->team); if(m_ctf) team = team_opposite(team); if(team != flag) return; @@ -1020,12 +1047,14 @@ void flagaction(int flag, int action, int actor) if(m_ctf) { if(f.state != CTFF_STOLEN || f.actor_cn != actor || of.state != CTFF_INBASE) return; + flagdistance(of, actor); score = 1; message = FM_SCORE; } else // m_htf { if(f.state != CTFF_DROPPED) return; + flagdistance(f, actor); score = (of.state == CTFF_STOLEN) ? 1 : 0; message = score ? FM_SCORE : FM_SCOREFAIL; if(of.actor_cn == actor) score *= 2; @@ -1045,6 +1074,7 @@ void flagaction(int flag, int action, int actor) { case FA_PICKUP: if(deadactor || f.state != CTFF_INBASE) return; + flagdistance(f, actor); f.state = CTFF_STOLEN; f.actor_cn = actor; f.stolentime = gamemillis; @@ -1408,9 +1438,9 @@ int spawntime(int type) bool serverpickup(int i, int sender) // server side item pickup, acknowledge first client that gets it { - if(!sents.inrange(i)) return false; + if(!sents.inrange(i)) return false; // client tries to pickup a wrong entity -> should be logged server_entity &e = sents[i]; - if(!e.spawned) return false; // client tried to pickup an unspawned entity -> should be logged + if(!e.spawned) return false; if(sender>=0) { client *cl = clients[sender]; @@ -2117,7 +2147,19 @@ void resetmap(const char *newname, int newmode, int newtime, bool notify) resetitems(); mapstats *ms = getservermapstats(smapname, isdedicated); loopi(3) clnumspawn[i] = ms ? ms->spawns[i] : 0; - loopi(2) clnumflagspawn[i] = ms ? ms->flags[i] : 0; + loopi(2) + { + clnumflagspawn[i] = ms ? ms->flags[i] : 0; + sflaginfo &f = sflaginfos[i]; + if(clnumflagspawn[i] == 1) // don't check flag positions, if there is more than one flag per team + { + short *fe = ms->entposs + ms->flagents[i] * 3; + f.x = *fe; + fe++; + f.y = *fe; + } + else f.x = f.y = -1; + } if(ms) { entity e; diff --git a/source/src/tools.cpp b/source/src/tools.cpp index 5941a78e..02eb2c51 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -342,7 +342,7 @@ mapstats *loadmapstats(const char *filename, bool getlayout) endianswap(&e, sizeof(short), 4); TRANSFORMOLDENTITIES(s.hdr) if(e.type == PLAYERSTART && (e.attr2 == 0 || e.attr2 == 1 || e.attr2 == 100)) s.spawns[e.attr2 == 100 ? 2 : e.attr2]++; - if(e.type == CTF_FLAG && (e.attr2 == 0 || e.attr2 == 1)) s.flags[e.attr2]++; + if(e.type == CTF_FLAG && (e.attr2 == 0 || e.attr2 == 1)) { s.flags[e.attr2]++; s.flagents[e.attr2] = i; } s.entcnt[e.type]++; enttypes[i] = e.type; entposs[i * 3] = e.x; entposs[i * 3 + 1] = e.y; entposs[i * 3 + 2] = e.z; @@ -383,7 +383,7 @@ mapstats *loadmapstats(const char *filename, bool getlayout) floor = gzgetc(f); ceil = gzgetc(f); if(floor >= ceil && ceil > -128) floor = ceil - 1; // for pre 12_13 - if(type == FHF) floor = 1; + if(type == FHF) floor = -128; gzgetc(f); gzgetc(f); if(s.hdr.version>=2) gzgetc(f); if(s.hdr.version>=5) gzgetc(f); diff --git a/source/src/world.h b/source/src/world.h index cb7656b4..1d2d2ad8 100644 --- a/source/src/world.h +++ b/source/src/world.h @@ -56,6 +56,7 @@ struct mapstats short *entposs; int spawns[3]; int flags[2]; + int flagents[2]; bool hasffaspawns; bool hasteamspawns; bool hasflags;