00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "common.h"
00026
00027 const vec3_t bytedirs[] = {
00028 #include "../shared/vertex_normals.h"
00029 };
00030
00031 void NET_WriteChar (struct dbuffer *buf, char c)
00032 {
00033 dbuffer_add(buf, &c, 1);
00034 }
00035
00036 void NET_WriteByte (struct dbuffer *buf, byte c)
00037 {
00038 dbuffer_add(buf, (char *)&c, 1);
00039 }
00040
00041 void NET_WriteShort (struct dbuffer *buf, int c)
00042 {
00043 unsigned short v = LittleShort(c);
00044 dbuffer_add(buf, (char *)&v, 2);
00045 }
00046
00047 void NET_WriteLong (struct dbuffer *buf, int c)
00048 {
00049 int v = LittleLong(c);
00050 dbuffer_add(buf, (char *)&v, 4);
00051 }
00052
00053 void NET_WriteString (struct dbuffer *buf, const char *str)
00054 {
00055 if (!str)
00056 dbuffer_add(buf, "", 1);
00057 else
00058 dbuffer_add(buf, str, strlen(str) + 1);
00059 }
00060
00061 void NET_WriteRawString (struct dbuffer *buf, const char *str)
00062 {
00063 if (str)
00064 dbuffer_add(buf, str, strlen(str));
00065 }
00066
00067 void NET_WriteCoord (struct dbuffer *buf, float f)
00068 {
00069 NET_WriteLong(buf, (int) (f * 32));
00070 }
00071
00075 void NET_Write2Pos (struct dbuffer *buf, vec2_t pos)
00076 {
00077 NET_WriteLong(buf, (long) (pos[0] * 32.));
00078 NET_WriteLong(buf, (long) (pos[1] * 32.));
00079 }
00080
00084 void NET_WritePos (struct dbuffer *buf, const vec3_t pos)
00085 {
00086 NET_WriteLong(buf, (long) (pos[0] * 32.));
00087 NET_WriteLong(buf, (long) (pos[1] * 32.));
00088 NET_WriteLong(buf, (long) (pos[2] * 32.));
00089 }
00090
00091 void NET_WriteGPos (struct dbuffer *buf, const pos3_t pos)
00092 {
00093 NET_WriteByte(buf, pos[0]);
00094 NET_WriteByte(buf, pos[1]);
00095 NET_WriteByte(buf, pos[2]);
00096 }
00097
00098 void NET_WriteAngle (struct dbuffer *buf, float f)
00099 {
00100 NET_WriteByte(buf, (int) (f * 256 / 360) & 255);
00101 }
00102
00103 void NET_WriteAngle16 (struct dbuffer *buf, float f)
00104 {
00105 NET_WriteShort(buf, ANGLE2SHORT(f));
00106 }
00107
00112 void NET_WriteDir (struct dbuffer *buf, const vec3_t dir)
00113 {
00114 int i, best;
00115 float bestd;
00116 size_t bytedirsLength;
00117
00118 if (!dir) {
00119 NET_WriteByte(buf, 0);
00120 return;
00121 }
00122
00123 bestd = 0;
00124 best = 0;
00125 bytedirsLength = lengthof(bytedirs);
00126 for (i = 0; i < bytedirsLength; i++) {
00127 const float d = DotProduct(dir, bytedirs[i]);
00128 if (d > bestd) {
00129 bestd = d;
00130 best = i;
00131 }
00132 }
00133 NET_WriteByte(buf, best);
00134 }
00135
00136
00141 void NET_vWriteFormat (struct dbuffer *buf, const char *format, va_list ap)
00142 {
00143 char typeID;
00144
00145 while (*format) {
00146 typeID = *format++;
00147
00148 switch (typeID) {
00149 case 'c':
00150 NET_WriteChar(buf, va_arg(ap, int));
00151
00152 break;
00153 case 'b':
00154 NET_WriteByte(buf, va_arg(ap, int));
00155
00156 break;
00157 case 's':
00158 NET_WriteShort(buf, va_arg(ap, int));
00159
00160 break;
00161 case 'l':
00162 NET_WriteLong(buf, va_arg(ap, int));
00163
00164 break;
00165 case 'p':
00166 NET_WritePos(buf, va_arg(ap, float *));
00167
00168 break;
00169 case 'g':
00170 NET_WriteGPos(buf, va_arg(ap, byte *));
00171 break;
00172 case 'd':
00173 NET_WriteDir(buf, va_arg(ap, float *));
00174
00175 break;
00176 case 'a':
00177
00178 NET_WriteAngle(buf, va_arg(ap, double));
00179
00180 break;
00181 case '!':
00182 break;
00183 case '&':
00184 NET_WriteString(buf, va_arg(ap, char *));
00185 break;
00186 case '*':
00187 {
00188 int i, n;
00189 byte *p;
00190
00191 n = va_arg(ap, int);
00192
00193 p = va_arg(ap, byte *);
00194 NET_WriteShort(buf, n);
00195 for (i = 0; i < n; i++)
00196 NET_WriteByte(buf, *p++);
00197 }
00198 break;
00199 default:
00200 Com_Error(ERR_DROP, "WriteFormat: Unknown type!");
00201 }
00202 }
00203
00204 if (!ap)
00205 Com_Error(ERR_DROP, "WriteFormat: Too many arguments!");
00206 }
00207
00211 void NET_WriteFormat (struct dbuffer *buf, const char *format, ...)
00212 {
00213 va_list ap;
00214 va_start(ap, format);
00215 NET_vWriteFormat(buf, format, ap);
00216 va_end(ap);
00217 }
00218
00219
00220
00221
00225 int NET_ReadChar (struct dbuffer *buf)
00226 {
00227 char c;
00228 if (dbuffer_extract(buf, &c, 1) == 0)
00229 return -1;
00230 else
00231 return c;
00232 }
00233
00239 int NET_ReadByte (struct dbuffer *buf)
00240 {
00241 unsigned char c;
00242 if (dbuffer_extract(buf, (char *)&c, 1) == 0)
00243 return -1;
00244 else
00245 return c;
00246 }
00247
00248 int NET_ReadShort (struct dbuffer *buf)
00249 {
00250 unsigned short v;
00251 if (dbuffer_extract(buf, (char *)&v, 2) < 2)
00252 return -1;
00253
00254 return LittleShort(v);
00255 }
00256
00262 int NET_PeekShort (const struct dbuffer *buf)
00263 {
00264 uint16_t v;
00265 if (dbuffer_get(buf, (char *)&v, 2) < 2)
00266 return -1;
00267
00268 return LittleShort(v);
00269 }
00270
00271 int NET_ReadLong (struct dbuffer *buf)
00272 {
00273 unsigned int v;
00274 if (dbuffer_extract(buf, (char *)&v, 4) < 4)
00275 return -1;
00276
00277 return LittleLong(v);
00278 }
00279
00292 int NET_ReadString (struct dbuffer *buf, char *string, size_t length)
00293 {
00294 unsigned int l;
00295
00296 l = 0;
00297 do {
00298 int c = NET_ReadByte(buf);
00299 if (c == -1 || c == 0)
00300 break;
00301
00302
00303 if (c == '%' || c > 127)
00304 c = '.';
00305 string[l] = c;
00306 l++;
00307 } while (l < length - 1);
00308
00309 string[l] = 0;
00310
00311 return l;
00312 }
00313
00317 int NET_ReadStringLine (struct dbuffer *buf, char *string, size_t length)
00318 {
00319 unsigned int l;
00320
00321 l = 0;
00322 do {
00323 int c = NET_ReadByte(buf);
00324 if (c == -1 || c == 0 || c == '\n')
00325 break;
00326
00327
00328 if (c == '%' || c > 127)
00329 c = '.';
00330 string[l] = c;
00331 l++;
00332 } while (l < length - 1);
00333
00334 string[l] = 0;
00335
00336 return l;
00337 }
00338
00339 float NET_ReadCoord (struct dbuffer *buf)
00340 {
00341 return (float) NET_ReadLong(buf) * (1.0 / 32);
00342 }
00343
00347 void NET_Read2Pos (struct dbuffer *buf, vec2_t pos)
00348 {
00349 pos[0] = NET_ReadLong(buf) / 32.;
00350 pos[1] = NET_ReadLong(buf) / 32.;
00351 }
00352
00356 void NET_ReadPos (struct dbuffer *buf, vec3_t pos)
00357 {
00358 pos[0] = NET_ReadLong(buf) / 32.;
00359 pos[1] = NET_ReadLong(buf) / 32.;
00360 pos[2] = NET_ReadLong(buf) / 32.;
00361 }
00362
00368 void NET_ReadGPos (struct dbuffer *buf, pos3_t pos)
00369 {
00370 pos[0] = NET_ReadByte(buf);
00371 pos[1] = NET_ReadByte(buf);
00372 pos[2] = NET_ReadByte(buf);
00373 }
00374
00375 float NET_ReadAngle (struct dbuffer *buf)
00376 {
00377 return (float) NET_ReadChar(buf) * (360.0 / 256);
00378 }
00379
00380 float NET_ReadAngle16 (struct dbuffer *buf)
00381 {
00382 short s;
00383
00384 s = NET_ReadShort(buf);
00385 return (float) SHORT2ANGLE(s);
00386 }
00387
00388 void NET_ReadData (struct dbuffer *buf, void *data, int len)
00389 {
00390 int i;
00391
00392 for (i = 0; i < len; i++)
00393 ((byte *) data)[i] = NET_ReadByte(buf);
00394 }
00395
00396 void NET_ReadDir (struct dbuffer *buf, vec3_t dir)
00397 {
00398 const int b = NET_ReadByte(buf);
00399 if (b >= lengthof(bytedirs))
00400 Com_Error(ERR_DROP, "NET_ReadDir: out of range");
00401 VectorCopy(bytedirs[b], dir);
00402 }
00403
00404
00411 void NET_vReadFormat (struct dbuffer *buf, const char *format, va_list ap)
00412 {
00413 while (*format) {
00414 const char typeID = *format++;
00415
00416 switch (typeID) {
00417 case 'c':
00418 *va_arg(ap, int *) = NET_ReadChar(buf);
00419 break;
00420 case 'b':
00421 *va_arg(ap, int *) = NET_ReadByte(buf);
00422 break;
00423 case 's':
00424 *va_arg(ap, int *) = NET_ReadShort(buf);
00425 break;
00426 case 'l':
00427 *va_arg(ap, int *) = NET_ReadLong(buf);
00428 break;
00429 case 'p':
00430 NET_ReadPos(buf, *va_arg(ap, vec3_t *));
00431 break;
00432 case 'g':
00433 NET_ReadGPos(buf, *va_arg(ap, pos3_t *));
00434 break;
00435 case 'd':
00436 NET_ReadDir(buf, *va_arg(ap, vec3_t *));
00437 break;
00438 case 'a':
00439 *va_arg(ap, float *) = NET_ReadAngle(buf);
00440 break;
00441 case '!':
00442 format++;
00443 break;
00444 case '&': {
00445 char *str = va_arg(ap, char *);
00446 const size_t length = va_arg(ap, size_t);
00447 NET_ReadString(buf, str, length);
00448 break;
00449 }
00450 case '*':
00451 {
00452 int i;
00453 byte *p;
00454 const int n = NET_ReadShort(buf);
00455
00456 *va_arg(ap, int *) = n;
00457 p = va_arg(ap, byte *);
00458
00459 for (i = 0; i < n; i++)
00460 *p++ = NET_ReadByte(buf);
00461 }
00462 break;
00463 default:
00464 Com_Error(ERR_DROP, "ReadFormat: Unknown type!");
00465 }
00466 }
00467
00468 if (!ap)
00469 Com_Error(ERR_DROP, "ReadFormat: Too many arguments!");
00470 }
00471
00475 void NET_ReadFormat (struct dbuffer *buf, const char *format, ...)
00476 {
00477 va_list ap;
00478
00479 va_start(ap, format);
00480 NET_vReadFormat(buf, format, ap);
00481 va_end(ap);
00482 }
00483
00490 void NET_OOB_Printf (struct net_stream *s, const char *format, ...)
00491 {
00492 va_list argptr;
00493 char string[4096];
00494 const char cmd = (const char)clc_oob;
00495 int len;
00496
00497 va_start(argptr, format);
00498 Q_vsnprintf(string, sizeof(string), format, argptr);
00499 va_end(argptr);
00500
00501 len = LittleLong(strlen(string) + 1);
00502 NET_StreamEnqueue(s, (const char *)&len, 4);
00503 NET_StreamEnqueue(s, &cmd, 1);
00504 NET_StreamEnqueue(s, string, strlen(string));
00505 }
00506
00512 void NET_WriteMsg (struct net_stream *s, struct dbuffer *buf)
00513 {
00514 char tmp[4096];
00515 int len = LittleLong(dbuffer_len(buf));
00516 NET_StreamEnqueue(s, (char *)&len, 4);
00517
00518 while (dbuffer_len(buf)) {
00519 len = dbuffer_extract(buf, tmp, sizeof(tmp));
00520 NET_StreamEnqueue(s, tmp, len);
00521 }
00522
00523
00524 free_dbuffer(buf);
00525 }
00526
00534 void NET_WriteConstMsg (struct net_stream *s, const struct dbuffer *buf)
00535 {
00536 char tmp[4096];
00537 int len = LittleLong(dbuffer_len(buf));
00538 int pos = 0;
00539 NET_StreamEnqueue(s, (char *)&len, 4);
00540
00541 while (pos < dbuffer_len(buf)) {
00542 const int x = dbuffer_get_at(buf, pos, tmp, sizeof(tmp));
00543 assert(x > 0);
00544 NET_StreamEnqueue(s, tmp, x);
00545 pos += x;
00546 }
00547 }
00548
00556 struct dbuffer *NET_ReadMsg (struct net_stream *s)
00557 {
00558 unsigned int v;
00559 unsigned int len;
00560 struct dbuffer *buf;
00561 char tmp[4096];
00562 if (NET_StreamPeek(s, (char *)&v, 4) < 4)
00563 return NULL;
00564
00565 len = LittleLong(v);
00566 if (NET_StreamGetLength(s) < (4 + len))
00567 return NULL;
00568
00569 NET_StreamDequeue(s, tmp, 4);
00570
00571 buf = new_dbuffer();
00572 while (len > 0) {
00573 const int x = NET_StreamDequeue(s, tmp, min(len, 4096));
00574 dbuffer_add(buf, tmp, x);
00575 len -= x;
00576 }
00577
00578 return buf;
00579 }
00580
00581 void NET_VPrintf (struct dbuffer *buf, const char *format, va_list ap, char *str, size_t length)
00582 {
00583 const int len = Q_vsnprintf(str, length, format, ap);
00584 dbuffer_add(buf, str, len);
00585 }