Network.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. #include "core/Network.h"
  2. #define ENET_IMPLEMENTATION
  3. #include <assert.h>
  4. #include <core/HashMap.h>
  5. #include <core/Logger.h>
  6. #include <core/Utility.h>
  7. #include <enet.h>
  8. #include <string.h>
  9. #include "ErrorSimulator.h"
  10. // HashMap clients; // Client -> ENetPeer*
  11. HASHMAP(Client, ENetPeer*, Client)
  12. #define equalClient equalInt
  13. #define isInvalidKeyClient isInvalidKeyInt
  14. #define hashClient hashInt
  15. HASHMAP_SOURCE(Client, ENetPeer*, Client)
  16. void initInPacket(InPacket* in, const void* data, size_t n) {
  17. in->data = data;
  18. in->size = n;
  19. in->index = 0;
  20. }
  21. bool readInPacketU8(InPacket* in, u8* u) {
  22. return readInPacket(in, u, sizeof(*u));
  23. }
  24. bool readInPacketU16(InPacket* in, u16* u) {
  25. if(readInPacket(in, u, sizeof(*u))) {
  26. return true;
  27. }
  28. *u = ntohs(*u);
  29. return false;
  30. }
  31. bool readInPacketU32(InPacket* in, u32* u) {
  32. if(readInPacket(in, u, sizeof(*u))) {
  33. return true;
  34. }
  35. *u = ntohl(*u);
  36. return false;
  37. }
  38. bool readInPacketI8(InPacket* in, i8* i) {
  39. u8 u;
  40. if(readInPacketU8(in, &u)) {
  41. return true;
  42. }
  43. *i = (i8)((i32)u - (i32)128);
  44. return false;
  45. }
  46. bool readInPacketI16(InPacket* in, i16* i) {
  47. u16 u;
  48. if(readInPacketU16(in, &u)) {
  49. return true;
  50. }
  51. *i = (i16)((i32)u - (i32)32768);
  52. return false;
  53. }
  54. bool readInPacketI32(InPacket* in, i32* i) {
  55. u32 u;
  56. if(readInPacketU32(in, &u)) {
  57. return true;
  58. }
  59. if(u < 2147483648) {
  60. *i = (i32)((i32)u - (i32)2147483648);
  61. } else {
  62. *i = (i32)(u - (u32)2147483648);
  63. }
  64. return false;
  65. }
  66. bool readInPacketFloat(InPacket* in, float* f) {
  67. u32 u;
  68. static_assert(sizeof(u) == sizeof(*f), "float and u32 size do not match");
  69. if(readInPacketU32(in, &u)) {
  70. return true;
  71. }
  72. memcpy(f, &u, sizeof(float));
  73. return false;
  74. }
  75. size_t readInPacketString(InPacket* in, char* buffer, size_t n) {
  76. if(n == 0) {
  77. return 0;
  78. }
  79. u16 size;
  80. if(readInPacketU16(in, &size)) {
  81. return 0;
  82. }
  83. size_t end = size;
  84. char* bufferStart = buffer;
  85. n--;
  86. while(n-- > 0 && end > 0) {
  87. end--;
  88. u8 u;
  89. if(readInPacketU8(in, &u)) {
  90. *bufferStart = '\0';
  91. break;
  92. }
  93. *(buffer++) = (char)u;
  94. }
  95. while(end-- > 0 && !readInPacketU8(in, &(u8){0})) {}
  96. *buffer = '\0';
  97. return size;
  98. }
  99. bool readInPacket(InPacket* in, void* buffer, size_t n) {
  100. if(in->index + n > in->size) {
  101. return true;
  102. }
  103. memcpy(buffer, in->data + in->index, n);
  104. in->index += n;
  105. return false;
  106. }
  107. void initOutPacket(OutPacket* out) {
  108. initBuffer(&out->data);
  109. }
  110. void destroyOutPacket(OutPacket* out) {
  111. destroyBuffer(&out->data);
  112. }
  113. void writeOutPacketU8(OutPacket* out, u8 u) {
  114. addSizedBufferData(&out->data, &u, sizeof(u));
  115. }
  116. void writeOutPacketU16(OutPacket* out, u16 u) {
  117. u = htons(u);
  118. addSizedBufferData(&out->data, &u, sizeof(u));
  119. }
  120. void writeOutPacketU32(OutPacket* out, u32 u) {
  121. u = htonl(u);
  122. addSizedBufferData(&out->data, &u, sizeof(u));
  123. }
  124. void writeOutPacketI8(OutPacket* out, i8 i) {
  125. if(i < 0) {
  126. writeOutPacketU8(out, (u8)((i32)i + (i32)128));
  127. } else {
  128. writeOutPacketU8(out, (u8)((u32)i + (u32)128));
  129. }
  130. }
  131. void writeOutPacketI16(OutPacket* out, i16 i) {
  132. if(i < 0) {
  133. writeOutPacketU16(out, (u16)((i32)i + (i32)32768));
  134. } else {
  135. writeOutPacketU16(out, (u16)((u32)i + (u32)32768));
  136. }
  137. }
  138. void writeOutPacketI32(OutPacket* out, i32 i) {
  139. if(i < 0) {
  140. writeOutPacketU32(out, (u32)((i + (i32)2147483647) + (i32)1));
  141. } else {
  142. writeOutPacketU32(out, (u32)((u32)i + (u32)2147483648));
  143. }
  144. }
  145. void writeOutPacketFloat(OutPacket* out, float f) {
  146. u32 u;
  147. static_assert(sizeof(u) == sizeof(f), "float and u32 size do not match");
  148. memcpy(&u, &f, sizeof(float));
  149. writeOutPacketU32(out, u);
  150. }
  151. void writeOutPacketString(OutPacket* out, const char* s) {
  152. size_t marker = out->data.size;
  153. writeOutPacketU16(out, 0);
  154. size_t end = 0;
  155. while(end < 65534 && *s != '\0') {
  156. writeOutPacketU8(out, (u8)(*(s++)));
  157. end++;
  158. }
  159. writeOutPacketU8(out, 0);
  160. end++;
  161. size_t endMarker = out->data.size;
  162. out->data.size = marker;
  163. writeOutPacketU16(out, (u16)end);
  164. out->data.size = endMarker;
  165. }
  166. void writeOutPacket(OutPacket* out, const void* buffer, size_t n) {
  167. addSizedBufferData(&out->data, buffer, n);
  168. }
  169. static int enetCounter = 0;
  170. static bool addENet(void) {
  171. if(enetCounter == 0 && FAIL(enet_initialize() != 0, true)) {
  172. return true;
  173. }
  174. enetCounter++;
  175. return false;
  176. }
  177. static void removeENet(void) {
  178. if(enetCounter > 0 && --enetCounter == 0) {
  179. enet_deinitialize();
  180. }
  181. }
  182. static_assert(sizeof(enet_uint16) == sizeof(Port), "port has wrong type");
  183. static void voidVoidDummy(void) {
  184. }
  185. static void voidInPacketDummy(InPacket*) {
  186. }
  187. typedef struct {
  188. ENetHost* client;
  189. ENetPeer* connection;
  190. OnServerConnect onConnect;
  191. OnServerDisconnect onDisconnect;
  192. OnServerPacket onPacket;
  193. int connectTicks;
  194. int connectTimeoutTicks;
  195. int disconnectTicks;
  196. int disconnectTimeoutTicks;
  197. } ClientData;
  198. static ClientData client = {
  199. nullptr, nullptr, voidVoidDummy, voidVoidDummy, voidInPacketDummy, 0, 0,
  200. 0, 0};
  201. bool startClient(void) {
  202. if(client.client != nullptr) {
  203. LOG_WARNING("Client already started");
  204. return true;
  205. } else if(addENet()) {
  206. LOG_ERROR("Client cannot initialize enet");
  207. return true;
  208. }
  209. client.client = FAIL(enet_host_create(nullptr, 1, 2, 0, 0), nullptr);
  210. if(client.client == nullptr) {
  211. stopClient();
  212. LOG_ERROR("Cannot create enet client host");
  213. return true;
  214. }
  215. return false;
  216. }
  217. void stopClient(void) {
  218. if(client.connection != nullptr) {
  219. client.onDisconnect();
  220. FAIL(enet_peer_disconnect_now(client.connection, 0),
  221. enet_peer_reset(client.connection));
  222. client.connection = nullptr;
  223. }
  224. if(client.client != nullptr) {
  225. enet_host_destroy(client.client);
  226. client.client = nullptr;
  227. }
  228. removeENet();
  229. client.connectTicks = 0;
  230. client.disconnectTicks = 0;
  231. }
  232. bool connectClient(const char* server, Port port, int timeoutTicks) {
  233. if(client.client == nullptr) {
  234. LOG_WARNING("Client not started");
  235. return true;
  236. } else if(client.connection != nullptr) {
  237. LOG_WARNING("Connection already exists");
  238. return true;
  239. }
  240. ENetAddress address = {0};
  241. enet_address_set_host(&address, server);
  242. address.port = port;
  243. client.connection =
  244. FAIL(enet_host_connect(client.client, &address, 3, 0), nullptr);
  245. if(client.connection == nullptr) {
  246. LOG_ERROR("Cannot create connection");
  247. return true;
  248. }
  249. client.connectTicks = 1;
  250. client.connectTimeoutTicks = timeoutTicks;
  251. return false;
  252. }
  253. void setClientTimeout(u32 timeout, u32 timeoutMin, u32 timeoutMax) {
  254. if(client.connection != nullptr) {
  255. enet_peer_timeout(client.connection, timeout, timeoutMin, timeoutMax);
  256. }
  257. }
  258. void disconnectClient(int timeoutTicks) {
  259. if(client.connection == nullptr) {
  260. return;
  261. }
  262. client.connectTicks = 0;
  263. enet_peer_disconnect(client.connection, 0);
  264. client.disconnectTicks = 1;
  265. client.disconnectTimeoutTicks = timeoutTicks;
  266. }
  267. void sendClientPacket(const OutPacket* p, PacketSendMode mode) {
  268. if(client.client == nullptr || client.connection == nullptr ||
  269. client.connectTicks >= 0) {
  270. return;
  271. }
  272. static const enet_uint32 flags[] = {ENET_PACKET_FLAG_RELIABLE, 0,
  273. ENET_PACKET_FLAG_UNSEQUENCED};
  274. enet_uint8 i = (enet_uint8)mode;
  275. enet_peer_send(client.connection, i,
  276. enet_packet_create(p->data.buffer, p->data.size, flags[i]));
  277. }
  278. static void tickClientEvents(void) {
  279. ENetEvent e;
  280. while(enet_host_service(client.client, &e, 0) >= 0) {
  281. switch(e.type) {
  282. case ENET_EVENT_TYPE_CONNECT:
  283. client.connectTicks = -1;
  284. client.onConnect();
  285. break;
  286. case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
  287. case ENET_EVENT_TYPE_DISCONNECT:
  288. client.disconnectTicks = 0;
  289. client.connectTicks = 0;
  290. client.onDisconnect();
  291. client.connection = nullptr;
  292. break;
  293. case ENET_EVENT_TYPE_RECEIVE: {
  294. InPacket in;
  295. initInPacket(&in, e.packet->data, e.packet->dataLength);
  296. client.onPacket(&in);
  297. enet_packet_destroy(e.packet);
  298. break;
  299. }
  300. case ENET_EVENT_TYPE_NONE: return;
  301. }
  302. }
  303. }
  304. void tickClient(void) {
  305. if(client.client == nullptr) {
  306. return;
  307. }
  308. tickClientEvents();
  309. if(client.connectTicks >= 1 &&
  310. ++client.connectTicks > client.connectTimeoutTicks) {
  311. client.connectTicks = 0;
  312. disconnectClient(client.connectTimeoutTicks);
  313. }
  314. if(client.disconnectTicks >= 1 &&
  315. ++client.disconnectTicks > client.disconnectTimeoutTicks) {
  316. client.disconnectTicks = 0;
  317. client.onDisconnect();
  318. if(client.connection != nullptr) {
  319. enet_peer_reset(client.connection);
  320. client.connection = nullptr;
  321. }
  322. }
  323. }
  324. void setClientConnectHandler(OnServerConnect oc) {
  325. client.onConnect = oc == nullptr ? voidVoidDummy : oc;
  326. }
  327. void setClientDisconnectHandler(OnServerDisconnect od) {
  328. client.onDisconnect = od == nullptr ? voidVoidDummy : od;
  329. }
  330. void setClientPacketHandler(OnServerPacket op) {
  331. client.onPacket = op == nullptr ? voidInPacketDummy : op;
  332. }
  333. void resetClientHandler(void) {
  334. client.onConnect = voidVoidDummy;
  335. client.onDisconnect = voidVoidDummy;
  336. client.onPacket = voidInPacketDummy;
  337. }
  338. bool isClientConnecting(void) {
  339. return client.connectTicks >= 1;
  340. }
  341. bool isClientConnected(void) {
  342. return client.connectTicks < 0;
  343. }
  344. static void voidClientDummy(Client) {
  345. }
  346. static void voidClientInPacketDummy(Client, InPacket*) {
  347. }
  348. typedef struct {
  349. ENetHost* server;
  350. HashMapClient clients;
  351. Client idCounter;
  352. OnClientConnect onConnect;
  353. OnClientDisconnect onDisconnect;
  354. OnClientPacket onPacket;
  355. } ServerData;
  356. static ServerData server = {
  357. nullptr, {0}, 1, voidClientDummy, voidClientDummy, voidClientInPacketDummy};
  358. bool startServer(Port port, size_t maxClients) {
  359. if(maxClients <= 0) {
  360. LOG_ERROR("Invalid max client amount");
  361. return true;
  362. } else if(server.server != nullptr) {
  363. LOG_WARNING("Server already started");
  364. return true;
  365. } else if(addENet()) {
  366. LOG_ERROR("Server cannot initialize enet");
  367. return true;
  368. }
  369. ENetAddress address = {.host = ENET_HOST_ANY, .port = port};
  370. server.server =
  371. FAIL(enet_host_create(&address, maxClients, 3, 0, 0), nullptr);
  372. if(server.server == nullptr) {
  373. stopServer();
  374. LOG_ERROR("Cannot create enet server host");
  375. return true;
  376. }
  377. initHashMapClient(&server.clients);
  378. return false;
  379. }
  380. void stopServer(void) {
  381. if(server.server != nullptr) {
  382. HashMapIteratorClient i;
  383. initHashMapIteratorClient(&i, &server.clients);
  384. while(hasNextHashMapNodeClient(&i)) {
  385. HashMapNodeClient* n = nextHashMapNodeClient(&i);
  386. enet_peer_reset(*n->value);
  387. }
  388. enet_host_destroy(server.server);
  389. server.server = nullptr;
  390. destroyHashMapClient(&server.clients);
  391. }
  392. removeENet();
  393. }
  394. static void writeId(ENetPeer* peer, Client id) {
  395. static_assert(sizeof(peer->data) >= sizeof(id),
  396. "private data not big enough for id");
  397. memcpy(&(peer->data), &id, sizeof(id));
  398. }
  399. static Client getId(ENetPeer* peer) {
  400. assert(peer->data != nullptr);
  401. Client id = -1;
  402. memcpy(&id, &(peer->data), sizeof(id));
  403. return id;
  404. }
  405. static void handleConnect(ENetEvent* e) {
  406. Client id = server.idCounter++;
  407. assert(searchHashMapKeyClient(&server.clients, id) == nullptr);
  408. *putHashMapKeyClient(&server.clients, id) = e->peer;
  409. writeId(e->peer, id);
  410. server.onConnect(id);
  411. }
  412. static void handlePacket(ENetEvent* e) {
  413. Client id = getId(e->peer);
  414. InPacket in;
  415. initInPacket(&in, e->packet->data, e->packet->dataLength);
  416. server.onPacket(id, &in);
  417. }
  418. static void handleDisconnect(ENetEvent* e) {
  419. Client id = getId(e->peer);
  420. server.onDisconnect(id);
  421. removeHashMapKeyClient(&server.clients, id);
  422. }
  423. void tickServer(void) {
  424. if(server.server == nullptr) {
  425. return;
  426. }
  427. ENetEvent e;
  428. while(enet_host_service(server.server, &e, 0) >= 0) {
  429. switch(e.type) {
  430. case ENET_EVENT_TYPE_CONNECT: handleConnect(&e); break;
  431. case ENET_EVENT_TYPE_RECEIVE:
  432. handlePacket(&e);
  433. enet_packet_destroy(e.packet);
  434. break;
  435. case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
  436. case ENET_EVENT_TYPE_DISCONNECT: handleDisconnect(&e); break;
  437. case ENET_EVENT_TYPE_NONE: return;
  438. }
  439. }
  440. }
  441. static ENetPacket* fromBuffer(const Buffer* buffer, enet_uint8 index) {
  442. static const enet_uint32 flags[] = {ENET_PACKET_FLAG_RELIABLE, 0,
  443. ENET_PACKET_FLAG_UNSEQUENCED};
  444. return enet_packet_create(buffer->buffer, buffer->size, flags[index]);
  445. }
  446. void sendServerPacketBroadcast(const OutPacket* p, PacketSendMode mode) {
  447. if(server.server != nullptr) {
  448. enet_uint8 index = (enet_uint8)mode;
  449. enet_host_broadcast(server.server, index, fromBuffer(&p->data, index));
  450. }
  451. }
  452. void sendServerPacket(Client clientId, const OutPacket* p,
  453. PacketSendMode mode) {
  454. if(server.server == nullptr) {
  455. return;
  456. }
  457. ENetPeer** peer = searchHashMapKeyClient(&server.clients, clientId);
  458. if(peer != nullptr) {
  459. enet_uint8 index = (enet_uint8)mode;
  460. enet_peer_send(*peer, index, fromBuffer(&p->data, index));
  461. }
  462. }
  463. void setServerTimeout(Client clientId, u32 timeout, u32 timeoutMin,
  464. u32 timeoutMax) {
  465. if(server.server == nullptr) {
  466. return;
  467. }
  468. ENetPeer** peer = searchHashMapKeyClient(&server.clients, clientId);
  469. if(peer != nullptr) {
  470. enet_peer_timeout(*peer, timeout, timeoutMin, timeoutMax);
  471. }
  472. }
  473. void disconnectServerClient(Client clientId) {
  474. if(server.server == nullptr) {
  475. return;
  476. }
  477. ENetPeer** peer = searchHashMapKeyClient(&server.clients, clientId);
  478. if(peer != nullptr) {
  479. enet_peer_disconnect(*peer, 0);
  480. }
  481. }
  482. void setServerConnectHandler(OnClientConnect oc) {
  483. server.onConnect = oc == nullptr ? voidClientDummy : oc;
  484. }
  485. void setServerDisconnectHandler(OnClientDisconnect od) {
  486. server.onDisconnect = od == nullptr ? voidClientDummy : od;
  487. }
  488. void setServerPacketHandler(OnClientPacket op) {
  489. server.onPacket = op == nullptr ? voidClientInPacketDummy : op;
  490. }
  491. void resetServerHandler(void) {
  492. server.onConnect = voidClientDummy;
  493. server.onDisconnect = voidClientDummy;
  494. server.onPacket = voidClientInPacketDummy;
  495. }