UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
netpack.cpp
Go to the documentation of this file.
1 
5 /*
6 Copyright (C) 1997-2001 Id Software, Inc.
7 
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16 
17 See the GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 
23 */
24 
25 #include "common.h"
26 
27 const vec3_t bytedirs[] = {
28 #include "../shared/vertex_normals.h"
29 };
30 
31 static const float POSSCALE = 32.0f;
32 
33 void NET_WriteChar (dbuffer* buf, char c)
34 {
35  buf->add(&c, 1);
36  Com_DPrintf(DEBUG_EVENTSYS, "char event data: %s (%i)\n", Com_ByteToBinary(c), c);
37 }
38 
40 {
41  buf->add((const char*)&c, 1);
42  Com_DPrintf(DEBUG_EVENTSYS, "byte event data: %s (%i)\n", Com_ByteToBinary(c), c);
43 }
44 
45 void NET_WriteShort (dbuffer* buf, int c)
46 {
47  const unsigned short v = LittleShort(c);
48  buf->add((const char*)&v, 2);
49  Com_DPrintf(DEBUG_EVENTSYS, "short event data: %i\n", c);
50 }
51 
52 void NET_WriteLong (dbuffer* buf, int c)
53 {
54  const int v = LittleLong(c);
55  buf->add((const char*)&v, 4);
56  Com_DPrintf(DEBUG_EVENTSYS, "long event data: %i\n", c);
57 }
58 
59 void NET_WriteString (dbuffer* buf, const char* str)
60 {
61  if (!str)
62  buf->add("", 1);
63  else
64  buf->add(str, strlen(str) + 1);
65  Com_DPrintf(DEBUG_EVENTSYS, "string event data: %s\n", str);
66 }
67 
71 void NET_WriteRawString (dbuffer* buf, const char* str)
72 {
73  if (!str)
74  return;
75  buf->add(str, strlen(str));
76  Com_DPrintf(DEBUG_EVENTSYS, "string raw event data: %s\n", str);
77 }
78 
79 void NET_WriteCoord (dbuffer* buf, float f)
80 {
81  NET_WriteLong(buf, (int) (f * 32));
82 }
83 
87 void NET_Write2Pos (dbuffer* buf, const vec2_t pos)
88 {
89  NET_WriteLong(buf, (long) (pos[0] * POSSCALE));
90  NET_WriteLong(buf, (long) (pos[1] * POSSCALE));
91 }
92 
96 void NET_WritePos (dbuffer* buf, const vec3_t pos)
97 {
98  NET_WriteLong(buf, (long) (pos[0] * POSSCALE));
99  NET_WriteLong(buf, (long) (pos[1] * POSSCALE));
100  NET_WriteLong(buf, (long) (pos[2] * POSSCALE));
101 }
102 
103 void NET_WriteGPos (dbuffer* buf, const pos3_t pos)
104 {
105  NET_WriteByte(buf, pos[0]);
106  NET_WriteByte(buf, pos[1]);
107  NET_WriteByte(buf, pos[2]);
108 }
109 
110 void NET_WriteAngle (dbuffer* buf, float f)
111 {
112  NET_WriteByte(buf, (int) (f * 256 / 360) & 255);
113 }
114 
116 {
117  NET_WriteShort(buf, ANGLE2SHORT(f));
118 }
119 
124 void NET_WriteDir (dbuffer* buf, const vec3_t dir)
125 {
126  if (!dir) {
127  NET_WriteByte(buf, 0);
128  return;
129  }
130 
131  float bestd = 0.0f;
132  int best = 0;
133  const size_t bytedirsLength = lengthof(bytedirs);
134  for (int i = 0; i < bytedirsLength; i++) {
135  const float d = DotProduct(dir, bytedirs[i]);
136  if (d > bestd) {
137  bestd = d;
138  best = i;
139  }
140  }
141  NET_WriteByte(buf, best);
142 }
143 
149 void NET_vWriteFormat (dbuffer* buf, const char* format, va_list ap)
150 {
151  while (*format) {
152  const char typeID = *format++;
153 
154  switch (typeID) {
155  case 'c':
156  NET_WriteChar(buf, va_arg(ap, int));
157  break;
158  case 'b':
159  NET_WriteByte(buf, va_arg(ap, int));
160  break;
161  case 's':
162  NET_WriteShort(buf, va_arg(ap, int));
163  break;
164  case 'l':
165  NET_WriteLong(buf, va_arg(ap, int));
166  break;
167  case 'p':
168  NET_WritePos(buf, va_arg(ap, float*));
169  break;
170  case 'g':
171  NET_WriteGPos(buf, va_arg(ap, byte*));
172  break;
173  case 'd':
174  NET_WriteDir(buf, va_arg(ap, float*));
175  break;
176  case 'a':
177  /* NOTE: float is promoted to double through ... */
178  NET_WriteAngle(buf, va_arg(ap, double));
179  break;
180  case '!':
181  break;
182  case '&':
183  NET_WriteString(buf, va_arg(ap, char*));
184  break;
185  case '*': {
186  const int n = va_arg(ap, int);
187  const byte* p = va_arg(ap, byte*);
188  NET_WriteShort(buf, n);
189  for (int i = 0; i < n; i++)
190  NET_WriteByte(buf, *p++);
191  break;
192  }
193  default:
194  Com_Error(ERR_DROP, "WriteFormat: Unknown type!");
195  }
196  }
197  /* Too many arguments for the given format; too few cause crash above */
198 #ifdef PARANOID
199  if (!ap)
200  Com_Error(ERR_DROP, "WriteFormat: Too many arguments!");
201 #endif
202 }
203 
207 void NET_WriteFormat (dbuffer* buf, const char* format, ...)
208 {
209  va_list ap;
210  va_start(ap, format);
211  NET_vWriteFormat(buf, format, ap);
212  va_end(ap);
213 }
214 
215 
216 /* reading functions */
217 
222 {
223  char c;
224  if (buf->extract(&c, 1) == 0)
225  return -1;
226  return c;
227 }
228 
235 {
236  unsigned char c;
237  if (buf->extract((char*)&c, 1) == 0)
238  return -1;
239  return c;
240 }
241 
243 {
244  unsigned short v;
245  if (buf->extract((char*)&v, 2) < 2)
246  return -1;
247 
248  return LittleShort(v);
249 }
250 
252 {
253  unsigned char c;
254  if (buf->get((char*)&c, 1) == 0)
255  return -1;
256  return c;
257 }
258 
265 {
266  uint16_t v;
267  if (buf->get((char*)&v, 2) < 2)
268  return -1;
269 
270  return LittleShort(v);
271 }
272 
274 {
275  uint32_t v;
276  if (buf->get((char*)&v, 4) < 4)
277  return -1;
278 
279  return LittleLong(v);
280 }
281 
283 {
284  unsigned int v;
285  if (buf->extract((char*)&v, 4) < 4)
286  return -1;
287 
288  return LittleLong(v);
289 }
290 
302 int NET_ReadString (dbuffer* buf, char* string, size_t length)
303 {
304  unsigned int l = 0;
305 
306  for (;;) {
307  int c = NET_ReadByte(buf);
308  if (c == -1 || c == 0)
309  break;
310  if (string && l < length - 1) {
311  /* translate all format specs to avoid crash bugs */
312  if (c == '%')
313  c = '.';
314  string[l] = c;
315  }
316  l++;
317  }
318 
319  if (string)
320  string[l] = '\0';
321 
322  return l;
323 }
324 
328 int NET_ReadStringLine (dbuffer* buf, char* string, size_t length)
329 {
330  unsigned int l = 0;
331  do {
332  int c = NET_ReadByte(buf);
333  if (c == -1 || c == 0 || c == '\n')
334  break;
335  /* translate all format specs to avoid crash bugs */
336  if (c == '%')
337  c = '.';
338  string[l] = c;
339  l++;
340  } while (l < length - 1);
341 
342  string[l] = 0;
343 
344  return l;
345 }
346 
348 {
349  return (float) NET_ReadLong(buf) * (1.0 / 32);
350 }
351 
356 {
357  pos[0] = NET_ReadLong(buf) / POSSCALE;
358  pos[1] = NET_ReadLong(buf) / POSSCALE;
359 }
360 
365 {
366  pos[0] = NET_ReadLong(buf) / POSSCALE;
367  pos[1] = NET_ReadLong(buf) / POSSCALE;
368  pos[2] = NET_ReadLong(buf) / POSSCALE;
369 }
370 
377 {
378  pos[0] = NET_ReadByte(buf);
379  pos[1] = NET_ReadByte(buf);
380  pos[2] = NET_ReadByte(buf);
381 }
382 
384 {
385  return (float) NET_ReadChar(buf) * (360.0f / 256);
386 }
387 
389 {
390  const short s = NET_ReadShort(buf);
391  return (float) SHORT2ANGLE(s);
392 }
393 
394 void NET_ReadData (dbuffer* buf, void* data, int len)
395 {
396  for (int i = 0; i < len; i++)
397  ((byte*) data)[i] = NET_ReadByte(buf);
398 }
399 
401 {
402  const int b = NET_ReadByte(buf);
403  if (b >= lengthof(bytedirs))
404  Com_Error(ERR_DROP, "NET_ReadDir: out of range");
405  VectorCopy(bytedirs[b], dir);
406 }
407 
415 void NET_vReadFormat (dbuffer* buf, const char* format, va_list ap)
416 {
417  while (*format) {
418  const char typeID = *format++;
419 
420  switch (typeID) {
421  case 'c':
422  *va_arg(ap, int*) = NET_ReadChar(buf);
423  break;
424  case 'b':
425  *va_arg(ap, int*) = NET_ReadByte(buf);
426  break;
427  case 's':
428  *va_arg(ap, int*) = NET_ReadShort(buf);
429  break;
430  case 'l':
431  *va_arg(ap, int*) = NET_ReadLong(buf);
432  break;
433  case 'p':
434  NET_ReadPos(buf, *va_arg(ap, vec3_t*));
435  break;
436  case 'g':
437  NET_ReadGPos(buf, *va_arg(ap, pos3_t*));
438  break;
439  case 'd':
440  NET_ReadDir(buf, *va_arg(ap, vec3_t*));
441  break;
442  case 'a':
443  *va_arg(ap, float*) = NET_ReadAngle(buf);
444  break;
445  case '!':
446  format++;
447  break;
448  case '&': {
449  char* str = va_arg(ap, char*);
450  const size_t length = va_arg(ap, size_t);
451  NET_ReadString(buf, str, length);
452  break;
453  }
454  case '*':
455  {
456  const int n = NET_ReadShort(buf);
457 
458  *va_arg(ap, int*) = n;
459  byte* p = va_arg(ap, byte*);
460 
461  for (int i = 0; i < n; i++)
462  *p++ = NET_ReadByte(buf);
463  }
464  break;
465  default:
466  Com_Error(ERR_DROP, "ReadFormat: Unknown type!");
467  }
468  }
469  /* Too many arguments for the given format; too few cause crash above */
470 #ifdef PARANOID
471  if (!ap)
472  Com_Error(ERR_DROP, "ReadFormat: Too many arguments!");
473 #endif
474 }
475 
476 void NET_SkipFormat (dbuffer* buf, const char* format)
477 {
478  while (*format) {
479  const char typeID = *format++;
480 
481  switch (typeID) {
482  case 'c':
483  NET_ReadChar(buf);
484  break;
485  case 'b':
486  NET_ReadByte(buf);
487  break;
488  case 's':
489  NET_ReadShort(buf);
490  break;
491  case 'l':
492  NET_ReadLong(buf);
493  break;
494  case 'p': {
495  vec3_t v;
496  NET_ReadPos(buf, v);
497  break;
498  }
499  case 'g': {
500  pos3_t p;
501  NET_ReadGPos(buf, p);
502  break;
503  }
504  case 'd': {
505  vec3_t v;
506  NET_ReadDir(buf, v);
507  break;
508  }
509  case 'a':
510  NET_ReadAngle(buf);
511  break;
512  case '!':
513  format++;
514  break;
515  case '&':
516  NET_ReadString(buf, nullptr, 0);
517  break;
518  case '*': {
519  const int n = NET_ReadShort(buf);
520  for (int i = 0; i < n; i++)
521  NET_ReadByte(buf);
522  break;
523  }
524  default:
525  Com_Error(ERR_DROP, "ReadFormat: Unknown type!");
526  }
527  }
528 }
529 
533 void NET_ReadFormat (dbuffer* buf, const char* format, ...)
534 {
535  va_list ap;
536 
537  va_start(ap, format);
538  NET_vReadFormat(buf, format, ap);
539  va_end(ap);
540 }
541 
548 void NET_OOB_Printf (struct net_stream* s, const char* format, ...)
549 {
550  va_list argptr;
551  char string[256];
552  const char cmd = (const char)clc_oob;
553 
554  va_start(argptr, format);
555  Q_vsnprintf(string, sizeof(string), format, argptr);
556  va_end(argptr);
557 
558  const int len = LittleLong(strlen(string) + 1);
559  NET_StreamEnqueue(s, (const char*)&len, 4);
560  NET_StreamEnqueue(s, &cmd, 1);
561  NET_StreamEnqueue(s, string, strlen(string));
562 }
563 
569 void NET_WriteMsg (struct net_stream* s, dbuffer& buf)
570 {
571  char tmp[256];
572  int len = LittleLong(buf.length());
573  NET_StreamEnqueue(s, (char*)&len, 4);
574 
575  while (buf.length()) {
576  len = buf.extract(tmp, sizeof(tmp));
577  NET_StreamEnqueue(s, tmp, len);
578  }
579 }
580 
588 void NET_WriteConstMsg (struct net_stream* s, const dbuffer& buf)
589 {
590  char tmp[256];
591  const int len = LittleLong(buf.length());
592  int pos = 0;
593  NET_StreamEnqueue(s, (const char*)&len, 4);
594 
595  while (pos < buf.length()) {
596  const int x = buf.getAt(pos, tmp, sizeof(tmp));
597  assert(x > 0);
598  NET_StreamEnqueue(s, tmp, x);
599  pos += x;
600  }
601 }
602 
603 void NET_VPrintf (dbuffer* buf, const char* format, va_list ap, char* str, size_t length)
604 {
605  const int len = Q_vsnprintf(str, length, format, ap);
606  buf->add(str, len);
607 }
const vec3_t bytedirs[]
Definition: netpack.cpp:27
void NET_ReadPos(dbuffer *buf, vec3_t pos)
Definition: netpack.cpp:364
void NET_ReadGPos(dbuffer *buf, pos3_t pos)
Definition: netpack.cpp:376
#define VectorCopy(src, dest)
Definition: vector.h:51
int Q_vsnprintf(char *str, size_t size, const char *format, va_list ap)
Safe (null terminating) vsnprintf implementation.
Definition: shared.cpp:535
#define DEBUG_EVENTSYS
Definition: defines.h:64
void NET_ReadDir(dbuffer *buf, vec3_t dir)
Definition: netpack.cpp:400
void NET_WriteRawString(dbuffer *buf, const char *str)
Skip the zero string terminal character. If you need it, use NET_WriteString.
Definition: netpack.cpp:71
int NET_ReadChar(dbuffer *buf)
Definition: netpack.cpp:221
void NET_WriteString(dbuffer *buf, const char *str)
Definition: netpack.cpp:59
void NET_WriteChar(dbuffer *buf, char c)
Definition: netpack.cpp:33
int NET_PeekShort(const dbuffer *buf)
Peeks into a buffer without changing it to get a short int.
Definition: netpack.cpp:264
void NET_WriteAngle16(dbuffer *buf, float f)
Definition: netpack.cpp:115
void NET_WritePos(dbuffer *buf, const vec3_t pos)
Definition: netpack.cpp:96
void NET_ReadFormat(dbuffer *buf, const char *format,...)
The user-friendly version of NET_ReadFormat that reads variable arguments from a buffer according to ...
Definition: netpack.cpp:533
void NET_VPrintf(dbuffer *buf, const char *format, va_list ap, char *str, size_t length)
Definition: netpack.cpp:603
void NET_Write2Pos(dbuffer *buf, const vec2_t pos)
Definition: netpack.cpp:87
int NET_ReadLong(dbuffer *buf)
Definition: netpack.cpp:282
void NET_vReadFormat(dbuffer *buf, const char *format, va_list ap)
Reads from a buffer according to format; version without syntactic sugar for variable arguments...
Definition: netpack.cpp:415
voidpf void * buf
Definition: ioapi.h:42
size_t getAt(size_t, char *, size_t) const
Read data from a dbuffer.
Definition: dbuffer.cpp:86
void Com_Error(int code, const char *fmt,...)
Definition: common.cpp:417
void NET_Read2Pos(dbuffer *buf, vec2_t pos)
Definition: netpack.cpp:355
void add(const char *, size_t)
Definition: dbuffer.cpp:42
void NET_OOB_Printf(struct net_stream *s, const char *format,...)
Out of band print.
Definition: netpack.cpp:548
#define LittleShort(X)
Definition: byte.h:35
void NET_vWriteFormat(dbuffer *buf, const char *format, va_list ap)
Writes to buffer according to format; version without syntactic sugar for variable arguments...
Definition: netpack.cpp:149
#define DotProduct(x, y)
Returns the distance between two 3-dimensional vectors.
Definition: vector.h:44
#define ERR_DROP
Definition: common.h:211
int NET_ReadString(dbuffer *buf, char *string, size_t length)
Definition: netpack.cpp:302
void NET_StreamEnqueue(struct net_stream *s, const char *data, int len)
Enqueue a network message into a stream.
Definition: net.cpp:719
QGL_EXTERN GLuint GLsizei GLsizei * length
Definition: r_gl.h:110
size_t extract(char *, size_t)
Read and delete data from a dbuffer.
Definition: dbuffer.cpp:136
void NET_WriteLong(dbuffer *buf, int c)
Definition: netpack.cpp:52
int NET_ReadShort(dbuffer *buf)
Definition: netpack.cpp:242
float NET_ReadAngle16(dbuffer *buf)
Definition: netpack.cpp:388
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
Definition: common.cpp:398
int NET_PeekByte(const dbuffer *buf)
Definition: netpack.cpp:251
void NET_WriteFormat(dbuffer *buf, const char *format,...)
The user-friendly version of NET_WriteFormat that writes variable arguments to buffer according to fo...
Definition: netpack.cpp:207
pos_t pos3_t[3]
Definition: ufotypes.h:58
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
int NET_PeekLong(const dbuffer *buf)
Definition: netpack.cpp:273
const char * Com_ByteToBinary(byte x)
Definition: common.cpp:1005
void NET_ReadData(dbuffer *buf, void *data, int len)
Definition: netpack.cpp:394
void NET_WriteAngle(dbuffer *buf, float f)
Definition: netpack.cpp:110
size_t get(char *, size_t) const
Read data from a dbuffer.
Definition: dbuffer.cpp:61
float NET_ReadAngle(dbuffer *buf)
Definition: netpack.cpp:383
QGL_EXTERN GLint i
Definition: r_gl.h:113
QGL_EXTERN GLuint GLchar GLuint * len
Definition: r_gl.h:99
void NET_WriteByte(dbuffer *buf, byte c)
Definition: netpack.cpp:39
vec_t vec3_t[3]
Definition: ufotypes.h:39
vec_t vec2_t[2]
Definition: ufotypes.h:38
static const float POSSCALE
Definition: netpack.cpp:31
definitions common between client and server, but not game lib
size_t length() const
Definition: dbuffer.h:48
#define lengthof(x)
Definition: shared.h:105
#define ANGLE2SHORT(x)
Definition: common.h:207
GLsizei const GLvoid * data
Definition: r_gl.h:152
void NET_WriteGPos(dbuffer *buf, const pos3_t pos)
Definition: netpack.cpp:103
void NET_WriteDir(dbuffer *buf, const vec3_t dir)
Definition: netpack.cpp:124
uint8_t byte
Definition: ufotypes.h:34
QGL_EXTERN int GLboolean GLfloat * v
Definition: r_gl.h:120
float NET_ReadCoord(dbuffer *buf)
Definition: netpack.cpp:347
void NET_SkipFormat(dbuffer *buf, const char *format)
Definition: netpack.cpp:476
void NET_WriteCoord(dbuffer *buf, float f)
Definition: netpack.cpp:79
void NET_WriteShort(dbuffer *buf, int c)
Definition: netpack.cpp:45
int NET_ReadByte(dbuffer *buf)
Reads a byte from the netchannel.
Definition: netpack.cpp:234
#define SHORT2ANGLE(x)
Definition: common.h:208
void format(__printf__, 1, 2)))
int NET_ReadStringLine(dbuffer *buf, char *string, size_t length)
Definition: netpack.cpp:328
#define LittleLong(X)
Definition: byte.h:37
void NET_WriteConstMsg(struct net_stream *s, const dbuffer &buf)
Enqueue the buffer in the net stream for MULTIPLE clients.
Definition: netpack.cpp:588
void NET_WriteMsg(struct net_stream *s, dbuffer &buf)
Enqueue the buffer in the net stream for ONE client.
Definition: netpack.cpp:569