diff --git a/source/src/client.cpp b/source/src/client.cpp index 3662ae78..f8c9739b 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -349,11 +349,19 @@ void c2sinfo(playerent *d) // send update to the server ya = (int)((512 * d->yaw) / 360.0f), pi = (int)((127 * d->pitch) / 90.0f), r = (int)(31*d->roll/20), - dx = (int)(d->vel.x*DVELF), - dy = (int)(d->vel.y*DVELF), - dz = (int)(d->vel.z*DVELF), + dxt = (int)(d->vel.x*DVELF), + dyt = (int)(d->vel.y*DVELF), + dzt = (int)(d->vel.z*DVELF), + dx = dxt - d->vel_t.i[0], + dy = dyt - d->vel_t.i[1], + dz = dzt - d->vel_t.i[2], // pack rest in 1 int: strafe:2, move:2, onfloor:1, onladder: 1 - f = (d->strafe&3) | ((d->move&3)<<2) | (((int)d->onfloor)<<4) | (((int)d->onladder)<<5) | ((d->lifesequence&1)<<6) | (((int)d->crouching)<<7); + f = (d->strafe&3) | ((d->move&3)<<2) | (((int)d->onfloor)<<4) | (((int)d->onladder)<<5) | ((d->lifesequence&1)<<6) | (((int)d->crouching)<<7), + vx = (dx*d->vel.i[0] > 0? 1 : 0), vy = (dy*d->vel.i[1] > 0? 1 : 0), vz = (dz*d->vel.i[2] > 0? 1 : 0), vr = (r ? 1 : 0), + g = (vx) | (vy<<1) | (vz<<2) | (vr<<3) | (((int)d->scoping)<<4); + d->vel_t.i[0] = dxt; + d->vel_t.i[1] = dyt; + d->vel_t.i[2] = dzt; int usefactor = sfactor < 7 ? 7 : sfactor, sizexy = 1 << (usefactor + 4); if(cn >= 0 && cn < 32 && usefactor <= 7 + 3 && // map size 7..10 @@ -363,7 +371,7 @@ void c2sinfo(playerent *d) // send update to the server ya >= 0 && ya < 512 && pi >= -128 && pi <= 127 && r >= -32 && r <= 31 && - dx >= -8 && dx <= 7 && + dx >= -8 && dx <= 7 && // FIXME dy >= -8 && dy <= 7 && dz >= -8 && dz <= 7) { // compact POS packet @@ -393,6 +401,7 @@ void c2sinfo(playerent *d) // send update to the server if(z >= (1 << s)) s = 11; b.putbits(1, s == 11 ? 1 : 0); b.putbits(s, z); + b.putbits(1, d->scoping ? 1 : 0); } else { // classic POS packet @@ -403,10 +412,11 @@ void c2sinfo(playerent *d) // send update to the server putuint(q, z); putuint(q, (int)d->yaw); putint(q, (int)d->pitch); - putint(q, (int)(125*d->roll/20)); - putint(q, dx); - putint(q, dy); - putint(q, dz); + putuint(q, g); + if (vr) putint(q, (int)(125*d->roll/20)); + if (vx) putint(q, dx); + if (vy) putint(q, dy); + if (vz) putint(q, dz); putuint(q, f); } sendpackettoserv(0, q.finalize()); diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index b8658866..c7c9f721 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -115,9 +115,10 @@ void parsepositions(ucharbuf &p) case SV_POS: // position of another client case SV_POSC: { - int cn, f; + int cn, f, g; vec o, vel; - float yaw, pitch, roll; + float yaw, pitch, roll = 0; + bool scoping; if(type == SV_POSC) { bitbuf q(p); @@ -144,6 +145,7 @@ void parsepositions(ucharbuf &p) int z = q.getbits(s); if(negz) z = -z; o.z = z / DMF; + scoping = ( q.getbits(1) ? true : false ); } else { @@ -153,10 +155,12 @@ void parsepositions(ucharbuf &p) o.z = getuint(p)/DMF; yaw = (float)getuint(p); pitch = (float)getint(p); - roll = (float)(getint(p)*20.0f/125.0f); - vel.x = getint(p)/DVELF; - vel.y = getint(p)/DVELF; - vel.z = getint(p)/DVELF; + g = getuint(p); + if ((g>>3) & 1) roll = (float)(getint(p)*20.0f/125.0f); + if (g & 1) vel.x = getint(p)/DVELF; + if ((g>>1) & 1) vel.y = getint(p)/DVELF; + if ((g>>2) & 1) vel.z = getint(p)/DVELF; + scoping = ( (g>>4) & 1 ? true : false ); f = getuint(p); } int seqcolor = (f>>6)&1; @@ -164,30 +168,13 @@ void parsepositions(ucharbuf &p) if(!d || seqcolor!=(d->lifesequence&1)) continue; vec oldpos(d->o); float oldyaw = d->yaw, oldpitch = d->pitch; - if ( !testvel ) d->vel = vel; - else - { - if ( d->last_pos > totalmillis ) - { - loopi(3) - { - // the idea here is to send only dv, instead of vel - float dv = vel.v[i] - d->vel_t.v[i]; - d->vel_t.v[i] = vel.v[i]; - float dr = o.v[i] - d->o.v[i] + ( i == 2 ? d->eyeheight : 0); - d->vel.v[i] = dr * 0.05f + d->vel.v[i] * 0.95f + ( dv * d->vel_t.v[i] > 0 ? dv : 0 ); - } - } - else loopi(3) d->vel.v[i] = 0.0f; - d->last_pos = totalmillis + 200; - } // printf("->>>>>> R %d %f %f %f %f %f %f\n",cn,vel.x,vel.y,vel.z,d->vel.x,d->vel.y,d->vel.z); d->o = o; d->o.z += d->eyeheight; d->yaw = yaw; d->pitch = pitch; + d->scoping = scoping; d->roll = roll; -// if (roll != 0) printf("roll: %f\n",roll); d->strafe = (f&3)==3 ? -1 : f&3; f >>= 2; d->move = (f&3)==3 ? -1 : f&3; @@ -196,6 +183,17 @@ void parsepositions(ucharbuf &p) f >>= 1; d->onladder = f&1; f >>= 2; + if ( d->last_pos > totalmillis ) + { + loopi(3) + { + float dr = o.v[i] - d->o.v[i] + ( i == 2 ? d->eyeheight : 0); + d->vel.v[i] = dr * 0.05f + d->vel.v[i] * 0.95f + vel.v[i]; + if ( i==2 && d->onfloor && d->vel.v[i] < 0 ) d->vel.v[i] = 0; + } + } + else loopi(3) d->vel.v[i] = 0.0f; + d->last_pos = totalmillis + 200; updatecrouch(d, f&1); updatepos(d); updatelagtime(d); diff --git a/source/src/entity.h b/source/src/entity.h index 7a4f7191..15dc3b82 100644 --- a/source/src/entity.h +++ b/source/src/entity.h @@ -104,7 +104,7 @@ public: int timeinair; // used for fake gravity float radius, eyeheight, maxeyeheight, aboveeye; // bounding box size bool inwater; - bool onfloor, onladder, jumpnext, crouching, crouchedinair, trycrouch, cancollide, stuck; + bool onfloor, onladder, jumpnext, crouching, crouchedinair, trycrouch, cancollide, stuck, scoping; int lastjump; int lastsplash; char move, strafe; @@ -113,7 +113,7 @@ public: int last_pos; physent() : o(0, 0, 0), deltapos(0, 0, 0), newpos(0, 0, 0), yaw(270), pitch(0), roll(0), pitchvel(0), - crouching(false), crouchedinair(false), trycrouch(false), cancollide(true), stuck(false), lastjump(0), lastsplash(0), state(CS_ALIVE), last_pos(0) + crouching(false), crouchedinair(false), trycrouch(false), cancollide(true), stuck(false), scoping(false), lastjump(0), lastsplash(0), state(CS_ALIVE), last_pos(0) { reset(); } diff --git a/source/src/protos.h b/source/src/protos.h index 06bbb000..32b9cbdd 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -792,6 +792,7 @@ struct serverconfigfile }; // server commandline parsing +extern int wait_afk; struct servercommandline { @@ -836,6 +837,7 @@ struct servercommandline } break; case 'A': if(*a) adminonlymaps.add(a); break; + case 'a': if (ai >= 0) wait_afk = ai * 1000; break; case 'c': if(ai > 0) maxclients = min(ai, MAXCLIENTS); break; case 'k': if(ai < 0) kickthreshold = ai; break; case 'y': if(ai < 0) banthreshold = ai; break; diff --git a/source/src/server.cpp b/source/src/server.cpp index 2c874999..56794782 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -2933,7 +2933,8 @@ void process(ENetPacket *packet, int sender, int chan) int val[3]; val[0] = getuint(p); val[1] = getint(p); - loopi(4) getint(p); + int g = getuint(p); // g + loopi(4) if ( (g >> i) & 1 ) getint(p); val[2] = getuint(p); if(!cl->isonrightmap) break; if(cl->type==ST_TCPIP && (cl->state.state==CS_ALIVE || cl->state.state==CS_EDITING)) @@ -2975,6 +2976,7 @@ void process(ENetPacket *packet, int sender, int chan) if(zfull) s = 11; int zt = q.getbits(s); if(negz) zt = -zt; + q.getbits(1); // scoping if(!cl->isonrightmap || p.remaining() || p.overread()) { p.flags = 0; break; } if(((f >> 6) & 1) != (cl->state.lifesequence & 1) || usefactor != (smapstats.hdr.sfactor < 7 ? 7 : smapstats.hdr.sfactor)) break; @@ -3516,7 +3518,7 @@ void serverslice(uint timeout) // main server update, called from cube main lo if(m_arena) arenacheck(); // if(m_lms) lmscheck(); sendextras(); - if ( mastermode == MM_OPEN && next_afk_check < servmillis && gamemillis > 20 * 1000 ) check_afk(); + if ( wait_afk && mastermode == MM_OPEN && next_afk_check < servmillis && gamemillis > 20 * 1000 ) check_afk(); } if(curvote) diff --git a/source/src/serverchecks.h b/source/src/serverchecks.h index b08edfb9..d0cd7982 100644 --- a/source/src/serverchecks.h +++ b/source/src/serverchecks.h @@ -438,7 +438,7 @@ void checkfrag (client *target, client *actor, int gun, bool gib) } } -int next_afk_check = 200; +int next_afk_check = 200, wait_afk = 45 * 1000; void check_afk() { @@ -448,7 +448,7 @@ void check_afk() { client &c = *clients[i]; if ( c.type != ST_TCPIP || c.connectmillis + 60 * 1000 > servmillis || - c.inputmillis + 45 * 1000 > servmillis || clienthasflag(c.clientnum) != -1 ) continue; + c.inputmillis + wait_afk > servmillis || clienthasflag(c.clientnum) != -1 ) continue; if ( ( c.state.state == CS_DEAD && !m_arena && c.state.lastdeath + 45 * 1000 < gamemillis) || ( c.state.state == CS_ALIVE && c.upspawnp ) || ( c.state.state == CS_SPECTATE ) ) {