36#define LUA_COMPAT_MODULE
42#define check_host(l, idx)\
43 *(ENetHost**)luaL_checkudata(l, idx, "enet_host")
45#define check_peer(l, idx)\
46 *(ENetPeer**)luaL_checkudata(l, idx, "enet_peer")
54static void parse_address(lua_State *l,
const char *addr_str, ENetAddress *address) {
55 int host_i = 0, port_i = 0;
56 char host_str[128] = {0};
57 char port_str[32] = {0};
58 int scanning_port = 0;
60 char *
c = (
char *)addr_str;
63 if (host_i >= 128 || port_i >= 32 ) luaL_error(l,
"Hostname too long");
65 port_str[port_i++] = *
c;
70 host_str[host_i++] = *
c;
75 host_str[host_i] =
'\0';
76 port_str[port_i] =
'\0';
78 if (host_i == 0) luaL_error(l,
"Failed to parse address");
79 if (port_i == 0) luaL_error(l,
"Missing port in address");
81 if (strcmp(
"*", host_str) == 0) {
82 address->host = ENET_HOST_ANY;
84 if (enet_address_set_host(address, host_str) != 0) {
85 luaL_error(l,
"Failed to resolve host name");
89 if (strcmp(
"*", port_str) == 0) {
90 address->port = ENET_PORT_ANY;
92 address->port = atoi(port_str);
101 for (peer_index = 0; peer_index < enet_host->peerCount; peer_index++) {
102 if (peer == &(enet_host->peers[peer_index]))
106 luaL_error (l,
"enet: could not find peer id!");
111static void push_peer(lua_State *l, ENetPeer *peer) {
113 lua_getfield(l, LUA_REGISTRYINDEX,
"enet_peers");
114 lua_pushlightuserdata(l, peer);
117 if (lua_isnil(l, -1)) {
121 *(ENetPeer**)lua_newuserdata(l,
sizeof(
void*)) = peer;
122 luaL_getmetatable(l,
"enet_peer");
123 lua_setmetatable(l, -2);
125 lua_pushlightuserdata(l, peer);
126 lua_pushvalue(l, -2);
133static void push_event(lua_State *l, ENetEvent *event) {
137 push_peer(l, event->peer);
138 lua_setfield(l, -2,
"peer");
141 switch (event->type) {
142 case ENET_EVENT_TYPE_CONNECT:
143 lua_pushinteger(l, event->data);
144 lua_setfield(l, -2,
"data");
146 lua_pushstring(l,
"connect");
148 case ENET_EVENT_TYPE_DISCONNECT:
149 lua_pushinteger(l, event->data);
150 lua_setfield(l, -2,
"data");
152 lua_pushstring(l,
"disconnect");
154 case ENET_EVENT_TYPE_RECEIVE:
155 lua_pushlstring(l, (
const char *)event->packet->data, event->packet->dataLength);
156 lua_setfield(l, -2,
"data");
158 lua_pushinteger(l, event->channelID);
159 lua_setfield(l, -2,
"channel");
161 lua_pushstring(l,
"receive");
163 enet_packet_destroy(event->packet);
165 case ENET_EVENT_TYPE_NONE:
166 lua_pushstring(l,
"none");
170 lua_setfield(l, -2,
"type");
177static ENetPacket *
read_packet(lua_State *l,
int idx, enet_uint8 *channel_id) {
179 int argc = lua_gettop(l);
180 const void *data = luaL_checklstring(l, idx, &size);
183 enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE;
186 if (argc >= idx+2 && !lua_isnil(l, idx+2)) {
187 const char *flag_str = luaL_checkstring(l, idx+2);
188 if (strcmp(
"unsequenced", flag_str) == 0) {
189 flags = ENET_PACKET_FLAG_UNSEQUENCED;
190 }
else if (strcmp(
"reliable", flag_str) == 0) {
191 flags = ENET_PACKET_FLAG_RELIABLE;
192 }
else if (strcmp(
"unreliable", flag_str) == 0) {
195 luaL_error(l,
"Unknown packet flag: %s", flag_str);
199 if (argc >= idx+1 && !lua_isnil(l, idx+1)) {
200 *channel_id = luaL_checkint(l, idx+1);
203 packet = enet_packet_create(data, size, flags);
204 if (packet == NULL) {
205 luaL_error(l,
"Failed to create packet");
222 size_t peer_count = 64, channel_count = 1;
223 enet_uint32 in_bandwidth = 0, out_bandwidth = 0;
225 int have_address = 1;
228 if (lua_gettop(l) == 0 || lua_isnil(l, 1)) {
234 switch (lua_gettop(l)) {
236 if (!lua_isnil(l, 5)) out_bandwidth = luaL_checkint(l, 5);
239 if (!lua_isnil(l, 4)) in_bandwidth = luaL_checkint(l, 4);
242 if (!lua_isnil(l, 3)) channel_count = luaL_checkint(l, 3);
245 if (!lua_isnil(l, 2)) peer_count = luaL_checkint(l, 2);
250 host = enet_host_create(have_address ? &address : NULL, peer_count,
251 channel_count, in_bandwidth, out_bandwidth);
255 lua_pushstring(l,
"enet: failed to create host (already listening?)");
259 *(ENetHost**)lua_newuserdata(l,
sizeof(
void*)) = host;
260 luaL_getmetatable(l,
"enet_host");
261 lua_setmetatable(l, -2);
266static int linked_version(lua_State *l) {
267 lua_pushfstring(l,
"%d.%d.%d",
268 ENET_VERSION_GET_MAJOR(enet_linked_version()),
269 ENET_VERSION_GET_MINOR(enet_linked_version()),
270 ENET_VERSION_GET_PATCH(enet_linked_version()));
284 ENetHost *host = check_host(l, 1);
286 return luaL_error(l,
"Tried to index a nil host!");
289 int timeout = 0, out;
291 if (lua_gettop(l) > 1)
292 timeout = luaL_checkint(l, 2);
294 out = enet_host_service(host, &event, timeout);
295 if (out == 0)
return 0;
296 if (out < 0)
return luaL_error(l,
"Error during service");
298 push_event(l, &event);
306 ENetHost *host = check_host(l, 1);
308 return luaL_error(l,
"Tried to index a nil host!");
311 int out = enet_host_check_events(host, &event);
312 if (out == 0)
return 0;
313 if (out < 0)
return luaL_error(l,
"Error checking event");
315 push_event(l, &event);
324 ENetHost *host = check_host(l, 1);
326 return luaL_error(l,
"Tried to index a nil host!");
329 int result = enet_host_compress_with_range_coder (host);
331 lua_pushboolean (l, 1);
333 lua_pushboolean (l, 0);
347 ENetHost *host = check_host(l, 1);
349 return luaL_error(l,
"Tried to index a nil host!");
354 enet_uint32 data = 0;
355 size_t channel_count = 1;
359 switch (lua_gettop(l)) {
361 if (!lua_isnil(l, 4)) data = luaL_checkint(l, 4);
365 if (!lua_isnil(l, 3)) channel_count = luaL_checkint(l, 3);
369 peer = enet_host_connect(host, &address, channel_count, data);
372 return luaL_error(l,
"Failed to create peer");
380static int host_flush(lua_State *l) {
381 ENetHost *host = check_host(l, 1);
383 return luaL_error(l,
"Tried to index a nil host!");
385 enet_host_flush(host);
389static int host_broadcast(lua_State *l) {
390 ENetHost *host = check_host(l, 1);
392 return luaL_error(l,
"Tried to index a nil host!");
395 enet_uint8 channel_id;
396 ENetPacket *packet =
read_packet(l, 2, &channel_id);
397 enet_host_broadcast(host, channel_id, packet);
402static int host_channel_limit(lua_State *l) {
403 ENetHost *host = check_host(l, 1);
405 return luaL_error(l,
"Tried to index a nil host!");
407 int limit = luaL_checkint(l, 2);
408 enet_host_channel_limit(host, limit);
412static int host_bandwidth_limit(lua_State *l) {
413 ENetHost *host = check_host(l, 1);
415 return luaL_error(l,
"Tried to index a nil host!");
417 enet_uint32 in_bandwidth = luaL_checkint(l, 2);
418 enet_uint32 out_bandwidth = luaL_checkint(l, 2);
419 enet_host_bandwidth_limit(host, in_bandwidth, out_bandwidth);
423static int host_get_socket_address(lua_State *l) {
424 ENetHost *host = check_host(l, 1);
426 return luaL_error(l,
"Tried to index a nil host!");
429 enet_socket_get_address (host->socket, &address);
431 lua_pushfstring(l,
"%d.%d.%d.%d:%d",
432 ((address.host) & 0xFF),
433 ((address.host >> 8) & 0xFF),
434 ((address.host >> 16) & 0xFF),
435 (address.host >> 24& 0xFF),
440static int host_total_sent_data(lua_State *l) {
441 ENetHost *host = check_host(l, 1);
443 return luaL_error(l,
"Tried to index a nil host!");
446 lua_pushinteger (l, host->totalSentData);
451static int host_total_received_data(lua_State *l) {
452 ENetHost *host = check_host(l, 1);
454 return luaL_error(l,
"Tried to index a nil host!");
457 lua_pushinteger (l, host->totalReceivedData);
461static int host_service_time(lua_State *l) {
462 ENetHost *host = check_host(l, 1);
464 return luaL_error(l,
"Tried to index a nil host!");
467 lua_pushinteger (l, host->serviceTime);
472static int host_peer_count(lua_State *l) {
473 ENetHost *host = check_host(l, 1);
475 return luaL_error(l,
"Tried to index a nil host!");
478 lua_pushinteger (l, host->peerCount);
483static int host_get_peer(lua_State *l) {
484 ENetHost *host = check_host(l, 1);
486 return luaL_error(l,
"Tried to index a nil host!");
489 size_t peer_index = (size_t) luaL_checkint(l, 2) - 1;
491 if (peer_index >= host->peerCount) {
492 luaL_argerror (l, 2,
"Invalid peer index");
495 ENetPeer *peer = &(host->peers[peer_index]);
501static int host_gc(lua_State *l) {
503 ENetHost** host = luaL_checkudata(l, 1,
"enet_host");
506 enet_host_destroy(*host);
512static int peer_tostring(lua_State *l) {
513 ENetPeer *peer = check_peer(l, 1);
515 enet_address_get_host_ip(&peer->address, host_str, 128);
517 lua_pushstring(l, host_str);
518 lua_pushstring(l,
":");
519 lua_pushinteger(l, peer->address.port);
524static int peer_ping(lua_State *l) {
525 ENetPeer *peer = check_peer(l, 1);
526 enet_peer_ping(peer);
530static int peer_throttle_configure(lua_State *l) {
531 ENetPeer *peer = check_peer(l, 1);
533 enet_uint32 interval = luaL_checkint(l, 2);
534 enet_uint32 acceleration = luaL_checkint(l, 3);
535 enet_uint32 deceleration = luaL_checkint(l, 4);
537 enet_peer_throttle_configure(peer, interval, acceleration, deceleration);
541static int peer_round_trip_time(lua_State *l) {
542 ENetPeer *peer = check_peer(l, 1);
544 if (lua_gettop(l) > 1) {
545 enet_uint32 round_trip_time = luaL_checkint(l, 2);
546 peer->roundTripTime = round_trip_time;
549 lua_pushinteger (l, peer->roundTripTime);
554static int peer_last_round_trip_time(lua_State *l) {
555 ENetPeer *peer = check_peer(l, 1);
557 if (lua_gettop(l) > 1) {
558 enet_uint32 round_trip_time = luaL_checkint(l, 2);
559 peer->lastRoundTripTime = round_trip_time;
561 lua_pushinteger (l, peer->lastRoundTripTime);
566static int peer_ping_interval(lua_State *l) {
567 ENetPeer *peer = check_peer(l, 1);
569 if (lua_gettop(l) > 1) {
570 enet_uint32 interval = luaL_checkint(l, 2);
571 enet_peer_ping_interval (peer, interval);
574 lua_pushinteger (l, peer->pingInterval);
579static int peer_timeout(lua_State *l) {
580 ENetPeer *peer = check_peer(l, 1);
582 enet_uint32 timeout_limit = 0;
583 enet_uint32 timeout_minimum = 0;
584 enet_uint32 timeout_maximum = 0;
586 switch (lua_gettop(l)) {
588 if (!lua_isnil(l, 4)) timeout_maximum = luaL_checkint(l, 4);
591 if (!lua_isnil(l, 3)) timeout_minimum = luaL_checkint(l, 3);
594 if (!lua_isnil(l, 2)) timeout_limit = luaL_checkint(l, 2);
597 enet_peer_timeout (peer, timeout_limit, timeout_minimum, timeout_maximum);
599 lua_pushinteger (l, peer->timeoutLimit);
600 lua_pushinteger (l, peer->timeoutMinimum);
601 lua_pushinteger (l, peer->timeoutMaximum);
606static int peer_disconnect(lua_State *l) {
607 ENetPeer *peer = check_peer(l, 1);
609 enet_uint32 data = lua_gettop(l) > 1 ? luaL_checkint(l, 2) : 0;
610 enet_peer_disconnect(peer, data);
614static int peer_disconnect_now(lua_State *l) {
615 ENetPeer *peer = check_peer(l, 1);
617 enet_uint32 data = lua_gettop(l) > 1 ? luaL_checkint(l, 2) : 0;
618 enet_peer_disconnect_now(peer, data);
622static int peer_disconnect_later(lua_State *l) {
623 ENetPeer *peer = check_peer(l, 1);
625 enet_uint32 data = lua_gettop(l) > 1 ? luaL_checkint(l, 2) : 0;
626 enet_peer_disconnect_later(peer, data);
630static int peer_index(lua_State *l) {
631 ENetPeer *peer = check_peer(l, 1);
634 lua_pushinteger (l, peer_index + 1);
639static int peer_state(lua_State *l) {
640 ENetPeer *peer = check_peer(l, 1);
642 switch (peer->state) {
643 case (ENET_PEER_STATE_DISCONNECTED):
644 lua_pushstring (l,
"disconnected");
646 case (ENET_PEER_STATE_CONNECTING):
647 lua_pushstring (l,
"connecting");
649 case (ENET_PEER_STATE_ACKNOWLEDGING_CONNECT):
650 lua_pushstring (l,
"acknowledging_connect");
652 case (ENET_PEER_STATE_CONNECTION_PENDING):
653 lua_pushstring (l,
"connection_pending");
655 case (ENET_PEER_STATE_CONNECTION_SUCCEEDED):
656 lua_pushstring (l,
"connection_succeeded");
658 case (ENET_PEER_STATE_CONNECTED):
659 lua_pushstring (l,
"connected");
661 case (ENET_PEER_STATE_DISCONNECT_LATER):
662 lua_pushstring (l,
"disconnect_later");
664 case (ENET_PEER_STATE_DISCONNECTING):
665 lua_pushstring (l,
"disconnecting");
667 case (ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT):
668 lua_pushstring (l,
"acknowledging_disconnect");
670 case (ENET_PEER_STATE_ZOMBIE):
671 lua_pushstring (l,
"zombie");
674 lua_pushstring (l,
"unknown");
680static int peer_connect_id(lua_State *l) {
681 ENetPeer *peer = check_peer(l, 1);
683 lua_pushinteger (l, peer->connectID);
689static int peer_reset(lua_State *l) {
690 ENetPeer *peer = check_peer(l, 1);
691 enet_peer_reset(peer);
695static int peer_receive(lua_State *l) {
696 ENetPeer *peer = check_peer(l, 1);
698 enet_uint8 channel_id = 0;
700 if (lua_gettop(l) > 1) {
701 channel_id = luaL_checkint(l, 2);
704 packet = enet_peer_receive(peer, &channel_id);
705 if (packet == NULL)
return 0;
707 lua_pushlstring(l, (
const char *)packet->data, packet->dataLength);
708 lua_pushinteger(l, channel_id);
710 enet_packet_destroy(packet);
724 ENetPeer *peer = check_peer(l, 1);
726 enet_uint8 channel_id;
727 ENetPacket *packet =
read_packet(l, 2, &channel_id);
730 int ret = enet_peer_send(peer, channel_id, packet);
732 enet_packet_destroy(packet);
735 lua_pushinteger(l, ret);
740static const struct luaL_Reg enet_funcs [] = {
742 {
"linked_version", linked_version},
746static const struct luaL_Reg enet_host_funcs [] = {
751 {
"flush", host_flush},
752 {
"broadcast", host_broadcast},
753 {
"channel_limit", host_channel_limit},
754 {
"bandwidth_limit", host_bandwidth_limit},
757 {
"get_socket_address", host_get_socket_address},
759 {
"destroy", host_gc},
762 {
"total_sent_data", host_total_sent_data},
763 {
"total_received_data", host_total_received_data},
764 {
"service_time", host_service_time},
765 {
"peer_count", host_peer_count},
766 {
"get_peer", host_get_peer},
770static const struct luaL_Reg enet_peer_funcs [] = {
771 {
"disconnect", peer_disconnect},
772 {
"disconnect_now", peer_disconnect_now},
773 {
"disconnect_later", peer_disconnect_later},
774 {
"reset", peer_reset},
776 {
"receive", peer_receive},
778 {
"throttle_configure", peer_throttle_configure},
779 {
"ping_interval", peer_ping_interval},
780 {
"timeout", peer_timeout},
783 {
"index", peer_index},
784 {
"state", peer_state},
785 {
"connect_id", peer_connect_id},
786 {
"round_trip_time", peer_round_trip_time},
787 {
"last_round_trip_time", peer_last_round_trip_time},
791int luaopen_enet(lua_State *l) {
793 atexit(enet_deinitialize);
796 luaL_newmetatable(l,
"enet_host");
798 luaL_register(l, NULL, enet_host_funcs);
799 lua_setfield(l, -2,
"__index");
800 lua_pushcfunction(l, host_gc);
801 lua_setfield(l, -2,
"__gc");
803 luaL_newmetatable(l,
"enet_peer");
805 luaL_register(l, NULL, enet_peer_funcs);
806 lua_setfield(l, -2,
"__index");
807 lua_pushcfunction(l, peer_tostring);
808 lua_setfield(l, -2,
"__tostring");
814 lua_pushstring(l,
"v");
815 lua_setfield(l, -2,
"__mode");
816 lua_setmetatable(l, -2);
818 lua_setfield(l, LUA_REGISTRYINDEX,
"enet_peers");
820 luaL_register(l,
"enet", enet_funcs);
static int host_service(lua_State *l)
static int host_create(lua_State *l)
static int host_compress_with_range_coder(lua_State *l)
size_t find_peer_index(lua_State *l, ENetHost *enet_host, ENetPeer *peer)
static int host_connect(lua_State *l)
static void parse_address(lua_State *l, const char *addr_str, ENetAddress *address)
static ENetPacket * read_packet(lua_State *l, int idx, enet_uint8 *channel_id)
static int peer_send(lua_State *l)
static int host_check_events(lua_State *l)