more robust SV_POSC parsing
git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@4617 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
+19
-20
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
+8
-10
@@ -193,22 +193,22 @@ struct databuf
|
||||
typedef databuf<char> charbuf;
|
||||
typedef databuf<uchar> 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 <class T> struct vector
|
||||
|
||||
Reference in New Issue
Block a user