From 9fca17a7a98b497617203eff29a6db71872ebea7 Mon Sep 17 00:00:00 2001 From: ac_stef Date: Sun, 9 Aug 2009 20:34:09 +0000 Subject: [PATCH] compact pos packets are now parseable out of context; all-whitespace chat gets suppressed git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@4620 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/client.cpp | 19 +++++++---- source/src/clients2c.cpp | 5 +-- source/src/protocol.cpp | 10 ++++-- source/src/protos.h | 1 + source/src/server.cpp | 72 ++++++++++++++++++++++++---------------- 5 files changed, 68 insertions(+), 39 deletions(-) diff --git a/source/src/client.cpp b/source/src/client.cpp index 7e3e8a54..ea3c7e22 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -220,10 +220,15 @@ void _toserver(char *text, int msg, int msgt) bool toteam = text && text[0] == '%' && (m_teammode || team_isspect(player1->team)); if(!toteam && text[0] == '%' && strlen(text) > 1) text++; // convert team-text to normal-text if no team-mode is active if(toteam) text++; + filtertext(text, text); + trimtrailingwhitespace(text); if(servstate.mastermode == MM_MATCH && servstate.matchteamsize && !team_isactive(player1->team) && !(player1->team == TEAM_SPECT && player1->clientrole == CR_ADMIN)) toteam = true; // spect chat - if(msg == SV_TEXTME) conoutf("\f%d%s %s", toteam ? 1 : 0, colorname(player1), highlight(text)); - else conoutf("%s:\f%d %s", colorname(player1), toteam ? 1 : 0, highlight(text)); - addmsg(toteam ? msgt : msg, "rs", text); + if(*text) + { + if(msg == SV_TEXTME) conoutf("\f%d%s %s", toteam ? 1 : 0, colorname(player1), highlight(text)); + else conoutf("%s:\f%d %s", colorname(player1), toteam ? 1 : 0, highlight(text)); + addmsg(toteam ? msgt : msg, "rs", text); + } } void toserver(char *text) @@ -353,8 +358,9 @@ void c2sinfo(playerent *d) // send update to the server dz = (int)(d->vel.z*DVELF), // 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); - int sizexy = 1 << (sfactor + 4); + int usefactor = sfactor < 7 ? 7 : sfactor, sizexy = 1 << (usefactor + 4); if(cn >= 0 && cn < 32 && + usefactor <= 7 + 3 && // map size 7..10 x >= 0 && x < sizexy && y >= 0 && y < sizexy && z >= -2047 && z <= 2047 && @@ -369,8 +375,9 @@ void c2sinfo(playerent *d) // send update to the server bitbuf b(&q); putint(q, SV_POSC); b.putbits(5, cn); - b.putbits(sfactor + 4, x); - b.putbits(sfactor + 4, y); + b.putbits(2, usefactor - 7); + b.putbits(usefactor + 4, x); + b.putbits(usefactor + 4, y); b.putbits(9, ya); b.putbits(8, pi + 128); b.putbits(1, noroll ? 1 : 0); diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 5174fb80..187dae1f 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -116,8 +116,9 @@ void parsepositions(ucharbuf &p) { bitbuf q(&p); cn = q.getbits(5); - o.x = q.getbits(sfactor + 4) / DMF; - o.y = q.getbits(sfactor + 4) / DMF; + int usefactor = q.getbits(2) + 7; + o.x = q.getbits(usefactor + 4) / DMF; + o.y = q.getbits(usefactor + 4) / DMF; yaw = q.getbits(9) * 360.0f / 512; pitch = (q.getbits(8) - 128) * 90.0f / 127; roll = !q.getbits(1) ? (q.getbits(6) - 32) * 20.0f / 31 : 0.0f; diff --git a/source/src/protocol.cpp b/source/src/protocol.cpp index 39264013..8f70fc1c 100644 --- a/source/src/protocol.cpp +++ b/source/src/protocol.cpp @@ -94,7 +94,7 @@ void getstring(char *text, ucharbuf &p, int len) #define follower(x) (((x) & 0xc0) == 0x80) -int getutf8char(const unsigned char *&s) +int getutf8char(const uchar *&s) { int res = *s++; if(res < 0x80) return res; @@ -140,7 +140,7 @@ int getutf8char(const unsigned char *&s) return -1; } -int pututf8char(unsigned char *&d, int s) +int pututf8char(uchar *&d, int s) { if(s < 0 || s > 0x1fffff) return 0; if(s < 0x80) @@ -246,6 +246,12 @@ void filterlang(char *d, const char *s) *d = '\0'; } +void trimtrailingwhitespace(char *s) +{ + for(int n = strlen(s) - 1; n >= 0 && isspace(s[n]); n--) + s[n] = '\0'; +} + void cutcolorstring(char *text, int len) { // limit string length, ignore color codes while(*text) diff --git a/source/src/protos.h b/source/src/protos.h index bfe62a2c..e337dee4 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -704,6 +704,7 @@ extern void filtertext(char *dst, const char *src, int whitespace = 1, int len = extern void filterrichtext(char *dst, const char *src, int len = sizeof(string)-1); extern void filterservdesc(char *dst, const char *src, int len = sizeof(string)-1); extern void filterlang(char *d, const char *s); +extern void trimtrailingwhitespace(char *s); extern void cutcolorstring(char *text, int len); extern void startintermission(); extern void restoreserverstate(vector &ents); diff --git a/source/src/server.cpp b/source/src/server.cpp index 74de4791..c7dec8fe 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -2344,15 +2344,19 @@ void process(ENetPacket *packet, int sender, int chan) case SV_TEAMTEXT: getstring(text, p); filtertext(text, text); - if(!spamdetect(cl, text)) - { // team chat - logline(ACLOG_INFO, "[%s] %s%s says to team %s: '%s'", cl->hostname, type == SV_TEAMTEXTME ? "(me) " : "", cl->name, team_string(cl->team), text); - sendteamtext(text, sender, type); - } - else + trimtrailingwhitespace(text); + if(*text) { - logline(ACLOG_INFO, "[%s] %s%s says to team %s: '%s', SPAM detected", cl->hostname, type == SV_TEAMTEXTME ? "(me) " : "", cl->name, team_string(cl->team), text); - sendservmsg("\f3please do not spam", sender); + if(!spamdetect(cl, text)) + { // team chat + logline(ACLOG_INFO, "[%s] %s%s says to team %s: '%s'", cl->hostname, type == SV_TEAMTEXTME ? "(me) " : "", cl->name, team_string(cl->team), text); + sendteamtext(text, sender, type); + } + else + { + logline(ACLOG_INFO, "[%s] %s%s says to team %s: '%s', SPAM detected", cl->hostname, type == SV_TEAMTEXTME ? "(me) " : "", cl->name, team_string(cl->team), text); + sendservmsg("\f3please do not spam", sender); + } } break; @@ -2362,25 +2366,29 @@ void process(ENetPacket *packet, int sender, int chan) int mid1 = curmsg, mid2 = p.length(); getstring(text, p); filtertext(text, text); - if(!spamdetect(cl, text)) + trimtrailingwhitespace(text); + if(*text) { - if(mastermode != MM_MATCH || !matchteamsize || team_isactive(cl->team) || (cl->team == TEAM_SPECT && cl->role == CR_ADMIN)) - { // common chat - logline(ACLOG_INFO, "[%s] %s%s says: '%s'", cl->hostname, type == SV_TEXTME ? "(me) " : "", cl->name, text); - if(cl->type==ST_TCPIP) while(mid1messages.add(p.buf[mid1++]); - QUEUE_STR(text); + if(!spamdetect(cl, text)) + { + if(mastermode != MM_MATCH || !matchteamsize || team_isactive(cl->team) || (cl->team == TEAM_SPECT && cl->role == CR_ADMIN)) + { // common chat + logline(ACLOG_INFO, "[%s] %s%s says: '%s'", cl->hostname, type == SV_TEXTME ? "(me) " : "", cl->name, text); + if(cl->type==ST_TCPIP) while(mid1messages.add(p.buf[mid1++]); + QUEUE_STR(text); + } + else + { // spect chat + logline(ACLOG_INFO, "[%s] %s%s says to team %s: '%s'", cl->hostname, type == SV_TEAMTEXTME ? "(me) " : "", cl->name, team_string(cl->team), text); + sendteamtext(text, sender, type == SV_TEXTME ? SV_TEAMTEXTME : SV_TEAMTEXT); + } } else - { // spect chat - logline(ACLOG_INFO, "[%s] %s%s says to team %s: '%s'", cl->hostname, type == SV_TEAMTEXTME ? "(me) " : "", cl->name, team_string(cl->team), text); - sendteamtext(text, sender, type == SV_TEXTME ? SV_TEAMTEXTME : SV_TEAMTEXT); + { + logline(ACLOG_INFO, "[%s] %s%s says: '%s', SPAM detected", cl->hostname, type == SV_TEXTME ? "(me) " : "", cl->name, text); + sendservmsg("\f3please do not spam", sender); } } - else - { - logline(ACLOG_INFO, "[%s] %s%s says: '%s', SPAM detected", cl->hostname, type == SV_TEXTME ? "(me) " : "", cl->name, text); - sendservmsg("\f3please do not spam", sender); - } break; } @@ -2677,20 +2685,26 @@ void process(ENetPacket *packet, int sender, int chan) #endif return; } - loopi(2) cl->state.o[i] = q.getbits(smapstats.hdr.sfactor + 4)/DMF; + int usefactor = q.getbits(2) + 7; + int xt = q.getbits(usefactor + 4); + int yt = q.getbits(usefactor + 4); q.getbits(9 + 8); if(!q.getbits(1)) q.getbits(6); if(!q.getbits(1)) q.getbits(4 + 4 + 4); - q.getbits(8); + int f = q.getbits(8); int negz = q.getbits(1); - int full = q.getbits(1); + int zfull = q.getbits(1); int s = q.rembits(); if(s < 3) s += 8; - if(full) s = 11; - int z = q.getbits(s); - if(negz) z = -z; - cl->state.o[2] = z/DMF; + if(zfull) s = 11; + int zt = q.getbits(s); + if(negz) zt = -zt; + 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; + cl->state.o[0] = xt / DMF; + cl->state.o[1] = yt / DMF; + cl->state.o[2] = zt / DMF; if(cl->type==ST_TCPIP && (cl->state.state==CS_ALIVE || cl->state.state==CS_EDITING)) { cl->position.setsizenodelete(0);