diff --git a/source/src/client.cpp b/source/src/client.cpp index ab4416d0..dd594630 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -385,6 +385,13 @@ void addmsg(int type, const char *fmt, ...) numi += n; break; } + case 'a': + { + int n = isdigit(*fmt) ? *fmt++-'0' : 1; + loopi(n) putaint(p, va_arg(args, int)); + numi += n; + break; + } case 's': { const char *t = va_arg(args, const char *); diff --git a/source/src/protocol.cpp b/source/src/protocol.cpp index 4af51532..bcd75c39 100644 --- a/source/src/protocol.cpp +++ b/source/src/protocol.cpp @@ -34,6 +34,32 @@ int getint(ucharbuf &p) } } +// special encoding for asymmetric small integers: -1..252 go into one byte, -256..65279 go into three bytes and any other int goes into five bytes +// (the network encoding is compatible with basic getint) +template +static inline void putaint_(T &p, int n) +{ + DEBUGVAR(n); + if(n<253 && n>-2) p.put(n - 125); + else if(n<0xFF00 && n>=-256) { n += 256; p.put(0x80); p.put(n); p.put(n>>8); } + else { p.put(0x81); p.put(n); p.put(n>>8); p.put(n>>16); p.put(n>>24); } +} +void putaint(ucharbuf &p, int n) { putaint_(p, n); } +void putaint(packetbuf &p, int n) { putaint_(p, n); } +void putaint(vector &p, int n) { putaint_(p, n); } + +int getaint(ucharbuf &p) +{ + int c = ((char)p.get()) + 125; + if(c==-128) { int n = p.get(); n |= p.get()<<8; n -= 256; DEBUGVAR(n); return n; } + else if(c==-127) { int n = p.get(); n |= p.get()<<8; n |= p.get()<<16; n |= (p.get()<<24); DEBUGVAR(n); return n; } + else + { + DEBUGVAR(c); + return c; + } +} + // much smaller encoding for unsigned integers up to 28 bits, but can handle signed template static inline void putuint_(T &p, int n) diff --git a/source/src/protos.h b/source/src/protos.h index 098b94a1..df003804 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -1038,6 +1038,10 @@ extern void putint(ucharbuf &p, int n); extern void putint(packetbuf &p, int n); extern void putint(vector &p, int n); extern int getint(ucharbuf &p); +extern void putaint(ucharbuf &p, int n); +extern void putaint(packetbuf &p, int n); +extern void putaint(vector &p, int n); +extern int getaint(ucharbuf &p); extern void putuint(ucharbuf &p, int n); extern void putuint(packetbuf &p, int n); extern void putuint(vector &p, int n); diff --git a/source/src/server.cpp b/source/src/server.cpp index 168d9995..5e905c9c 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -440,6 +440,12 @@ void sendf(int cn, int chan, const char *format, ...) loopi(n) putint(p, va_arg(args, int)); break; } + case 'a': + { + int n = isdigit(*format) ? *format++-'0' : 1; + loopi(n) putaint(p, va_arg(args, int)); + break; + } case 's': sendstring(va_arg(args, const char *), p); break; case 'm': {