network.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /* $Id: network.c,v 1.11 2001/04/28 15:29:25 kilobug Exp $ */
  2. #include "server.h"
  3. void gfx_trash_client(net_type_t get, net_type_t wanted, void *data)
  4. {
  5. gfx_client_t *cl;
  6. cl = data;
  7. fprintf(stderr, "Network warning: reading %s, wanted %s.\n",
  8. net_type_name(get), net_type_name(wanted));
  9. close(cl->sock);
  10. cl->alive = FALSE;
  11. }
  12. gboolean gfx_get_ack(gfx_client_t *cl)
  13. {
  14. gfx_t *gfx;
  15. fflush(cl->wsock);
  16. gfx = gl_config->gfx_clients;
  17. if (!net_wait_ack(cl->sock))
  18. {
  19. gfx_trash_client(net_type_none, net_type_int, cl);
  20. return FALSE;
  21. }
  22. return TRUE;
  23. }
  24. void gfx_write_object(FILE *file, item_t *obj)
  25. {
  26. net_wr_float(file, obj->obj.x);
  27. net_wr_float(file, obj->obj.y);
  28. net_wr_int(file, obj->obj.team_id);
  29. if (obj->obj.type == obj_akx)
  30. {
  31. net_wr_int(file, obj->akx.action.type);
  32. switch (obj->akx.action.type)
  33. {
  34. case act_akx_move:
  35. break;
  36. case act_akx_pulse:
  37. net_wr_float(file, obj->akx.action.act.pulse.angle);
  38. net_wr_float(file, obj->akx.action.act.pulse.x);
  39. net_wr_float(file, obj->akx.action.act.pulse.y);
  40. break;
  41. case act_akx_link:
  42. net_wr_int(file, obj->akx.action.act.link.target_id);
  43. break;
  44. }
  45. }
  46. }
  47. static gboolean gfx_do_send_updates(void *data, void *foo)
  48. {
  49. GSList *l;
  50. player_t *play;
  51. item_t *obj;
  52. int i;
  53. gfx_client_t *cl;
  54. cl = data;
  55. if (cl == NULL)
  56. return TRUE;
  57. if (!cl->alive)
  58. return TRUE;
  59. net_set_error_handler(gfx_trash_client, cl);
  60. net_wr_string(cl->wsock, "TRN");
  61. net_wr_int(cl->wsock, gl_config->turn_num);
  62. if (!gfx_get_ack(cl))
  63. return FALSE;
  64. for (l = gl_config->players; l != NULL; l = l->next)
  65. {
  66. net_wr_string(cl->wsock, "UPL");
  67. play = l->data;
  68. net_wr_int(cl->wsock, play->team_id);
  69. net_wr_float(cl->wsock, play->score);
  70. }
  71. net_wr_string(cl->wsock, "END");
  72. if (!gfx_get_ack(cl))
  73. return FALSE;
  74. for (i = 0; i < gl_config->nb_objects; i++)
  75. if (gl_objects[i].obj.change)
  76. {
  77. net_wr_string(cl->wsock, "UOB");
  78. obj = gl_objects + i;
  79. net_wr_int(cl->wsock, obj->obj.id);
  80. gfx_write_object(cl->wsock, obj);
  81. }
  82. net_wr_string(cl->wsock, "END");
  83. if (!gfx_get_ack(cl))
  84. return FALSE;
  85. return TRUE;
  86. }
  87. static void gfx_send_updates(void *data, void *foo)
  88. {
  89. gfx_client_t *cl;
  90. if (!gfx_do_send_updates(data, foo))
  91. {
  92. cl = data;
  93. cl->alive = FALSE;
  94. }
  95. }
  96. static void gfx_send_goodbye(void *data, void *foo)
  97. {
  98. gfx_client_t *cl;
  99. cl = data;
  100. net_wr_string(cl->wsock, "BYE");
  101. fflush(cl->wsock);
  102. net_wait_ack(cl->sock);
  103. }
  104. void gfx_client_new_turn(gboolean last)
  105. {
  106. gfx_t *gfx;
  107. int i;
  108. if (!gl_config->gfx)
  109. return;
  110. gfx = gl_config->gfx_clients;
  111. i = net_chk_str_list(gfx->master, "GO", "END", NULL);
  112. if (i == -1)
  113. {
  114. fprintf(stderr, "Protocol error.\n");
  115. exit(0);
  116. }
  117. net_send_ack(gfx->wmaster);
  118. net_set_error_handler(NULL, NULL);
  119. if ((i == 0) && (!last))
  120. {
  121. while (gfx_new_client(gfx->sock, FALSE));
  122. g_slist_foreach(gfx->clients, gfx_send_updates, NULL);
  123. }
  124. else
  125. {
  126. g_slist_foreach(gfx->clients, gfx_send_goodbye, NULL);
  127. exit(0);
  128. }
  129. }
  130. static void gfx_clean()
  131. {
  132. close(gl_config->gfx_clients->sock);
  133. }
  134. void gfx_init()
  135. {
  136. if (!gl_config->gfx)
  137. {
  138. return;
  139. gl_config->gfx_clients = NULL;
  140. }
  141. gl_config->gfx_clients = g_malloc(sizeof(*(gl_config->gfx_clients)));
  142. gl_config->gfx_clients->master = 0;
  143. gl_config->gfx_clients->wmaster = NULL;
  144. gl_config->gfx_clients->clients = NULL;
  145. gl_config->gfx_clients->sock = net_listen_at(gl_config->port, 15,
  146. NULL, 0);
  147. atexit(gfx_clean);
  148. while (!gfx_new_client(gl_config->gfx_clients->sock, TRUE));
  149. }