network_connect.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /* $Id: network_connect.c,v 1.16 2001/04/29 18:16:20 kilobug Exp $ */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <unistd.h>
  5. #include <fcntl.h>
  6. #include <netinet/in.h>
  7. #include <server.h>
  8. #include <network.h>
  9. #include <private.h>
  10. #include <general.h>
  11. #include <pulsarnet.h>
  12. static void gfx_send_map(gfx_client_t *cl)
  13. {
  14. player_t *play;
  15. GSList *l;
  16. int i;
  17. item_t *obj;
  18. net_wr_float(cl->wsock, gl_config->size_x);
  19. net_wr_float(cl->wsock, gl_config->size_y);
  20. net_wr_int(cl->wsock, gl_config->nb_turns);
  21. net_wr_int(cl->wsock, gl_config->turn_num);
  22. net_wr_int(cl->wsock, gl_config->nb_players);
  23. net_wr_int(cl->wsock, gl_config->nb_r4d2);
  24. net_wr_int(cl->wsock, gl_config->nb_akx);
  25. net_wr_string(cl->wsock, gl_config->sand_file);
  26. if (!gfx_get_ack(cl))
  27. {
  28. return;
  29. }
  30. for (l = gl_config->players ; l != NULL ; l = l->next)
  31. {
  32. play = l->data;
  33. net_wr_string(cl->wsock, "PLR");
  34. net_wr_int(cl->wsock, play->team_id);
  35. net_wr_string(cl->wsock, play->name);
  36. net_wr_float(cl->wsock, play->score);
  37. }
  38. if (!gfx_get_ack(cl))
  39. {
  40. return;
  41. }
  42. for (i = 0 ; i < gl_config->nb_objects ; i++)
  43. {
  44. obj = gl_objects + i;
  45. net_wr_string(cl->wsock, "OBJ");
  46. net_wr_int(cl->wsock, obj->obj.id);
  47. net_wr_int(cl->wsock, obj->obj.type);
  48. gfx_write_object(cl->wsock, obj);
  49. }
  50. if (!gfx_get_ack(cl))
  51. {
  52. return;
  53. }
  54. }
  55. boolean_t gfx_new_client(int socket, boolean_t master)
  56. {
  57. gfx_client_t *cl;
  58. gfx_t *gfx;
  59. struct sockaddr_in sin;
  60. int sin_len;
  61. int fd;
  62. FILE *file;
  63. struct timeval tv;
  64. int value = 1;
  65. if (!gl_config->gfx)
  66. {
  67. return True;
  68. }
  69. if ((!master) && (!gl_config->pub))
  70. {
  71. return False;
  72. }
  73. sin_len = sizeof(sin);
  74. if (!master)
  75. {
  76. fcntl(gl_config->gfx_clients->sock, F_SETFL, O_NONBLOCK);
  77. }
  78. if ((fd = accept(socket, (struct sockaddr *)&sin, &sin_len)) == -1)
  79. {
  80. if (master)
  81. {
  82. perror("accept");
  83. }
  84. return False;
  85. }
  86. setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &value, sizeof(value));
  87. if (!master)
  88. {
  89. fcntl(fd, F_SETFL, 0);
  90. tv.tv_sec = 5;
  91. tv.tv_usec = 0;
  92. setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
  93. net_set_error_handler(NULL, NULL);
  94. }
  95. else
  96. {
  97. net_set_error_handler(net_error_abort, NULL);
  98. }
  99. if (!net_chk_string(fd, "HELLO 42"))
  100. {
  101. close(fd);
  102. return False;
  103. }
  104. file = fdopen(fd, "w");
  105. net_wr_string(file, "HELLO 42");
  106. fflush(file);
  107. if (net_get_int(fd) != PROTOCOL_VERSION)
  108. {
  109. net_send_abort(file);
  110. fclose(file);
  111. return False;
  112. }
  113. net_send_ack(file);
  114. if (net_get_flag(fd) != master)
  115. {
  116. net_send_abort(file);
  117. fclose(file);
  118. return False;
  119. }
  120. net_send_ack(file);
  121. if (!net_wait_ack(fd))
  122. {
  123. net_send_abort(file);
  124. fclose(file);
  125. return False;
  126. }
  127. gfx = gl_config->gfx_clients;
  128. cl = malloc(sizeof(*cl));
  129. cl->sock = fd;
  130. cl->wsock = file;
  131. cl->alive = True;
  132. gfx->clients = g_slist_prepend(gfx->clients, cl);
  133. if (master)
  134. {
  135. gfx->master = cl->sock;
  136. gfx->wmaster = cl->wsock;
  137. }
  138. gfx_send_map(cl);
  139. return True;
  140. }