diff --git a/source/src/client.cpp b/source/src/client.cpp index 788fdd04..6ce5e2e5 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -339,6 +339,7 @@ void c2sinfo(playerent *d) // send update to the server if(d->state==CS_ALIVE || d->state==CS_EDITING) { ENetPacket *packet = enet_packet_create(NULL, 100, 0); + ucharbuf q(packet->data, packet->dataLength); int cn = d->clientnum, x = (int)(d->o.x*DMF), // quantize coordinates to 1/16th of a cube, between 1 and 3 bytes y = (int)(d->o.y*DMF), @@ -364,35 +365,33 @@ void c2sinfo(playerent *d) // send update to the server dz >= -8 && dz <= 7) { // compact POS packet bool noroll = !r, novel = !dx && !dy && !dz; - bitbuf q(packet->data, packet->dataLength); + bitbuf b(&q); putint(q, SV_POSC); - q.putbits(5, cn); - q.putbits(sfactor + 4, x); - q.putbits(sfactor + 4, y); - q.putbits(9, ya); - q.putbits(8, pi + 128); - q.putbits(1, noroll ? 1 : 0); - if(!noroll) q.putbits(6, r + 32); - q.putbits(1, novel ? 1 : 0); + b.putbits(5, cn); + b.putbits(sfactor + 4, x); + b.putbits(sfactor + 4, y); + b.putbits(9, ya); + b.putbits(8, pi + 128); + b.putbits(1, noroll ? 1 : 0); + if(!noroll) b.putbits(6, r + 32); + b.putbits(1, novel ? 1 : 0); if(!novel) { - q.putbits(4, dx + 8); - q.putbits(4, dy + 8); - q.putbits(4, dz + 8); + b.putbits(4, dx + 8); + b.putbits(4, dy + 8); + b.putbits(4, dz + 8); } - q.putbits(8, f); - q.putbits(1, z < 0 ? 1 : 0); + b.putbits(8, f); + b.putbits(1, z < 0 ? 1 : 0); if(z < 0) z = -z; // z is encoded with 3..10 bits minimum (fitted to byte boundaries), or full 11 bits if necessary - int s = (q.rembits() - 1 + 8) % 8; + int s = (b.rembits() - 1 + 8) % 8; if(s < 3) s += 8; if(z >= (1 << s)) s = 11; - q.putbits(1, s == 11 ? 1 : 0); - q.putbits(s, z); - enet_packet_resize(packet, q.length()); + b.putbits(1, s == 11 ? 1 : 0); + b.putbits(s, z); } else { // classic POS packet - ucharbuf q(packet->data, packet->dataLength); putint(q, SV_POS); putint(q, d->clientnum); putuint(q, x); @@ -405,8 +404,8 @@ void c2sinfo(playerent *d) // send update to the server putint(q, dy); putint(q, dz); putuint(q, f); - enet_packet_resize(packet, q.length()); } + enet_packet_resize(packet, q.length()); sendpackettoserv(0, packet); } diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index f060e292..5174fb80 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -114,7 +114,7 @@ void parsepositions(ucharbuf &p) float yaw, pitch, roll; if(type == SV_POSC) { - bitbuf q(p.buf + p.length(), p.remaining()); + bitbuf q(&p); cn = q.getbits(5); o.x = q.getbits(sfactor + 4) / DMF; o.y = q.getbits(sfactor + 4) / DMF; @@ -137,7 +137,6 @@ void parsepositions(ucharbuf &p) int z = q.getbits(s); if(negz) z = -z; o.z = z / DMF; - p.len += q.length(); } else { diff --git a/source/src/server.cpp b/source/src/server.cpp index 3b582737..74de4791 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -2447,7 +2447,7 @@ void process(ENetPacket *packet, int sender, int chan) bool spawn = false; if(team_isspect(cl->team)) { - if(numclients() < 2 && !m_demo) + if(numclients() < 2 && !m_demo && mastermode != MM_MATCH) { // spawn on empty servers spawn = updateclientteam(cl->clientnum, TEAM_ANYACTIVE, FTR_INFO); } @@ -2667,7 +2667,7 @@ void process(ENetPacket *packet, int sender, int chan) case SV_POSC: { - bitbuf q(p.buf + p.length(), p.remaining()); + bitbuf q(&p); int cn = q.getbits(5); if(cn!=sender) { @@ -2690,8 +2690,7 @@ void process(ENetPacket *packet, int sender, int chan) int z = q.getbits(s); if(negz) z = -z; cl->state.o[2] = z/DMF; - p.len += q.length(); - if(!cl->isonrightmap) break; + if(!cl->isonrightmap || p.remaining() || p.overread()) { p.flags = 0; break; } if(cl->type==ST_TCPIP && (cl->state.state==CS_ALIVE || cl->state.state==CS_EDITING)) { cl->position.setsizenodelete(0); diff --git a/source/src/tools.h b/source/src/tools.h index 9c291847..763d9285 100644 --- a/source/src/tools.h +++ b/source/src/tools.h @@ -193,22 +193,22 @@ struct databuf typedef databuf charbuf; typedef databuf ucharbuf; -struct bitbuf : ucharbuf +struct bitbuf { + ucharbuf *q; int blen; - uchar *cur; - bitbuf(unsigned char *buf, int maxlen) : ucharbuf(buf, maxlen), blen(0) {} + bitbuf(ucharbuf *oq) : q(oq), blen(0) {} int getbits(int n) { int res = 0, p = 0; while(n > 0) { - if(!blen) cur = (uchar *)&get(); + if(!blen) q->get(); int r = 8 - blen; if(r > n) r = n; - res |= ((*cur >> blen) & ((1 << r) - 1)) << p; + res |= ((q->buf[q->len - 1] >> blen) & ((1 << r) - 1)) << p; n -= r; p += r; blen = (blen + r) % 8; } @@ -217,20 +217,18 @@ struct bitbuf : ucharbuf void putbits(int n, int v) { - if(8 * remaining() < n) { flags |= OVERWROTE; return; } while(n > 0) { - if(!blen) put(0); - cur = (uchar *)buf + len - 1; + if(!blen) { q->put(0); if(q->overwrote()) return; } int r = 8 - blen; if(r > n) r = n; - *cur |= (v & ((1 << r) - 1)) << blen; + q->buf[q->len - 1] |= (v & ((1 << r) - 1)) << blen; n -= r; v >>= r; blen = (blen + r) % 8; } } - int rembits() { return (8 - blen) % 8; } + int rembits() { return (8 - blen) % 8; } // 0..7 bits remaining in current byte }; template struct vector