2D Run-and-gun shooter inspired by One Man's Doomsday, Counter-Strike, and Metal Slug.
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

IZ_net_client.c 5.6 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "IZ_net_client.h"
  2. bool IZ_NetClientIsValidPacketIntervalMs(long packet_interval_ms) {
  3. return (100 <= packet_interval_ms && packet_interval_ms <= 500);
  4. }
  5. bool IZ_NetClientIsValidMaxReconnectRetries(long max_reconnect_retries) {
  6. return (0 <= max_reconnect_retries && max_reconnect_retries <= 8);
  7. }
  8. bool IZ_NetClientIsValidReconnectIntervalSeconds(long reconnect_interval_secs) {
  9. return (3 <= reconnect_interval_secs && reconnect_interval_secs <= 10);
  10. }
  11. static IZ_ConfigItem net_client_config_items[IZ_PLAYERS + 3];
  12. void IZ_NetClientInitializeConfigItems(IZ_ConfigItem config_items[]) {
  13. config_items[0] = (IZ_ConfigItem) {
  14. IZ_CONFIG_TYPE_U16,
  15. sizeof(u16),
  16. "Network",
  17. "PacketIntervalMs",
  18. "-i",
  19. &IZ_NET_CLIENT_DEFAULT_STATE.config.packet_interval_ms,
  20. IZ_NetClientIsValidPacketIntervalMs,
  21. NULL,
  22. };
  23. config_items[1] = (IZ_ConfigItem) {
  24. IZ_CONFIG_TYPE_U8,
  25. sizeof(u8),
  26. "Network",
  27. "MaxReconnectRetries",
  28. NULL,
  29. &IZ_NET_CLIENT_DEFAULT_STATE.config.max_reconnect_retries,
  30. IZ_NetClientIsValidMaxReconnectRetries,
  31. NULL,
  32. };
  33. config_items[2] = (IZ_ConfigItem) {
  34. IZ_CONFIG_TYPE_U8,
  35. sizeof(u8),
  36. "Network",
  37. "ReconnectIntervalSeconds",
  38. NULL,
  39. &IZ_NET_CLIENT_DEFAULT_STATE.config.reconnect_interval_secs,
  40. IZ_NetClientIsValidReconnectIntervalSeconds,
  41. NULL,
  42. };
  43. u8 player_index;
  44. char* main_section_name;
  45. for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) {
  46. main_section_name = malloc(sizeof(char) * 64);
  47. sprintf_s(main_section_name, 64, "Network.%d", player_index);
  48. config_items[3 + player_index] = (IZ_ConfigItem) {
  49. IZ_CONFIG_TYPE_STRING,
  50. 32,
  51. main_section_name,
  52. "Username",
  53. NULL,
  54. &IZ_NET_CLIENT_DEFAULT_STATE.config.usernames[player_index],
  55. NULL,
  56. NULL,
  57. };
  58. }
  59. config_items[3 + IZ_PLAYERS] = IZ_CONFIG_ITEM_NULL;
  60. }
  61. void IZ_NetClientBindStateToConfig(IZ_NetClientState* state, IZ_ConfigItem config_items[]) {
  62. config_items[0].dest = &state->config.packet_interval_ms;
  63. config_items[1].dest = &state->config.max_reconnect_retries;
  64. config_items[2].dest = &state->config.reconnect_interval_secs;
  65. u8 player_index;
  66. for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) {
  67. config_items[3 + player_index].dest = &state->config.usernames[player_index];
  68. }
  69. }
  70. IZ_ProcedureResult IZ_NetClientSaveConfig(IZ_NetClientState* state, const char* config_path) {
  71. IZ_NetClientBindStateToConfig(state, net_client_config_items);
  72. return IZ_ConfigSave(net_client_config_items, config_path);
  73. }
  74. IZ_ProcedureResult IZ_NetClientInitializeConfig(
  75. IZ_NetClientState* state,
  76. const char* config_path,
  77. u8 argc,
  78. const char* argv[]
  79. ) {
  80. IZ_NetClientInitializeConfigItems(net_client_config_items);
  81. IZ_NetClientBindStateToConfig(state, net_client_config_items);
  82. if (IZ_ConfigInitialize(net_client_config_items, config_path, argc, argv) < 0) {
  83. return -1;
  84. }
  85. return 0;
  86. }
  87. IZ_ProcedureResult IZ_NetClientInitialize(
  88. IZ_NetClientState* state,
  89. void* user_data,
  90. void* callback,
  91. const char* config_path,
  92. u8 argc,
  93. const char* argv[]
  94. ) {
  95. if (!user_data) {
  96. return -1;
  97. }
  98. memcpy_s(state, sizeof(IZ_NetClientState), &IZ_NET_CLIENT_DEFAULT_STATE, sizeof(IZ_NetClientState));
  99. if (IZ_NetClientInitializeConfig(state, config_path, argc, argv) < 0) {
  100. return -2;
  101. }
  102. state->binding.user_data = user_data;
  103. state->callback = callback;
  104. state->retries = state->config.max_reconnect_retries;
  105. u8 player_index;
  106. for (player_index = 0; player_index < IZ_PLAYERS; player_index += 1) {
  107. state->action[player_index] = 0;
  108. }
  109. return 0;
  110. }
  111. void IZ_NetClientConnect(IZ_NetClientState* state, IZ_WSClientInitializeParams params) {
  112. if (!state->callback) {
  113. return;
  114. }
  115. if (state->status == IZ_NET_CLIENT_STATUS_CONNECTED) {
  116. return;
  117. }
  118. if (state->status == IZ_NET_CLIENT_STATUS_CONNECTING) {
  119. return;
  120. }
  121. if (state->retries < state->config.max_reconnect_retries) {
  122. return;
  123. }
  124. state->retries = 0;
  125. state->params = params;
  126. state->thread = SDL_CreateThread(state->callback, "networking", state->binding.user_data);
  127. SDL_DetachThread(state->thread);
  128. }
  129. void IZ_NetClientDisconnect(IZ_NetClientState* state) {
  130. if (state->status == IZ_NET_CLIENT_STATUS_PRISTINE) {
  131. return;
  132. }
  133. if (state->binding.connection) {
  134. IZ_WSClientVHostData *vhd = (IZ_WSClientVHostData *) lws_protocol_vh_priv_get(
  135. lws_get_vhost(state->binding.connection),
  136. lws_get_protocol(state->binding.connection)
  137. );
  138. if (vhd) {
  139. lws_sul_cancel(&vhd->sul);
  140. }
  141. }
  142. state->retries = state->config.max_reconnect_retries;
  143. IZ_WSClientCancelService(&state->binding);
  144. }
  145. void IZ_NetClientSendBinaryMessage(IZ_NetClientState* state, void* in, size_t len) {
  146. if (state->status != IZ_NET_CLIENT_STATUS_CONNECTED) {
  147. return;
  148. }
  149. IZ_WSClientVHostData* vhd = (IZ_WSClientVHostData*) lws_protocol_vh_priv_get(
  150. lws_get_vhost(state->binding.connection),
  151. lws_get_protocol(state->binding.connection)
  152. );
  153. IZ_WebsocketMessage amsg;
  154. i32 result;
  155. result = IZ_WebsocketCreateBinaryMessage(state->binding.connection, &amsg, in, len);
  156. if (result < 0) {
  157. return;
  158. }
  159. lws_ring_insert(vhd->ring, &amsg, 1);
  160. lws_callback_on_writable(state->binding.connection);
  161. }
  162. void IZ_NetClientSendTextMessage(IZ_NetClientState* state, char* in, size_t len) {
  163. if (state->status != IZ_NET_CLIENT_STATUS_CONNECTED) {
  164. return;
  165. }
  166. IZ_WSClientVHostData* vhd = (IZ_WSClientVHostData*) lws_protocol_vh_priv_get(
  167. lws_get_vhost(state->binding.connection),
  168. lws_get_protocol(state->binding.connection)
  169. );
  170. IZ_WebsocketMessage amsg;
  171. i32 result;
  172. result = IZ_WebsocketCreateTextMessage(state->binding.connection, &amsg, in, len);
  173. if (result < 0) {
  174. return;
  175. }
  176. lws_ring_insert(vhd->ring, &amsg, 1);
  177. lws_callback_on_writable(state->binding.connection);
  178. }