From 7734e7c57a82aecd61ea3b312a028569abe4ef21 Mon Sep 17 00:00:00 2001 From: ac_stef Date: Mon, 30 Mar 2009 22:40:00 +0000 Subject: [PATCH] check for map-collisions serverside git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@4308 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/server.cpp | 27 ++++++++++++++----- source/src/tools.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++- source/src/tools.h | 2 +- source/src/world.h | 1 + 4 files changed, 83 insertions(+), 8 deletions(-) diff --git a/source/src/server.cpp b/source/src/server.cpp index 80491cbd..93592323 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -23,7 +23,7 @@ bool refillteams(bool now = false, bool notify = true); void changeclientrole(int client, int role, char *pwd = NULL, bool force=false); bool mapavailable(const char *mapname); void getservermap(void); -mapstats *getservermapstats(const char *name); +mapstats *getservermapstats(const char *mapname, bool getlayout = false); servercontroller *svcctrl = NULL; struct log *logger = NULL; @@ -240,6 +240,7 @@ struct client // server side version of "dynent" type bool at3_dontmove; int spawnindex; int salt; + int mapcollisions, farpickups; gameevent &addevent() { @@ -256,6 +257,7 @@ struct client // server side version of "dynent" type timesync = false; lastevent = 0; at3_lastforce = 0; + mapcollisions = farpickups = 0; } void reset() @@ -298,6 +300,9 @@ struct ban vector bans; +char *maplayout = NULL; +int maplayout_factor; + struct worldstate { enet_uint32 uses; @@ -1325,7 +1330,7 @@ void arenacheck() bool spamdetect(client *cl, char *text) // checks doubled lines and average typing speed { - if(cl->type != ST_TCPIP) return false; + if(cl->type != ST_TCPIP || cl->role == CR_ADMIN) return false; bool spam = false; int pause = servmillis - cl->lastsay; if(pause < 0 || pause > 90*1000) pause = 90*1000; @@ -1608,7 +1613,7 @@ void readipblacklist(const char *name) static int blfilesize; char *p, *l, *r; iprange ir; - int m, len, line = 0, errors = 0; + int len, line = 0, errors = 0; if(!name && getfilesize(blfilename) == blfilesize) return; ipblacklist.setsize(0); @@ -2099,7 +2104,7 @@ void resetmap(const char *newname, int newmode, int newtime, bool notify) lastfillup = servmillis; resetvotes(VOTE_YES); // flowtron: VOTE_YES => reset lastvotecall too resetitems(); - mapstats *ms = getservermapstats(smapname); + mapstats *ms = getservermapstats(smapname, isdedicated); loopi(3) clnumspawn[i] = ms ? ms->spawns[i] : 0; loopi(2) clnumflagspawn[i] = ms ? ms->flags[i] : 0; if(ms) @@ -2456,7 +2461,7 @@ ENetPacket *getmapserv(int n) // provide maps by the server -mapstats *getservermapstats(const char *mapname) +mapstats *getservermapstats(const char *mapname, bool getlayout) { const char *name = behindpath(mapname); s_sprintfd(filename)(SERVERMAP_PATH "%s.cgz", name); @@ -2474,7 +2479,8 @@ mapstats *getservermapstats(const char *mapname) found = fileexists(filename, "r"); } } - return found ? loadmapstats(filename) : NULL; + if(getlayout) DELETEA(maplayout); + return found ? loadmapstats(filename, getlayout) : NULL; } #define GZBUFSIZE ((MAXCFGFILESIZE * 11) / 10) @@ -3141,6 +3147,15 @@ void process(ENetPacket *packet, int sender, int chan) // sender may be -1 cl->position.setsizenodelete(0); while(curmsgposition.add(p.buf[curmsg++]); } + if(maplayout) + { + vec &po = clients[cn]->state.o; + int ls = (1 << maplayout_factor) - 1; + if(po.x < 0 || po.y < 0 || po.x > ls || po.y > ls || maplayout[((int) po.x) + (((int) po.y) << maplayout_factor)] > po.z + 3) + { + clients[cn]->mapcollisions++; + } + } break; } diff --git a/source/src/tools.cpp b/source/src/tools.cpp index ecb83efc..5941a78e 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -312,10 +312,14 @@ bool delfile(const char *path) return !remove(path); } -mapstats *loadmapstats(const char *filename) +extern char *maplayout; +extern int maplayout_factor; + +mapstats *loadmapstats(const char *filename, bool getlayout) { static mapstats s; static uchar *enttypes = NULL; + static short *entposs = NULL; DELETEA(enttypes); loopi(MAXENTTYPES) s.entcnt[i] = 0; @@ -331,6 +335,7 @@ mapstats *loadmapstats(const char *filename) if(s.hdr.version>=4) endianswap(&s.hdr.waterlevel, sizeof(int), 1); else s.hdr.waterlevel = -100000; entity e; enttypes = new uchar[s.hdr.numents]; + entposs = new short[s.hdr.numents * 3]; loopi(s.hdr.numents) { gzread(f, &e, sizeof(persistent_entity)); @@ -340,12 +345,66 @@ mapstats *loadmapstats(const char *filename) if(e.type == CTF_FLAG && (e.attr2 == 0 || e.attr2 == 1)) s.flags[e.attr2]++; 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; + } + if(getlayout) + { + DELETEA(maplayout); + if(s.hdr.sfactor <= LARGEST_FACTOR && s.hdr.sfactor >= SMALLEST_FACTOR) + { + maplayout_factor = s.hdr.sfactor; + int layoutsize = 1 << (maplayout_factor * 2); + bool fail = false; + maplayout = new char[layoutsize + 256]; + memset(maplayout, 0, layoutsize * sizeof(char)); + char *t = NULL; + char floor = 0, ceil; + loopk(layoutsize) + { + char *c = maplayout + k; + int type = gzgetc(f); + switch(type) + { + case 255: + { + int n = gzgetc(f); + if(!t || n < 0) { fail = true; break; } + memset(c, *t, n); + k += n - 1; + break; + } + case 254: // only in MAPVERSION<=2 + if(!t) { fail = true; break; } + *c = *t; + gzgetc(f); gzgetc(f); + break; + default: + if(type<0 || type>=MAXTYPE) { fail = true; break; } + floor = gzgetc(f); + ceil = gzgetc(f); + if(floor >= ceil && ceil > -128) floor = ceil - 1; // for pre 12_13 + if(type == FHF) floor = 1; + gzgetc(f); gzgetc(f); + if(s.hdr.version>=2) gzgetc(f); + if(s.hdr.version>=5) gzgetc(f); + case SOLID: + *c = type == SOLID ? 127 : floor; + gzgetc(f); gzgetc(f); + if(s.hdr.version<=2) { gzgetc(f); gzgetc(f); } + break; + } + if(fail) break; + t = c; + } + if(fail) DELETEA(maplayout); + } } gzclose(f); s.hasffaspawns = s.spawns[2] > 0; s.hasteamspawns = s.spawns[0] > 0 && s.spawns[1] > 0; s.hasflags = s.flags[0] > 0 && s.flags[1] > 0; s.enttypes = enttypes; + s.entposs = entposs; return &s; } diff --git a/source/src/tools.h b/source/src/tools.h index 9c59f066..5d0d3505 100644 --- a/source/src/tools.h +++ b/source/src/tools.h @@ -595,7 +595,7 @@ extern char *loadfile(const char *fn, int *size, const char *mode = NULL); extern bool listdir(const char *dir, const char *ext, vector &files); extern int listfiles(const char *dir, const char *ext, vector &files); extern bool delfile(const char *path); -extern struct mapstats *loadmapstats(const char *filename); +extern struct mapstats *loadmapstats(const char *filename, bool getlayout); extern bool cmpb(void *b, int n, enet_uint32 c); extern bool cmpf(char *fn, enet_uint32 c); extern void endianswap(void *, int, int); diff --git a/source/src/world.h b/source/src/world.h index 0fe64098..cb7656b4 100644 --- a/source/src/world.h +++ b/source/src/world.h @@ -53,6 +53,7 @@ struct mapstats struct header hdr; int entcnt[MAXENTTYPES]; uchar *enttypes; + short *entposs; int spawns[3]; int flags[2]; bool hasffaspawns;