http://sourceforge.net/p/sauerbraten/code/4699/ --- a/src/shared/iengine.h +++ b/src/shared/iengine.h @@ -415,23 +415,6 @@ extern int getservermtu(); extern int getnumclients(); extern uint getclientip(int n); -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 putuint(ucharbuf &p, int n); -extern void putuint(packetbuf &p, int n); -extern void putuint(vector &p, int n); -extern int getuint(ucharbuf &p); -extern void putfloat(ucharbuf &p, float f); -extern void putfloat(packetbuf &p, float f); -extern void putfloat(vector &p, float f); -extern float getfloat(ucharbuf &p); -extern void sendstring(const char *t, ucharbuf &p); -extern void sendstring(const char *t, packetbuf &p); -extern void sendstring(const char *t, vector &p); -extern void getstring(char *t, ucharbuf &p, int len = MAXTRANS); -extern void filtertext(char *dst, const char *src, bool whitespace = true, int len = sizeof(string)-1); extern void localconnect(); extern const char *disconnectreason(int reason); extern void disconnect_client(int n, int reason); --- a/src/engine/server.cpp +++ b/src/engine/server.cpp @@ -99,125 +99,6 @@ va_end(args); } #endif - -// all network traffic is in 32bit ints, which are then compressed using the following simple scheme (assumes that most values are small). - -template -static inline void putint_(T &p, int n) -{ - if(n<128 && n>-127) p.put(n); - else if(n<0x8000 && n>=-0x8000) { 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 putint(ucharbuf &p, int n) { putint_(p, n); } -void putint(packetbuf &p, int n) { putint_(p, n); } -void putint(vector &p, int n) { putint_(p, n); } - -int getint(ucharbuf &p) -{ - int c = (char)p.get(); - if(c==-128) { int n = p.get(); n |= char(p.get())<<8; return n; } - else if(c==-127) { int n = p.get(); n |= p.get()<<8; n |= p.get()<<16; return n|(p.get()<<24); } - else 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) -{ - if(n < 0 || n >= (1<<21)) - { - p.put(0x80 | (n & 0x7F)); - p.put(0x80 | ((n >> 7) & 0x7F)); - p.put(0x80 | ((n >> 14) & 0x7F)); - p.put(n >> 21); - } - else if(n < (1<<7)) p.put(n); - else if(n < (1<<14)) - { - p.put(0x80 | (n & 0x7F)); - p.put(n >> 7); - } - else - { - p.put(0x80 | (n & 0x7F)); - p.put(0x80 | ((n >> 7) & 0x7F)); - p.put(n >> 14); - } -} -void putuint(ucharbuf &p, int n) { putuint_(p, n); } -void putuint(packetbuf &p, int n) { putuint_(p, n); } -void putuint(vector &p, int n) { putuint_(p, n); } - -int getuint(ucharbuf &p) -{ - int n = p.get(); - if(n & 0x80) - { - n += (p.get() << 7) - 0x80; - if(n & (1<<14)) n += (p.get() << 14) - (1<<14); - if(n & (1<<21)) n += (p.get() << 21) - (1<<21); - if(n & (1<<28)) n |= -1<<28; - } - return n; -} - -template -static inline void putfloat_(T &p, float f) -{ - lilswap(&f, 1); - p.put((uchar *)&f, sizeof(float)); -} -void putfloat(ucharbuf &p, float f) { putfloat_(p, f); } -void putfloat(packetbuf &p, float f) { putfloat_(p, f); } -void putfloat(vector &p, float f) { putfloat_(p, f); } - -float getfloat(ucharbuf &p) -{ - float f; - p.get((uchar *)&f, sizeof(float)); - return lilswap(f); -} - -template -static inline void sendstring_(const char *t, T &p) -{ - while(*t) putint(p, *t++); - putint(p, 0); -} -void sendstring(const char *t, ucharbuf &p) { sendstring_(t, p); } -void sendstring(const char *t, packetbuf &p) { sendstring_(t, p); } -void sendstring(const char *t, vector &p) { sendstring_(t, p); } - -void getstring(char *text, ucharbuf &p, int len) -{ - char *t = text; - do - { - if(t>=&text[len]) { text[len-1] = 0; return; } - if(!p.remaining()) { *t = 0; return; } - *t = getint(p); - } - while(*t++); -} - -void filtertext(char *dst, const char *src, bool whitespace, int len) -{ - for(int c = uchar(*src); c; c = uchar(*++src)) - { - if(c == '\f') - { - if(!*++src) break; - continue; - } - if(iscubeprint(c) || (iscubespace(c) && whitespace)) - { - *dst++ = c; - if(!--len) break; - } - } - *dst = '\0'; -} enum { ST_EMPTY, ST_LOCAL, ST_TCPIP }; --- a/src/shared/tools.h +++ b/src/shared/tools.h @@ -1178,5 +1178,24 @@ extern uint randomMT(); extern int guessnumcpus(); -#endif - +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 putuint(ucharbuf &p, int n); +extern void putuint(packetbuf &p, int n); +extern void putuint(vector &p, int n); +extern int getuint(ucharbuf &p); +extern void putfloat(ucharbuf &p, float f); +extern void putfloat(packetbuf &p, float f); +extern void putfloat(vector &p, float f); +extern float getfloat(ucharbuf &p); +extern void sendstring(const char *t, ucharbuf &p); +extern void sendstring(const char *t, packetbuf &p); +extern void sendstring(const char *t, vector &p); +extern void getstring(char *t, ucharbuf &p, int len); +template static inline void getstring(T (&t)[N], ucharbuf &p) { getstring(t, p, N); } +extern void filtertext(char *dst, const char *src, bool whitespace = true, int len = sizeof(string)-1); + +#endif + --- a/src/engine/master.cpp +++ b/src/engine/master.cpp @@ -514,7 +514,7 @@ authreq &a = c.authreqs.add(); a.reqtime = servtime; a.id = id; - uint seed[3] = { starttime, servtime, randomMT() }; + uint seed[3] = { uint(starttime), servtime, randomMT() }; static vector buf; buf.setsize(0); a.answer = genchallenge(u->pubkey, seed, sizeof(seed), buf); --- a/src/shared/tools.cpp +++ b/src/shared/tools.cpp @@ -53,3 +53,124 @@ return y; } +///////////////////////// network /////////////////////// + +// all network traffic is in 32bit ints, which are then compressed using the following simple scheme (assumes that most values are small). + +template +static inline void putint_(T &p, int n) +{ + if(n<128 && n>-127) p.put(n); + else if(n<0x8000 && n>=-0x8000) { 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 putint(ucharbuf &p, int n) { putint_(p, n); } +void putint(packetbuf &p, int n) { putint_(p, n); } +void putint(vector &p, int n) { putint_(p, n); } + +int getint(ucharbuf &p) +{ + int c = (char)p.get(); + if(c==-128) { int n = p.get(); n |= char(p.get())<<8; return n; } + else if(c==-127) { int n = p.get(); n |= p.get()<<8; n |= p.get()<<16; return n|(p.get()<<24); } + else 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) +{ + if(n < 0 || n >= (1<<21)) + { + p.put(0x80 | (n & 0x7F)); + p.put(0x80 | ((n >> 7) & 0x7F)); + p.put(0x80 | ((n >> 14) & 0x7F)); + p.put(n >> 21); + } + else if(n < (1<<7)) p.put(n); + else if(n < (1<<14)) + { + p.put(0x80 | (n & 0x7F)); + p.put(n >> 7); + } + else + { + p.put(0x80 | (n & 0x7F)); + p.put(0x80 | ((n >> 7) & 0x7F)); + p.put(n >> 14); + } +} +void putuint(ucharbuf &p, int n) { putuint_(p, n); } +void putuint(packetbuf &p, int n) { putuint_(p, n); } +void putuint(vector &p, int n) { putuint_(p, n); } + +int getuint(ucharbuf &p) +{ + int n = p.get(); + if(n & 0x80) + { + n += (p.get() << 7) - 0x80; + if(n & (1<<14)) n += (p.get() << 14) - (1<<14); + if(n & (1<<21)) n += (p.get() << 21) - (1<<21); + if(n & (1<<28)) n |= -1<<28; + } + return n; +} + +template +static inline void putfloat_(T &p, float f) +{ + lilswap(&f, 1); + p.put((uchar *)&f, sizeof(float)); +} +void putfloat(ucharbuf &p, float f) { putfloat_(p, f); } +void putfloat(packetbuf &p, float f) { putfloat_(p, f); } +void putfloat(vector &p, float f) { putfloat_(p, f); } + +float getfloat(ucharbuf &p) +{ + float f; + p.get((uchar *)&f, sizeof(float)); + return lilswap(f); +} + +template +static inline void sendstring_(const char *t, T &p) +{ + while(*t) putint(p, *t++); + putint(p, 0); +} +void sendstring(const char *t, ucharbuf &p) { sendstring_(t, p); } +void sendstring(const char *t, packetbuf &p) { sendstring_(t, p); } +void sendstring(const char *t, vector &p) { sendstring_(t, p); } + +void getstring(char *text, ucharbuf &p, int len) +{ + char *t = text; + do + { + if(t>=&text[len]) { text[len-1] = 0; return; } + if(!p.remaining()) { *t = 0; return; } + *t = getint(p); + } + while(*t++); +} + +void filtertext(char *dst, const char *src, bool whitespace, int len) +{ + for(int c = uchar(*src); c; c = uchar(*++src)) + { + if(c == '\f') + { + if(!*++src) break; + continue; + } + if(iscubeprint(c) || (iscubespace(c) && whitespace)) + { + *dst++ = c; + if(!--len) break; + } + } + *dst = '\0'; +} +