Network.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. #include "core/Network.h"
  2. #define ENET_IMPLEMENTATION
  3. #include <core/HashMap.h>
  4. #include <core/Logger.h>
  5. #include <core/Utility.h>
  6. #include <enet.h>
  7. #include <string.h>
  8. #include "ErrorSimulator.h"
  9. typedef CoreOutPacket OutPacket;
  10. void coreInitInPacket(CoreInPacket* in, const void* data, size_t n) {
  11. in->data = data;
  12. in->size = n;
  13. in->index = 0;
  14. }
  15. bool coreInPacketReadU8(CoreInPacket* in, u8* u) {
  16. return coreInPacketRead(in, u, sizeof(*u));
  17. }
  18. bool coreInPacketReadU16(CoreInPacket* in, u16* u) {
  19. if(coreInPacketRead(in, u, sizeof(*u))) {
  20. return true;
  21. }
  22. *u = ntohs(*u);
  23. return false;
  24. }
  25. bool coreInPacketReadU32(CoreInPacket* in, u32* u) {
  26. if(coreInPacketRead(in, u, sizeof(*u))) {
  27. return true;
  28. }
  29. *u = ntohl(*u);
  30. return false;
  31. }
  32. bool coreInPacketReadI8(CoreInPacket* in, i8* i) {
  33. u8 u;
  34. if(coreInPacketReadU8(in, &u)) {
  35. return true;
  36. }
  37. *i = (i8)((i32)u - (i32)128);
  38. return false;
  39. }
  40. bool coreInPacketReadI16(CoreInPacket* in, i16* i) {
  41. u16 u;
  42. if(coreInPacketReadU16(in, &u)) {
  43. return true;
  44. }
  45. *i = (i16)((i32)u - (i32)32768);
  46. return false;
  47. }
  48. bool coreInPacketReadI32(CoreInPacket* in, i32* i) {
  49. u32 u;
  50. if(coreInPacketReadU32(in, &u)) {
  51. return true;
  52. }
  53. if(u < 2147483648) {
  54. *i = (i32)((i32)u - (i32)2147483648);
  55. } else {
  56. *i = (i32)(u - (u32)2147483648);
  57. }
  58. return false;
  59. }
  60. bool coreInPacketReadFloat(CoreInPacket* in, float* f) {
  61. u32 u;
  62. static_assert(sizeof(u) == sizeof(*f), "float and u32 size do not match");
  63. if(coreInPacketReadU32(in, &u)) {
  64. return true;
  65. }
  66. memcpy(f, &u, sizeof(float));
  67. return false;
  68. }
  69. size_t coreInPacketReadString(CoreInPacket* in, char* buffer, size_t n) {
  70. if(n == 0) {
  71. return 0;
  72. }
  73. u16 size;
  74. if(coreInPacketReadU16(in, &size)) {
  75. return 0;
  76. }
  77. size_t end = size;
  78. char* bufferStart = buffer;
  79. n--;
  80. while(n-- > 0 && end > 0) {
  81. end--;
  82. u8 u;
  83. if(coreInPacketReadU8(in, &u)) {
  84. *bufferStart = '\0';
  85. break;
  86. }
  87. *(buffer++) = (char)u;
  88. }
  89. while(end-- > 0 && !coreInPacketReadU8(in, &(u8){0})) {}
  90. *buffer = '\0';
  91. return size;
  92. }
  93. bool coreInPacketRead(CoreInPacket* in, void* buffer, size_t n) {
  94. if(in->index + n > in->size) {
  95. return true;
  96. }
  97. memcpy(buffer, in->data + in->index, n);
  98. in->index += n;
  99. return false;
  100. }
  101. void coreInitOutPacket(OutPacket* out) {
  102. coreInitBuffer(&out->data);
  103. }
  104. void coreDestroyOutPacket(OutPacket* out) {
  105. coreDestroyBuffer(&out->data);
  106. }
  107. OutPacket* coreOutPacketWriteU8(OutPacket* out, u8 u) {
  108. coreAddSizedBufferData(&out->data, &u, sizeof(u));
  109. return out;
  110. }
  111. OutPacket* coreOutPacketWriteU16(OutPacket* out, u16 u) {
  112. u = htons(u);
  113. coreAddSizedBufferData(&out->data, &u, sizeof(u));
  114. return out;
  115. }
  116. OutPacket* coreOutPacketWriteU32(OutPacket* out, u32 u) {
  117. u = htonl(u);
  118. coreAddSizedBufferData(&out->data, &u, sizeof(u));
  119. return out;
  120. }
  121. OutPacket* coreOutPacketWriteI8(OutPacket* out, i8 i) {
  122. if(i < 0) {
  123. return coreOutPacketWriteU8(out, (u8)((i32)i + (i32)128));
  124. }
  125. return coreOutPacketWriteU8(out, (u8)((u32)i + (u32)128));
  126. }
  127. OutPacket* coreOutPacketWriteI16(OutPacket* out, i16 i) {
  128. if(i < 0) {
  129. return coreOutPacketWriteU16(out, (u16)((i32)i + (i32)32768));
  130. }
  131. return coreOutPacketWriteU16(out, (u16)((u32)i + (u32)32768));
  132. }
  133. OutPacket* coreOutPacketWriteI32(OutPacket* out, i32 i) {
  134. if(i < 0) {
  135. return coreOutPacketWriteU32(out, (u32)(i + (i32)2147483648));
  136. }
  137. return coreOutPacketWriteU32(out, (u32)((u32)i + (u32)2147483648));
  138. }
  139. OutPacket* coreOutPacketWriteFloat(OutPacket* out, float f) {
  140. u32 u;
  141. static_assert(sizeof(u) == sizeof(f), "float and u32 size do not match");
  142. memcpy(&u, &f, sizeof(float));
  143. return coreOutPacketWriteU32(out, u);
  144. }
  145. OutPacket* coreOutPacketWriteString(OutPacket* out, const char* s) {
  146. size_t marker = out->data.size;
  147. coreOutPacketWriteU16(out, 0);
  148. size_t end = 0;
  149. while(end < 65534 && *s != '\0') {
  150. coreOutPacketWriteU8(out, (u8)(*(s++)));
  151. end++;
  152. }
  153. coreOutPacketWriteU8(out, 0);
  154. end++;
  155. size_t endMarker = out->data.size;
  156. out->data.size = marker;
  157. coreOutPacketWriteU16(out, (u16)end);
  158. out->data.size = endMarker;
  159. return out;
  160. }
  161. OutPacket* coreOutPacketWrite(OutPacket* out, const void* buffer, size_t n) {
  162. coreAddSizedBufferData(&out->data, buffer, n);
  163. return out;
  164. }
  165. static int enetCounter = 0;
  166. static bool addENet(void) {
  167. if(enetCounter == 0 && CORE_FAIL(enet_initialize() != 0, true)) {
  168. return true;
  169. }
  170. enetCounter++;
  171. return false;
  172. }
  173. static void removeENet(void) {
  174. if(enetCounter > 0 && --enetCounter == 0) {
  175. enet_deinitialize();
  176. }
  177. }
  178. static_assert(sizeof(enet_uint16) == sizeof(CorePort), "port has wrong type");
  179. static void voidVoidDummy(void) {
  180. }
  181. static void voidInPacketDummy(CoreInPacket*) {
  182. }
  183. typedef struct {
  184. ENetHost* client;
  185. ENetPeer* connection;
  186. CoreClientOnConnect onConnect;
  187. CoreClientOnDisconnect onDisconnect;
  188. CoreClientOnPacket onPacket;
  189. int connectTicks;
  190. int connectTimeoutTicks;
  191. int disconnectTicks;
  192. int disconnectTimeoutTicks;
  193. } Client;
  194. static Client client = {
  195. nullptr, nullptr, voidVoidDummy, voidVoidDummy, voidInPacketDummy, 0, 0,
  196. 0, 0};
  197. bool coreClientStart(void) {
  198. if(client.client != nullptr) {
  199. CORE_LOG_WARNING("Client already started");
  200. return true;
  201. } else if(addENet()) {
  202. CORE_LOG_ERROR("Client cannot initialize enet");
  203. return true;
  204. }
  205. client.client = CORE_FAIL(enet_host_create(nullptr, 1, 2, 0, 0), nullptr);
  206. if(client.client == nullptr) {
  207. coreClientStop();
  208. CORE_LOG_ERROR("Cannot create enet client host");
  209. return true;
  210. }
  211. return false;
  212. }
  213. void coreClientStop(void) {
  214. if(client.connection != nullptr) {
  215. client.onDisconnect();
  216. enet_peer_disconnect_now(client.connection, 0);
  217. client.connection = nullptr;
  218. }
  219. if(client.client != nullptr) {
  220. enet_host_destroy(client.client);
  221. client.client = nullptr;
  222. }
  223. removeENet();
  224. client.connectTicks = 0;
  225. client.disconnectTicks = 0;
  226. }
  227. bool coreClientConnect(const char* server, CorePort port, int timeoutTicks) {
  228. if(client.client == nullptr) {
  229. CORE_LOG_WARNING("Client not started");
  230. return true;
  231. } else if(client.connection != nullptr) {
  232. CORE_LOG_WARNING("Connection already exists");
  233. return true;
  234. }
  235. ENetAddress address = {0};
  236. enet_address_set_host(&address, server);
  237. address.port = port;
  238. client.connection =
  239. CORE_FAIL(enet_host_connect(client.client, &address, 3, 0), nullptr);
  240. if(client.connection == nullptr) {
  241. CORE_LOG_ERROR("Cannot create connection");
  242. return true;
  243. }
  244. client.connectTicks = 1;
  245. client.connectTimeoutTicks = timeoutTicks;
  246. return false;
  247. }
  248. void coreClientTimeout(u32 timeout, u32 timeoutMin, u32 timeoutMax) {
  249. if(client.connection != nullptr) {
  250. enet_peer_timeout(client.connection, timeout, timeoutMin, timeoutMax);
  251. }
  252. }
  253. void coreClientDisconnect(int timeoutTicks) {
  254. if(client.connection == nullptr) {
  255. return;
  256. }
  257. client.connectTicks = 0;
  258. enet_peer_disconnect(client.connection, 0);
  259. client.disconnectTicks = 1;
  260. client.disconnectTimeoutTicks = timeoutTicks;
  261. }
  262. void coreClientSend(const OutPacket* p, CorePacketSendMode mode) {
  263. if(client.client == nullptr || client.connection == nullptr ||
  264. client.connectTicks >= 0) {
  265. return;
  266. }
  267. static const enet_uint32 flags[] = {ENET_PACKET_FLAG_RELIABLE, 0,
  268. ENET_PACKET_FLAG_UNSEQUENCED};
  269. enet_uint8 i = (enet_uint8)mode;
  270. enet_peer_send(client.connection, i,
  271. enet_packet_create(p->data.buffer, p->data.size, flags[i]));
  272. }
  273. static void tickClientEvents(void) {
  274. ENetEvent e;
  275. while(enet_host_service(client.client, &e, 0) >= 0) {
  276. switch(e.type) {
  277. case ENET_EVENT_TYPE_CONNECT:
  278. client.connectTicks = -1;
  279. client.onConnect();
  280. break;
  281. case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
  282. case ENET_EVENT_TYPE_DISCONNECT:
  283. client.disconnectTicks = 0;
  284. client.connectTicks = 0;
  285. client.onDisconnect();
  286. client.connection = nullptr;
  287. break;
  288. case ENET_EVENT_TYPE_RECEIVE: {
  289. CoreInPacket in;
  290. coreInitInPacket(&in, e.packet->data, e.packet->dataLength);
  291. client.onPacket(&in);
  292. enet_packet_destroy(e.packet);
  293. break;
  294. }
  295. case ENET_EVENT_TYPE_NONE: return;
  296. }
  297. }
  298. }
  299. void coreClientTick(void) {
  300. if(client.client == nullptr) {
  301. return;
  302. }
  303. tickClientEvents();
  304. if(client.connectTicks >= 1 &&
  305. ++client.connectTicks > client.connectTimeoutTicks) {
  306. client.connectTicks = 0;
  307. coreClientDisconnect(client.connectTimeoutTicks);
  308. }
  309. if(client.disconnectTicks >= 1 &&
  310. ++client.disconnectTicks > client.disconnectTimeoutTicks) {
  311. client.disconnectTicks = 0;
  312. client.onDisconnect();
  313. if(client.connection != nullptr) {
  314. enet_peer_reset(client.connection);
  315. client.connection = nullptr;
  316. }
  317. }
  318. }
  319. void coreClientSetConnectHandler(CoreClientOnConnect oc) {
  320. client.onConnect = oc == nullptr ? voidVoidDummy : oc;
  321. }
  322. void coreClientSetDisconnectHandler(CoreClientOnDisconnect od) {
  323. client.onDisconnect = od == nullptr ? voidVoidDummy : od;
  324. }
  325. void coreClientSetPacketHandler(CoreClientOnPacket op) {
  326. client.onPacket = op == nullptr ? voidInPacketDummy : op;
  327. }
  328. void coreClientResetHandler(void) {
  329. client.onConnect = voidVoidDummy;
  330. client.onDisconnect = voidVoidDummy;
  331. client.onPacket = voidInPacketDummy;
  332. }
  333. bool coreClientIsConnecting(void) {
  334. return client.connectTicks >= 1;
  335. }
  336. bool coreClientIsConnected(void) {
  337. return client.connectTicks < 0;
  338. }
  339. static void voidClientDummy(CoreClient) {
  340. }
  341. static void voidClientInPacketDummy(CoreClient, CoreInPacket*) {
  342. }
  343. typedef struct {
  344. ENetHost* server;
  345. CoreHashMap clients; // CoreClient -> ENetPeer*
  346. CoreClient idCounter;
  347. CoreServerOnConnect onConnect;
  348. CoreServerOnDisconnect onDisconnect;
  349. CoreServerOnPacket onPacket;
  350. } Server;
  351. static Server server = {
  352. nullptr, {0}, 1, voidClientDummy, voidClientDummy, voidClientInPacketDummy};
  353. bool coreServerStart(CorePort port, size_t maxClients) {
  354. if(maxClients <= 0) {
  355. CORE_LOG_ERROR("Invalid max client amount");
  356. return true;
  357. } else if(server.server != nullptr) {
  358. CORE_LOG_WARNING("Server already started");
  359. return true;
  360. } else if(addENet()) {
  361. CORE_LOG_ERROR("Server cannot initialize enet");
  362. return true;
  363. }
  364. ENetAddress address = {.host = ENET_HOST_ANY, .port = port};
  365. server.server =
  366. CORE_FAIL(enet_host_create(&address, maxClients, 3, 0, 0), nullptr);
  367. if(server.server == nullptr) {
  368. coreServerStop();
  369. CORE_LOG_ERROR("Cannot create enet server host");
  370. return true;
  371. }
  372. coreInitHashMap(&server.clients, sizeof(CoreClient), sizeof(ENetPeer*));
  373. return false;
  374. }
  375. void coreServerStop(void) {
  376. if(server.server != nullptr) {
  377. CoreHashMapIterator i;
  378. coreInitHashMapIterator(&i, &server.clients);
  379. while(coreHashMapHasNext(&i)) {
  380. CoreHashMapNode* n = coreHashMapNext(&i);
  381. enet_peer_reset(coreHashMapValue(n, ENetPeer*));
  382. }
  383. enet_host_destroy(server.server);
  384. server.server = nullptr;
  385. coreDestroyHashMap(&server.clients);
  386. }
  387. removeENet();
  388. }
  389. static void writeId(ENetPeer* peer, CoreClient id) {
  390. static_assert(sizeof(peer->data) >= sizeof(id),
  391. "private data not big enough for id");
  392. memcpy(&(peer->data), &id, sizeof(id));
  393. }
  394. static CoreClient getId(ENetPeer* peer) {
  395. CoreClient id = -1;
  396. memcpy(&id, &(peer->data), sizeof(id));
  397. return id;
  398. }
  399. static void handleConnect(ENetEvent* e) {
  400. CoreClient id = server.idCounter++;
  401. if(coreHashMapContains(&server.clients, CoreClient, id)) {
  402. CORE_LOG_WARNING("Id is connected twice");
  403. return;
  404. }
  405. coreHashMapPut(&server.clients, CoreClient, id, ENetPeer*, e->peer);
  406. writeId(e->peer, id);
  407. server.onConnect(id);
  408. }
  409. static void handlePacket(ENetEvent* e) {
  410. if(e->peer->data == nullptr) {
  411. CORE_LOG_WARNING("Client without data sent package");
  412. return;
  413. }
  414. CoreClient id = getId(e->peer);
  415. CoreInPacket in;
  416. coreInitInPacket(&in, e->packet->data, e->packet->dataLength);
  417. server.onPacket(id, &in);
  418. }
  419. static void handleDisconnect(ENetEvent* e) {
  420. if(e->peer->data == nullptr) {
  421. CORE_LOG_WARNING("Client without data disconnected");
  422. return;
  423. }
  424. CoreClient id = getId(e->peer);
  425. server.onDisconnect(id);
  426. if(!coreHashMapRemove(&server.clients, CoreClient, id)) {
  427. CORE_LOG_WARNING("Removed non existing client");
  428. }
  429. }
  430. void coreServerTick(void) {
  431. if(server.server == nullptr) {
  432. return;
  433. }
  434. ENetEvent e;
  435. while(enet_host_service(server.server, &e, 0) > 0) {
  436. switch(e.type) {
  437. case ENET_EVENT_TYPE_CONNECT: handleConnect(&e); break;
  438. case ENET_EVENT_TYPE_RECEIVE:
  439. handlePacket(&e);
  440. enet_packet_destroy(e.packet);
  441. break;
  442. case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
  443. case ENET_EVENT_TYPE_DISCONNECT: handleDisconnect(&e); break;
  444. case ENET_EVENT_TYPE_NONE: return;
  445. }
  446. }
  447. }
  448. static ENetPacket* fromBuffer(const CoreBuffer* buffer, enet_uint8 index) {
  449. static const enet_uint32 flags[] = {ENET_PACKET_FLAG_RELIABLE, 0,
  450. ENET_PACKET_FLAG_UNSEQUENCED};
  451. return enet_packet_create(buffer->buffer, buffer->size, flags[index]);
  452. }
  453. void coreServerSendAll(const CoreOutPacket* p, CorePacketSendMode mode) {
  454. if(server.server != nullptr) {
  455. enet_uint8 index = (enet_uint8)mode;
  456. enet_host_broadcast(server.server, index, fromBuffer(&p->data, index));
  457. }
  458. }
  459. void coreServerSend(CoreClient clientId, const CoreOutPacket* p,
  460. CorePacketSendMode mode) {
  461. if(server.server == nullptr) {
  462. return;
  463. }
  464. ENetPeer** peer = coreHashMapSearchPointer(&server.clients, &clientId);
  465. if(peer != nullptr) {
  466. enet_uint8 index = (enet_uint8)mode;
  467. enet_peer_send(*peer, index, fromBuffer(&p->data, index));
  468. }
  469. }
  470. void coreServerDisconnect(CoreClient clientId) {
  471. if(server.server == nullptr) {
  472. return;
  473. }
  474. ENetPeer** peer = coreHashMapSearchPointer(&server.clients, &clientId);
  475. if(peer != nullptr) {
  476. enet_peer_disconnect(*peer, 0);
  477. }
  478. }
  479. void coreServerSetConnectHandler(CoreServerOnConnect oc) {
  480. server.onConnect = oc == nullptr ? voidClientDummy : oc;
  481. }
  482. void coreServerSetDisconnectHandler(CoreServerOnDisconnect od) {
  483. server.onDisconnect = od == nullptr ? voidClientDummy : od;
  484. }
  485. void coreServerSetPacketHandler(CoreServerOnPacket op) {
  486. server.onPacket = op == nullptr ? voidClientInPacketDummy : op;
  487. }
  488. void coreServerResetHandler(void) {
  489. server.onConnect = voidClientDummy;
  490. server.onDisconnect = voidClientDummy;
  491. server.onPacket = voidClientInPacketDummy;
  492. }