PageRenderTime 57ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/quakeforge/trunk/libs/net/nm/net_loop.c

#
C | 274 lines | 179 code | 60 blank | 35 comment | 28 complexity | f301bbc3d8f808863333860152ec75c6 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, AGPL-3.0, AGPL-1.0, Unlicense
  1. /*
  2. net_loop.c
  3. @description@
  4. Copyright (C) 1996-1997 Id Software, Inc.
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. See the GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to:
  15. Free Software Foundation, Inc.
  16. 59 Temple Place - Suite 330
  17. Boston, MA 02111-1307, USA
  18. */
  19. #ifdef HAVE_CONFIG_H
  20. # include "config.h"
  21. #endif
  22. static __attribute__ ((used)) const char rcsid[] =
  23. "$Id: net_loop.c 11797 2009-12-20 05:59:22Z taniwha $";
  24. #include "QF/cvar.h"
  25. #include "QF/msg.h"
  26. #include "QF/sys.h"
  27. #include "netmain.h"
  28. #include "net_loop.h"
  29. #include "../nq/include/client.h"
  30. #include "../nq/include/server.h"
  31. qboolean localconnectpending = false;
  32. qsocket_t *loop_client = NULL;
  33. qsocket_t *loop_server = NULL;
  34. int
  35. Loop_Init (void)
  36. {
  37. if (cls.state == ca_dedicated)
  38. return -1;
  39. return 0;
  40. }
  41. void
  42. Loop_Shutdown (void)
  43. {
  44. }
  45. void
  46. Loop_Listen (qboolean state)
  47. {
  48. }
  49. void
  50. Loop_SearchForHosts (qboolean xmit)
  51. {
  52. if (!sv.active)
  53. return;
  54. hostCacheCount = 1;
  55. if (strcmp (hostname->string, "UNNAMED") == 0)
  56. strcpy (hostcache[0].name, "local");
  57. else
  58. strcpy (hostcache[0].name, hostname->string);
  59. strcpy (hostcache[0].map, sv.name);
  60. hostcache[0].users = net_activeconnections;
  61. hostcache[0].maxusers = svs.maxclients;
  62. hostcache[0].driver = net_driverlevel;
  63. strcpy (hostcache[0].cname, "local");
  64. }
  65. qsocket_t *
  66. Loop_Connect (const char *host)
  67. {
  68. if (strcmp (host, "local") != 0)
  69. return NULL;
  70. localconnectpending = true;
  71. if (!loop_client) {
  72. if ((loop_client = NET_NewQSocket ()) == NULL) {
  73. Sys_Printf ("Loop_Connect: no qsocket available\n");
  74. return NULL;
  75. }
  76. strcpy (loop_client->address, "localhost");
  77. }
  78. loop_client->receiveMessageLength = 0;
  79. loop_client->sendMessageLength = 0;
  80. loop_client->canSend = true;
  81. if (!loop_server) {
  82. if ((loop_server = NET_NewQSocket ()) == NULL) {
  83. Sys_Printf ("Loop_Connect: no qsocket available\n");
  84. return NULL;
  85. }
  86. strcpy (loop_server->address, "LOCAL");
  87. }
  88. loop_server->receiveMessageLength = 0;
  89. loop_server->sendMessageLength = 0;
  90. loop_server->canSend = true;
  91. loop_client->driverdata = (void *) loop_server;
  92. loop_server->driverdata = (void *) loop_client;
  93. return loop_client;
  94. }
  95. qsocket_t *
  96. Loop_CheckNewConnections (void)
  97. {
  98. if (!localconnectpending)
  99. return NULL;
  100. localconnectpending = false;
  101. loop_server->sendMessageLength = 0;
  102. loop_server->receiveMessageLength = 0;
  103. loop_server->canSend = true;
  104. loop_client->sendMessageLength = 0;
  105. loop_client->receiveMessageLength = 0;
  106. loop_client->canSend = true;
  107. return loop_server;
  108. }
  109. static int
  110. IntAlign (int value)
  111. {
  112. return (value + (sizeof (int) - 1)) & (~(sizeof (int) - 1));
  113. }
  114. int
  115. Loop_GetMessage (qsocket_t * sock)
  116. {
  117. int ret;
  118. int length;
  119. if (sock->receiveMessageLength == 0)
  120. return 0;
  121. ret = sock->receiveMessage[0];
  122. length = sock->receiveMessage[1] + (sock->receiveMessage[2] << 8);
  123. // alignment byte skipped here
  124. SZ_Clear (net_message->message);
  125. SZ_Write (net_message->message, &sock->receiveMessage[4], length);
  126. length = IntAlign (length + 4);
  127. sock->receiveMessageLength -= length;
  128. if (sock->receiveMessageLength)
  129. memmove (sock->receiveMessage, &sock->receiveMessage[length],
  130. sock->receiveMessageLength);
  131. if (sock->driverdata && ret == 1)
  132. ((qsocket_t *) sock->driverdata)->canSend = true;
  133. return ret;
  134. }
  135. int
  136. Loop_SendMessage (qsocket_t * sock, sizebuf_t *data)
  137. {
  138. byte *buffer;
  139. int *bufferLength;
  140. if (!sock->driverdata)
  141. return -1;
  142. bufferLength = &((qsocket_t *) sock->driverdata)->receiveMessageLength;
  143. if ((*bufferLength + data->cursize + 4) > NET_MAXMESSAGE)
  144. Sys_Error ("Loop_SendMessage: overflow");
  145. buffer = ((qsocket_t *) sock->driverdata)->receiveMessage + *bufferLength;
  146. // message type
  147. *buffer++ = 1;
  148. // length
  149. *buffer++ = data->cursize & 0xff;
  150. *buffer++ = data->cursize >> 8;
  151. // align
  152. buffer++;
  153. // message
  154. memcpy (buffer, data->data, data->cursize);
  155. *bufferLength = IntAlign (*bufferLength + data->cursize + 4);
  156. sock->canSend = false;
  157. return 1;
  158. }
  159. int
  160. Loop_SendUnreliableMessage (qsocket_t * sock, sizebuf_t *data)
  161. {
  162. byte *buffer;
  163. int *bufferLength;
  164. if (!sock->driverdata)
  165. return -1;
  166. bufferLength = &((qsocket_t *) sock->driverdata)->receiveMessageLength;
  167. if ((*bufferLength + data->cursize + sizeof (byte) + sizeof (short)) >
  168. NET_MAXMESSAGE) return 0;
  169. buffer = ((qsocket_t *) sock->driverdata)->receiveMessage + *bufferLength;
  170. // message type
  171. *buffer++ = 2;
  172. // length
  173. *buffer++ = data->cursize & 0xff;
  174. *buffer++ = data->cursize >> 8;
  175. // align
  176. buffer++;
  177. // message
  178. memcpy (buffer, data->data, data->cursize);
  179. *bufferLength = IntAlign (*bufferLength + data->cursize + 4);
  180. return 1;
  181. }
  182. qboolean
  183. Loop_CanSendMessage (qsocket_t * sock)
  184. {
  185. if (!sock->driverdata)
  186. return false;
  187. return sock->canSend;
  188. }
  189. qboolean
  190. Loop_CanSendUnreliableMessage (qsocket_t * sock)
  191. {
  192. return true;
  193. }
  194. void
  195. Loop_Close (qsocket_t * sock)
  196. {
  197. if (sock->driverdata)
  198. ((qsocket_t *) sock->driverdata)->driverdata = NULL;
  199. sock->receiveMessageLength = 0;
  200. sock->sendMessageLength = 0;
  201. sock->canSend = true;
  202. if (sock == loop_client)
  203. loop_client = NULL;
  204. else
  205. loop_server = NULL;
  206. }