38#define LUA_COMPAT_MODULE
44#define check_host(l, idx)\
45 *(ENetHost**)luaL_checkudata(l, idx, "enet_host")
47#define check_peer(l, idx)\
48 *(ENetPeer**)luaL_checkudata(l, idx, "enet_peer")
56static void parse_address(lua_State *l,
const char *addr_str, ENetAddress *address) {
57 int host_i = 0, port_i = 0;
58 char host_str[128] = {0};
59 char port_str[32] = {0};
60 int scanning_port = 0;
62 char *
c = (
char *)addr_str;
65 if (host_i >= 128 || port_i >= 32 ) luaL_error(l,
"Hostname too long");
67 port_str[port_i++] = *
c;
72 host_str[host_i++] = *
c;
77 host_str[host_i] =
'\0';
78 port_str[port_i] =
'\0';
80 if (host_i == 0) luaL_error(l,
"Failed to parse address");
81 if (port_i == 0) luaL_error(l,
"Missing port in address");
83 if (strcmp(
"*", host_str) == 0) {
84 address->host = ENET_HOST_ANY;
86 if (enet_address_set_host(address, host_str) != 0) {
87 luaL_error(l,
"Failed to resolve host name");
91 if (strcmp(
"*", port_str) == 0) {
92 address->port = ENET_PORT_ANY;
94 address->port = atoi(port_str);
103 for (peer_index = 0; peer_index < enet_host->peerCount; peer_index++) {
104 if (peer == &(enet_host->peers[peer_index]))
108 luaL_error (l,
"enet: could not find peer id!");
113static void push_peer(lua_State *l, ENetPeer *peer) {
115 lua_getfield(l, LUA_REGISTRYINDEX,
"enet_peers");
116 lua_pushlightuserdata(l, peer);
119 if (lua_isnil(l, -1)) {
123 *(ENetPeer**)lua_newuserdata(l,
sizeof(
void*)) = peer;
124 luaL_getmetatable(l,
"enet_peer");
125 lua_setmetatable(l, -2);
127 lua_pushlightuserdata(l, peer);
128 lua_pushvalue(l, -2);
135static void push_event(lua_State *l, ENetEvent *event) {
139 push_peer(l, event->peer);
140 lua_setfield(l, -2,
"peer");
143 switch (event->type) {
144 case ENET_EVENT_TYPE_CONNECT:
145 lua_pushinteger(l, event->data);
146 lua_setfield(l, -2,
"data");
148 lua_pushstring(l,
"connect");
150 case ENET_EVENT_TYPE_DISCONNECT:
151 lua_pushinteger(l, event->data);
152 lua_setfield(l, -2,
"data");
154 lua_pushstring(l,
"disconnect");
156 case ENET_EVENT_TYPE_RECEIVE:
157 lua_pushlstring(l, (
const char *)event->packet->data, event->packet->dataLength);
158 lua_setfield(l, -2,
"data");
160 lua_pushinteger(l, event->channelID);
161 lua_setfield(l, -2,
"channel");
163 lua_pushstring(l,
"receive");
165 enet_packet_destroy(event->packet);
167 case ENET_EVENT_TYPE_NONE:
168 lua_pushstring(l,
"none");
172 lua_setfield(l, -2,
"type");
179static ENetPacket *
read_packet(lua_State *l,
int idx, enet_uint8 *channel_id) {
181 int argc = lua_gettop(l);
182 const void *data = luaL_checklstring(l, idx, &size);
185 enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE;
188 if (argc >= idx+2 && !lua_isnil(l, idx+2)) {
189 const char *flag_str = luaL_checkstring(l, idx+2);
190 if (strcmp(
"unsequenced", flag_str) == 0) {
191 flags = ENET_PACKET_FLAG_UNSEQUENCED;
192 }
else if (strcmp(
"reliable", flag_str) == 0) {
193 flags = ENET_PACKET_FLAG_RELIABLE;
194 }
else if (strcmp(
"unreliable", flag_str) == 0) {
197 luaL_error(l,
"Unknown packet flag: %s", flag_str);
201 if (argc >= idx+1 && !lua_isnil(l, idx+1)) {
202 *channel_id = luaL_checkint(l, idx+1);
205 packet = enet_packet_create(data, size, flags);
206 if (packet == NULL) {
207 luaL_error(l,
"Failed to create packet");
224 size_t peer_count = 64, channel_count = 1;
225 enet_uint32 in_bandwidth = 0, out_bandwidth = 0;
227 int have_address = 1;
230 if (lua_gettop(l) == 0 || lua_isnil(l, 1)) {
236 switch (lua_gettop(l)) {
238 if (!lua_isnil(l, 5)) out_bandwidth = luaL_checkint(l, 5);
241 if (!lua_isnil(l, 4)) in_bandwidth = luaL_checkint(l, 4);
244 if (!lua_isnil(l, 3)) channel_count = luaL_checkint(l, 3);
247 if (!lua_isnil(l, 2)) peer_count = luaL_checkint(l, 2);
252 host = enet_host_create(have_address ? &address : NULL, peer_count,
253 channel_count, in_bandwidth, out_bandwidth);
257 lua_pushstring(l,
"enet: failed to create host (already listening?)");
261 *(ENetHost**)lua_newuserdata(l,
sizeof(
void*)) = host;
262 luaL_getmetatable(l,
"enet_host");
263 lua_setmetatable(l, -2);
268static int linked_version(lua_State *l) {
269 lua_pushfstring(l,
"%d.%d.%d",
270 ENET_VERSION_GET_MAJOR(enet_linked_version()),
271 ENET_VERSION_GET_MINOR(enet_linked_version()),
272 ENET_VERSION_GET_PATCH(enet_linked_version()));
286 ENetHost *host = check_host(l, 1);
288 return luaL_error(l,
"Tried to index a nil host!");
291 int timeout = 0, out;
293 if (lua_gettop(l) > 1)
294 timeout = luaL_checkint(l, 2);
296 out = enet_host_service(host, &event, timeout);
297 if (out == 0)
return 0;
298 if (out < 0)
return luaL_error(l,
"Error during service");
300 push_event(l, &event);
308 ENetHost *host = check_host(l, 1);
310 return luaL_error(l,
"Tried to index a nil host!");
313 int out = enet_host_check_events(host, &event);
314 if (out == 0)
return 0;
315 if (out < 0)
return luaL_error(l,
"Error checking event");
317 push_event(l, &event);
326 ENetHost *host = check_host(l, 1);
328 return luaL_error(l,
"Tried to index a nil host!");
331 int result = enet_host_compress_with_range_coder (host);
333 lua_pushboolean (l, 1);
335 lua_pushboolean (l, 0);
349 ENetHost *host = check_host(l, 1);
351 return luaL_error(l,
"Tried to index a nil host!");
356 enet_uint32 data = 0;
357 size_t channel_count = 1;
361 switch (lua_gettop(l)) {
363 if (!lua_isnil(l, 4)) data = luaL_checkint(l, 4);
367 if (!lua_isnil(l, 3)) channel_count = luaL_checkint(l, 3);
371 peer = enet_host_connect(host, &address, channel_count, data);
374 return luaL_error(l,
"Failed to create peer");
382static int host_flush(lua_State *l) {
383 ENetHost *host = check_host(l, 1);
385 return luaL_error(l,
"Tried to index a nil host!");
387 enet_host_flush(host);
391static int host_broadcast(lua_State *l) {
392 ENetHost *host = check_host(l, 1);
394 return luaL_error(l,
"Tried to index a nil host!");
397 enet_uint8 channel_id;
398 ENetPacket *packet =
read_packet(l, 2, &channel_id);
399 enet_host_broadcast(host, channel_id, packet);
404static int host_channel_limit(lua_State *l) {
405 ENetHost *host = check_host(l, 1);
407 return luaL_error(l,
"Tried to index a nil host!");
409 int limit = luaL_checkint(l, 2);
410 enet_host_channel_limit(host, limit);
414static int host_bandwidth_limit(lua_State *l) {
415 ENetHost *host = check_host(l, 1);
417 return luaL_error(l,
"Tried to index a nil host!");
419 enet_uint32 in_bandwidth = luaL_checkint(l, 2);
420 enet_uint32 out_bandwidth = luaL_checkint(l, 2);
421 enet_host_bandwidth_limit(host, in_bandwidth, out_bandwidth);
425static int host_get_socket_address(lua_State *l) {
426 ENetHost *host = check_host(l, 1);
428 return luaL_error(l,
"Tried to index a nil host!");
431 enet_socket_get_address (host->socket, &address);
433 lua_pushfstring(l,
"%d.%d.%d.%d:%d",
434 ((address.host) & 0xFF),
435 ((address.host >> 8) & 0xFF),
436 ((address.host >> 16) & 0xFF),
437 (address.host >> 24& 0xFF),
442static int host_total_sent_data(lua_State *l) {
443 ENetHost *host = check_host(l, 1);
445 return luaL_error(l,
"Tried to index a nil host!");
448 lua_pushinteger (l, host->totalSentData);
453static int host_total_received_data(lua_State *l) {
454 ENetHost *host = check_host(l, 1);
456 return luaL_error(l,
"Tried to index a nil host!");
459 lua_pushinteger (l, host->totalReceivedData);
463static int host_service_time(lua_State *l) {
464 ENetHost *host = check_host(l, 1);
466 return luaL_error(l,
"Tried to index a nil host!");
469 lua_pushinteger (l, host->serviceTime);
474static int host_peer_count(lua_State *l) {
475 ENetHost *host = check_host(l, 1);
477 return luaL_error(l,
"Tried to index a nil host!");
480 lua_pushinteger (l, host->peerCount);
485static int host_get_peer(lua_State *l) {
486 ENetHost *host = check_host(l, 1);
488 return luaL_error(l,
"Tried to index a nil host!");
491 size_t peer_index = (size_t) luaL_checkint(l, 2) - 1;
493 if (peer_index >= host->peerCount) {
494 luaL_argerror (l, 2,
"Invalid peer index");
497 ENetPeer *peer = &(host->peers[peer_index]);
503static int host_gc(lua_State *l) {
505 ENetHost** host = luaL_checkudata(l, 1,
"enet_host");
508 enet_host_destroy(*host);
514static int peer_tostring(lua_State *l) {
515 ENetPeer *peer = check_peer(l, 1);
517 enet_address_get_host_ip(&peer->address, host_str, 128);
519 lua_pushstring(l, host_str);
520 lua_pushstring(l,
":");
521 lua_pushinteger(l, peer->address.port);
526static int peer_ping(lua_State *l) {
527 ENetPeer *peer = check_peer(l, 1);
528 enet_peer_ping(peer);
532static int peer_throttle_configure(lua_State *l) {
533 ENetPeer *peer = check_peer(l, 1);
535 enet_uint32 interval = luaL_checkint(l, 2);
536 enet_uint32 acceleration = luaL_checkint(l, 3);
537 enet_uint32 deceleration = luaL_checkint(l, 4);
539 enet_peer_throttle_configure(peer, interval, acceleration, deceleration);
543static int peer_round_trip_time(lua_State *l) {
544 ENetPeer *peer = check_peer(l, 1);
546 if (lua_gettop(l) > 1) {
547 enet_uint32 round_trip_time = luaL_checkint(l, 2);
548 peer->roundTripTime = round_trip_time;
551 lua_pushinteger (l, peer->roundTripTime);
556static int peer_last_round_trip_time(lua_State *l) {
557 ENetPeer *peer = check_peer(l, 1);
559 if (lua_gettop(l) > 1) {
560 enet_uint32 round_trip_time = luaL_checkint(l, 2);
561 peer->lastRoundTripTime = round_trip_time;
563 lua_pushinteger (l, peer->lastRoundTripTime);
568static int peer_ping_interval(lua_State *l) {
569 ENetPeer *peer = check_peer(l, 1);
571 if (lua_gettop(l) > 1) {
572 enet_uint32 interval = luaL_checkint(l, 2);
573 enet_peer_ping_interval (peer, interval);
576 lua_pushinteger (l, peer->pingInterval);
581static int peer_timeout(lua_State *l) {
582 ENetPeer *peer = check_peer(l, 1);
584 enet_uint32 timeout_limit = 0;
585 enet_uint32 timeout_minimum = 0;
586 enet_uint32 timeout_maximum = 0;
588 switch (lua_gettop(l)) {
590 if (!lua_isnil(l, 4)) timeout_maximum = luaL_checkint(l, 4);
593 if (!lua_isnil(l, 3)) timeout_minimum = luaL_checkint(l, 3);
596 if (!lua_isnil(l, 2)) timeout_limit = luaL_checkint(l, 2);
599 enet_peer_timeout (peer, timeout_limit, timeout_minimum, timeout_maximum);
601 lua_pushinteger (l, peer->timeoutLimit);
602 lua_pushinteger (l, peer->timeoutMinimum);
603 lua_pushinteger (l, peer->timeoutMaximum);
608static int peer_disconnect(lua_State *l) {
609 ENetPeer *peer = check_peer(l, 1);
611 enet_uint32 data = lua_gettop(l) > 1 ? luaL_checkint(l, 2) : 0;
612 enet_peer_disconnect(peer, data);
616static int peer_disconnect_now(lua_State *l) {
617 ENetPeer *peer = check_peer(l, 1);
619 enet_uint32 data = lua_gettop(l) > 1 ? luaL_checkint(l, 2) : 0;
620 enet_peer_disconnect_now(peer, data);
624static int peer_disconnect_later(lua_State *l) {
625 ENetPeer *peer = check_peer(l, 1);
627 enet_uint32 data = lua_gettop(l) > 1 ? luaL_checkint(l, 2) : 0;
628 enet_peer_disconnect_later(peer, data);
632static int peer_index(lua_State *l) {
633 ENetPeer *peer = check_peer(l, 1);
636 lua_pushinteger (l, peer_index + 1);
641static int peer_state(lua_State *l) {
642 ENetPeer *peer = check_peer(l, 1);
644 switch (peer->state) {
645 case (ENET_PEER_STATE_DISCONNECTED):
646 lua_pushstring (l,
"disconnected");
648 case (ENET_PEER_STATE_CONNECTING):
649 lua_pushstring (l,
"connecting");
651 case (ENET_PEER_STATE_ACKNOWLEDGING_CONNECT):
652 lua_pushstring (l,
"acknowledging_connect");
654 case (ENET_PEER_STATE_CONNECTION_PENDING):
655 lua_pushstring (l,
"connection_pending");
657 case (ENET_PEER_STATE_CONNECTION_SUCCEEDED):
658 lua_pushstring (l,
"connection_succeeded");
660 case (ENET_PEER_STATE_CONNECTED):
661 lua_pushstring (l,
"connected");
663 case (ENET_PEER_STATE_DISCONNECT_LATER):
664 lua_pushstring (l,
"disconnect_later");
666 case (ENET_PEER_STATE_DISCONNECTING):
667 lua_pushstring (l,
"disconnecting");
669 case (ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT):
670 lua_pushstring (l,
"acknowledging_disconnect");
672 case (ENET_PEER_STATE_ZOMBIE):
673 lua_pushstring (l,
"zombie");
676 lua_pushstring (l,
"unknown");
682static int peer_connect_id(lua_State *l) {
683 ENetPeer *peer = check_peer(l, 1);
685 lua_pushinteger (l, peer->connectID);
691static int peer_reset(lua_State *l) {
692 ENetPeer *peer = check_peer(l, 1);
693 enet_peer_reset(peer);
697static int peer_receive(lua_State *l) {
698 ENetPeer *peer = check_peer(l, 1);
700 enet_uint8 channel_id = 0;
702 if (lua_gettop(l) > 1) {
703 channel_id = luaL_checkint(l, 2);
706 packet = enet_peer_receive(peer, &channel_id);
707 if (packet == NULL)
return 0;
709 lua_pushlstring(l, (
const char *)packet->data, packet->dataLength);
710 lua_pushinteger(l, channel_id);
712 enet_packet_destroy(packet);
726 ENetPeer *peer = check_peer(l, 1);
728 enet_uint8 channel_id;
729 ENetPacket *packet =
read_packet(l, 2, &channel_id);
732 int ret = enet_peer_send(peer, channel_id, packet);
734 enet_packet_destroy(packet);
737 lua_pushinteger(l, ret);
742static const struct luaL_Reg enet_funcs [] = {
744 {
"linked_version", linked_version},
748static const struct luaL_Reg enet_host_funcs [] = {
753 {
"flush", host_flush},
754 {
"broadcast", host_broadcast},
755 {
"channel_limit", host_channel_limit},
756 {
"bandwidth_limit", host_bandwidth_limit},
759 {
"get_socket_address", host_get_socket_address},
761 {
"destroy", host_gc},
764 {
"total_sent_data", host_total_sent_data},
765 {
"total_received_data", host_total_received_data},
766 {
"service_time", host_service_time},
767 {
"peer_count", host_peer_count},
768 {
"get_peer", host_get_peer},
772static const struct luaL_Reg enet_peer_funcs [] = {
773 {
"disconnect", peer_disconnect},
774 {
"disconnect_now", peer_disconnect_now},
775 {
"disconnect_later", peer_disconnect_later},
776 {
"reset", peer_reset},
778 {
"receive", peer_receive},
780 {
"throttle_configure", peer_throttle_configure},
781 {
"ping_interval", peer_ping_interval},
782 {
"timeout", peer_timeout},
785 {
"index", peer_index},
786 {
"state", peer_state},
787 {
"connect_id", peer_connect_id},
788 {
"round_trip_time", peer_round_trip_time},
789 {
"last_round_trip_time", peer_last_round_trip_time},
793int luaopen_enet(lua_State *l) {
795 atexit(enet_deinitialize);
798 luaL_newmetatable(l,
"enet_host");
800 luaL_register(l, NULL, enet_host_funcs);
801 lua_setfield(l, -2,
"__index");
802 lua_pushcfunction(l, host_gc);
803 lua_setfield(l, -2,
"__gc");
805 luaL_newmetatable(l,
"enet_peer");
807 luaL_register(l, NULL, enet_peer_funcs);
808 lua_setfield(l, -2,
"__index");
809 lua_pushcfunction(l, peer_tostring);
810 lua_setfield(l, -2,
"__tostring");
816 lua_pushstring(l,
"v");
817 lua_setfield(l, -2,
"__mode");
818 lua_setmetatable(l, -2);
820 lua_setfield(l, LUA_REGISTRYINDEX,
"enet_peers");
822 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)