From bc01595024bea367bcaf5106859424e90ac9f8bd Mon Sep 17 00:00:00 2001 From: Rafael Barreto Date: Mon, 24 May 2010 17:24:33 +0000 Subject: [PATCH] blocking bad maps in client side, and beginning the work with the medal system git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@5031 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/clientgame.cpp | 13 +++++-- source/src/clients2c.cpp | 34 +++++++++++-------- source/src/server.cpp | 1 + source/src/server.h | 3 ++ source/src/serveractions.h | 2 +- source/src/serverchecks.h | 69 ++++++++++++++++++++++++++++++++++++-- source/src/tools.cpp | 4 +-- source/src/world.h | 1 + source/src/worldio.cpp | 28 ++++++++++++++-- 9 files changed, 129 insertions(+), 26 deletions(-) diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index f3199939..acf32c89 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -577,9 +577,16 @@ void respawnself() } } +extern int checkarea(int maplayout_factor, char *maplayout); +extern int MA; +extern float Mh; + bool tryrespawn() { - if(spawnpermission > SP_OK_NUM) + if ( Mh >= MAXMHEIGHT || MA >= MAXMAREA ) { + hudoutf("This map is not supported in multiplayer"); + } + else if(spawnpermission > SP_OK_NUM) { hudeditf(HUDMSG_TIMER, "\f3%s", spawnpermission == SP_WRONGMAP ? "You have to be on the correct map to spawn. Type /getmap" : "You can't spawn. You're a spectator."); } @@ -621,8 +628,8 @@ void dodamage(int damage, playerent *pl, playerent *actor, bool gib, bool local) pl->respawnoffset = pl->lastpain = lastmillis; - playerent *h = local ? player1 : updatefollowplayer(0); - if(/*actor==h && pl!=actor*/ pl == player1) +// playerent *h = local ? player1 : updatefollowplayer(0); + if(/*actor==h && pl!=actor*/ pl == player1) // FIXME { if(hitsound && lasthit != lastmillis) audiomgr.playsound(S_HITSOUND, SP_LOW); lasthit = lastmillis; diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index a82ab68d..9d2801f9 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -212,6 +212,19 @@ void parsepositions(ucharbuf &p) } } +extern int checkarea(int maplayout_factor, char *maplayout); +char *mlayout = NULL; +int Mv = 0, Ma = 0, MA = 0; +float Mh = 0; +extern int connected; + +bool good_map() +{ + bool checked = ((MA = checkarea(sfactor, mlayout)) < MAXMAREA && Mh < MAXMHEIGHT); + if (!connected) return true; + return checked; +} + void parsemessages(int cn, playerent *d, ucharbuf &p) { static char text[MAXTRANS]; @@ -369,7 +382,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) if(d) d->setskin(i, skin); } break; - + case SV_INITCLIENT: // another client either connected or changed name/team { int cn = getint(p); @@ -443,6 +456,12 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) case SV_SPAWNSTATE: { + + if (!good_map()) { + loopi(6+2*NUMGUNS) getint(p); + break; + } + if(editmode) toggleedit(true); showscores(false); setscope(false); @@ -469,19 +488,6 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) player1->weaponswitch(player1->primweap); player1->weaponchanging -= weapon::weaponchangetime/2; - int A = 0, V = 0, h; - for ( int i = 0 ; i < ssize ; i++ ) { - for ( int j = 0 ; j < ssize ; j++ ) { - sqr *s = S(i, j); - if( s->type!=SOLID && (h = s->ceil - s->floor) > 6 ) { - A++; - V+=h; - } - } - } - float H = (float)V/A; -// conoutf("Map height density information (ssize = %d): H = %.2f, V = %d and A = %d", ssize, H,V,A); - break; } diff --git a/source/src/server.cpp b/source/src/server.cpp index 58eb0180..5679e3e0 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -1314,6 +1314,7 @@ void serverdamage(client *target, client *actor, int damage, int gun, bool gib, if(!v.iszero()) v.normalize(); sendf(target->clientnum, 1, "ri6", SV_HITPUSH, gun, damage, int(v.x*DNF), int(v.y*DNF), int(v.z*DNF)); + combopoints (target, actor, damage, gun); } if(ts.health<=0) { diff --git a/source/src/server.h b/source/src/server.h index 78ba17cb..6b394452 100644 --- a/source/src/server.h +++ b/source/src/server.h @@ -229,6 +229,8 @@ struct client // server side version of "dynent" type int mapcollisions, farpickups; enet_uint32 bottomRTT; + int points, lasthit, lastgun, combohits, combo, combotime, combodamage, ncombos, ncovers, nhs; + gameevent &addevent() { static gameevent dummy; @@ -253,6 +255,7 @@ struct client // server side version of "dynent" type lastevent = 0; at3_lastforce = 0; mapcollisions = farpickups = 0; + points = lasthit = lastgun = combohits = combo = combotime = combodamage = ncombos = ncovers = nhs = 0; } void reset() diff --git a/source/src/serveractions.h b/source/src/serveractions.h index 6b9a4460..a9431bae 100644 --- a/source/src/serveractions.h +++ b/source/src/serveractions.h @@ -49,7 +49,7 @@ struct mapaction : serveraction bool notify = valid_client(caller); int maploc = MAP_NOTFOUND; mapstats *ms = map[0] ? getservermapstats(map, true, &maploc) : NULL; // this is very redundant, since startgame gets the layout - mapok = mode == GMODE_COOPEDIT || ( ms != NULL && Mheight < 30 && (Mopen = checkarea()) < 10000 ); + mapok = mode == GMODE_COOPEDIT || ( ms != NULL && Mheight < MAXMHEIGHT && (Mopen = checkarea(maplayout_factor, maplayout)) < MAXMAREA ); if(!mapok) { if(notify) sendservmsg("the server does not have/support this map", caller); diff --git a/source/src/serverchecks.h b/source/src/serverchecks.h index 68c6b13c..d4c0a4ba 100644 --- a/source/src/serverchecks.h +++ b/source/src/serverchecks.h @@ -3,7 +3,7 @@ //FIXME /* There are smarter ways to implement this function */ -int getmaxarea(bool inversed_x, bool inversed_y, bool transposed) +int getmaxarea(bool inversed_x, bool inversed_y, bool transposed, int maplayout_factor, char *maplayout) { int ls = (1 << maplayout_factor); int xi = 0, oxi = 0, xf = 0, oxf = 0, yi = 0, yf = 0, fx = 0, fy = 0; @@ -62,15 +62,78 @@ int getmaxarea(bool inversed_x, bool inversed_y, bool transposed) return maxarea; } -int checkarea() { +int checkarea(int maplayout_factor, char *maplayout) { int area = 0, maxarea = 0; for (int i=0; i < 8; i++) { - area = getmaxarea((i & 1),(i & 2),(i & 4)); + area = getmaxarea((i & 1),(i & 2),(i & 4), maplayout_factor, maplayout); if ( area > maxarea ) maxarea = area; } + printf("MAX AREA %d\n",maxarea); return maxarea; } +/** +This part is related to medals system. WIP + */ + +inline int minhits2combo(int gun) +{ + switch (gun) + { + case GUN_SUBGUN: + case GUN_AKIMBO: + case GUN_GRENADE: + return 3; + default: + return 2; + } +} + +void combopoints (client *target, client *actor, int damage, int gun) +{ + int diffhittime = gamemillis - actor->lasthit; + actor->lasthit = gamemillis; + if ((gun == GUN_SHOTGUN || gun == GUN_GRENADE) && damage < 20) return; + + if ( diffhittime < 900 ) { + if ( gun == actor->lastgun ) { + if ( diffhittime < guns[gun].attackdelay * 1.25 ) { + actor->combohits++; + actor->combotime+=diffhittime; + actor->combodamage+=damage; + int mh2c = minhits2combo(gun); + if ( actor->combohits > mh2c && actor->combo < 3 && actor->combohits % mh2c == 1 ) { + actor->combo++; + actor->points++; + actor->ncombos++; + } + } + } else { + if ( diffhittime < 550 ) { + switch (gun) { + case GUN_KNIFE: + case GUN_PISTOL: + if ( guns[actor->lastgun].isauto ) break; + case GUN_GRENADE: + actor->combohits++; + actor->combotime+=diffhittime; + actor->combodamage+=damage; + actor->combo++; + actor->points++; + actor->ncombos++; + break; + } + } + } + } else { + actor->combo=0; + actor->combotime=0; + actor->combodamage=0; + actor->combohits=0; + } +} + + /** If you read README.txt you must know that AC does not have cheat protection implemented. However this file is the sketch to a very special kind of cheat detection tools in server side. diff --git a/source/src/tools.cpp b/source/src/tools.cpp index 8c2b475b..a26e398a 100644 --- a/source/src/tools.cpp +++ b/source/src/tools.cpp @@ -27,7 +27,6 @@ const char *numtime() extern char *maplayout; extern int maplayout_factor, Mvolume, Marea; extern float Mheight; -extern int checkarea(); mapstats *loadmapstats(const char *filename, bool getlayout) { @@ -82,8 +81,7 @@ mapstats *loadmapstats(const char *filename, bool getlayout) maplayout = new char[layoutsize + 256]; memset(maplayout, 0, layoutsize * sizeof(char)); char *t = NULL; - char floor = 0, ceil; - int diff = 0; + char floor = 0, ceil, diff = 0; Mvolume = Marea = 0; loopk(layoutsize) { diff --git a/source/src/world.h b/source/src/world.h index 947af7a2..97a4202c 100644 --- a/source/src/world.h +++ b/source/src/world.h @@ -126,6 +126,7 @@ struct mapstats #define OUTBORD(x,y) ((x)=ssize-MINBORD || (y)>=ssize-MINBORD) #define OUTBORDRAD(x,y,rad) (int(x-rad)=ssize-MINBORD || (y+rad)>=ssize-MINBORD) #define MAXMHEIGHT 30 +#define MAXMAREA 10000 struct block { int x, y, xs, ys; }; diff --git a/source/src/worldio.cpp b/source/src/worldio.cpp index 22f7a653..9c42c36b 100644 --- a/source/src/worldio.cpp +++ b/source/src/worldio.cpp @@ -445,6 +445,10 @@ extern void preparectf(bool cleanonly = false); int numspawn[3], maploaded = 0, numflagspawn[2]; VAR(curmaprevision, 1, 0, 0); +extern char *mlayout; +extern int Mv, Ma; +extern float Mh; + bool load_world(char *mname) // still supports all map formats that have existed since the earliest cube betas! { stopwatch watch; @@ -513,6 +517,13 @@ bool load_world(char *mname) // still supports all map formats that have } delete[] world; setupworld(hdr.sfactor); + + DELETEA(mlayout); + mlayout = new char[cubicsize + 256]; + memset(mlayout, 0, cubicsize * sizeof(char)); + char diff = 0; + Mv = Ma = 0; + if(!mapinfo.numelems || (mapinfo.access(mname) && !cmpf(cgzname, mapinfo[mname]))) world = (sqr *)ents.getbuf(); c2skeepalive(); char texuse[256]; @@ -520,6 +531,7 @@ bool load_world(char *mname) // still supports all map formats that have sqr *t = NULL; loopk(cubicsize) { + char *c = mlayout + k; sqr *s = &world[k]; int type = f ? f->getchar() : -1; switch(type) @@ -532,6 +544,7 @@ bool load_world(char *mname) // still supports all map formats that have delete f; f = NULL; } + *c = 127; s->type = SOLID; s->ftex = DEFAULT_FLOOR; s->ctex = DEFAULT_CEIL; @@ -544,8 +557,10 @@ bool load_world(char *mname) // still supports all map formats that have } case 255: { - if(!t) { delete f; f = NULL; k--; continue; } - int n = f->getchar(); + int n; + if(!t || (n = f->getchar()) < 0) { delete f; f = NULL; k--; continue; } + char tmp = *(c-1); + memset(c, tmp, n); for(int i = 0; ir = s->g = s->b = f->getchar(); f->getchar(); @@ -560,6 +576,7 @@ bool load_world(char *mname) // still supports all map formats that have } case SOLID: { + *c = 127; s->type = SOLID; s->wtex = f->getchar(); s->vdelta = f->getchar(); @@ -586,6 +603,8 @@ bool load_world(char *mname) // still supports all map formats that have s->floor = f->getchar(); s->ceil = f->getchar(); if(s->floor>=s->ceil) s->floor = s->ceil-1; // for pre 12_13 + diff = s->ceil - s->floor; + *c = s->floor; // FIXME s->wtex = f->getchar(); s->ftex = f->getchar(); s->ctex = f->getchar(); @@ -595,11 +614,16 @@ bool load_world(char *mname) // still supports all map formats that have s->tag = (hdr.version>=5) ? f->getchar() : 0; } } + if ( type != SOLID && diff > 6 ) { + Ma++; + Mv+=diff; + } s->defer = 0; t = s; texuse[s->wtex] = 1; if(!SOLID(s)) texuse[s->utex] = texuse[s->ftex] = texuse[s->ctex] = 1; } + Mh = Ma ? (float)Mv/Ma : 0; if(f) delete f; c2skeepalive(); calclight();