Rick Posted September 22, 2011 Share Posted September 22, 2011 [EDIT] Title shouldn't have LE just Lua at this point. This is still pretty early stage but I was able to get a wrapper around RakNet working in Lua. I'm simply using C methods currently so it's not like I did class wrapping for all of RakNet as that would be pretty intense and overkill for what I need. I'll show how I'm doing it in case anyone else is interested, but you would have to download RakNet yourself and compile the code because that's how the RakNet developer wants you do work with his code. He doesn't want precompiled wrappers around his code distributed. RakNetLua.dll is my wrapper. The below code will load the dll for Lua to use. Inside the DLL I define a table as 'raknet' so after calling this that's how you use the methods in the dll. After loading the dll and binding to the connection success message (those all caps are ints that use the same values from RakNet's header) I connect to my server. The connect is async so it then hits the main loop calling an update method for RakNet to check for packets coming in. The server gets my connection request and accepts, causing my ConnectionSuccess lua function to get called. Inside that method I'm create a BitStream (just a structure that you write your data to and then send it after you are finished writing to it) and send the server a game message. In my test server when it see's this game message 1, it'll write back game message 2 and since I've bound that message the GameMessage2 lua method will fire in which it reads the string that the server sent. *Note* This lua example isn't from inside LE. It was basic Lua exe that you can download. I didn't want to introduce LE yet, but there should be no reason this won't work in LE Lua which I will be doing today or tomorrow pending time. package.loadlib("RakNetLua.dll", "luaopen_raknet")() -- this lua function will get called by the DLL given the binding that happens below function ConnectionSuccess(reader) print "Connection success!" -- create a bitstream and write something to it local writer = raknet.net_CreateBitStream(ID_GAME_MESSAGE_1) raknet.net_WriteBitStream(writer, "Welcome") -- send this bitstream to the server raknet.net_Send(writer) end function GameMessage2(reader) print "Inside game message 2" local msg = "" msg = raknet.net_ReadBitStream(reader, TYPE_STRING) print(msg) end -- Bind connection success! raknet.net_BindMessageEvent(ID_CONNECTION_REQUEST_ACCEPTED, "ConnectionSuccess") -- Bind game message raknet.net_BindMessageEvent(ID_GAME_MESSAGE_2, "GameMessage2") raknet.net_Connect("127.0.0.1", 60000) while i == 1 do raknet.net_Update() end Currently this only supports strings and doubles but that's the basic building blocks of most data anyway. Below is the DLL I currently have. It'll change as I refine this. If you were to duplicate this the idea is that you link in Lua 5.1 and RakNet lib which you've registered to download yourself and compiled. Given the post here you should be able to make this yourself if you are interested in using RakNet via Lua. #define LUA_API_EXP __declspec(dllexport) #include "RakPeerInterface.h" #include "MessageIdentifiers.h" #include "BitStream.h" #include "RakNetTypes.h" // MessageID #include <string> #include <map> using namespace std; extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" // prevents the function name from being mangled LUA_API_EXP int luaopen_raknet(lua_State *L); } RakNet::RakPeerInterface *peer = RakNet::RakPeerInterface::GetInstance(); RakNet::Packet *packet; RakNet::SystemAddress serverAddress; map<RakNet::MessageID, string> luaHandlers; static int NetConnect(lua_State* L) { const char* ip = luaL_checkstring(L, 1); int port = luaL_checknumber(L, 2); peer->Startup(1, &RakNet::SocketDescriptor(), 1); peer->Connect(ip, port, 0,0); return 0; } static int NetSend(lua_State* L) { //luaL_checktype(L, 1, LUA_TLIGHTUSERDATA); // cast the first param to the bitstream to send RakNet::BitStream *stream = static_cast<RakNet::BitStream*>(lua_touserdata(L, 1)); // send the bitstream to the server peer->Send(stream, HIGH_PRIORITY, RELIABLE_ORDERED, 0, serverAddress, false); return 0; } static int NetCreateBitStream(lua_State* L) { RakNet::BitStream *stream = new RakNet::BitStream(); // the first parameter is the message id int v1 = luaL_checknumber(L, 1); // write the message id to the bitstream stream->Write((RakNet::MessageID)v1); // return the bitstream to lua lua_pushlightuserdata(L, stream); return 1; } static int NetWriteBitStream(lua_State* L) { // cast the first param to the bitstream to send RakNet::BitStream *stream = static_cast<RakNet::BitStream*>(lua_touserdata(L, 1)); // get the type of the value we want to write to the bitstream int type = lua_type(L, 2); //double vDbl; //const char* vStr; switch(type) { case LUA_TNUMBER: double vDbl; vDbl = luaL_checknumber(L, 2); stream->Write(vDbl); break; case LUA_TBOOLEAN: // TODO: implement boolean values break; case LUA_TSTRING: const char* vStr; vStr = luaL_checkstring(L, 2); RakNet::RakString str = vStr; stream->Write(str); break; } return 0; } static int NetReadBitStream(lua_State* L) { // cast the first param to the bitstream to send RakNet::BitStream *stream = static_cast<RakNet::BitStream*>(lua_touserdata(L, 1)); // get the type to read int type = luaL_checknumber(L, 2); switch(type) { case 0: // double (constant in Lua) double v; stream->Read(v); lua_pushnumber (L, v); break; case 1: // string (constant in Lua) RakNet::RakString str; stream->Read(str); lua_pushstring(L, str.C_String()); break; } return 1; } static int NetBindMessageEvent(lua_State* L) { int msgID = luaL_checknumber(L, 1); const char* luaFunctionName = luaL_checkstring(L, 2); string functionName = luaFunctionName; // link the lua function name to this msg id luaHandlers[msgID] = functionName; return 0; } static int NetUpdate(lua_State* L) { // check for new packets for (packet=peer->Receive(); packet; peer->DeallocatePacket(packet), packet=peer->Receive()) { switch(packet->data[0]) { // if we get connected store off the servers address to use when we send data case ID_CONNECTION_REQUEST_ACCEPTED: serverAddress = packet->systemAddress; break; } // get the lua method to call if(luaHandlers.find(packet->data[0]) != luaHandlers.end()) { lua_getglobal(L, luaHandlers[packet->data[0]].c_str()); // push the bitstream pointer on the lua stack RakNet::BitStream reader(packet->data,packet->length,false); reader.IgnoreBytes(sizeof(RakNet::MessageID)); lua_pushlightuserdata(L, &reader); // call the function (1 param, 0 return) lua_pcall(L, 1, 0, 0); } } return 0; } static const luaL_reg netLib[] = { {"net_Connect", NetConnect}, {"net_Update", NetUpdate}, {"net_BindMessageEvent", NetBindMessageEvent}, {"net_CreateBitStream", NetCreateBitStream}, {"net_Send", NetSend}, {"net_WriteBitStream", NetWriteBitStream}, {"net_ReadBitStream", NetReadBitStream}, {NULL, NULL} }; // lua calls this to open the library LUA_API_EXP int luaopen_raknet (lua_State *L) { luaL_openlib(L, "raknet", netLib, 0); return 1; } I'm open to suggestions/comments/thoughts. Quote Link to comment Share on other sites More sharing options...
YouGroove Posted September 23, 2011 Share Posted September 23, 2011 I'm not planning for the moment multiplayer games, but i could be interested later , is Racknet allowed to use for free and sell a commercial game ? Quote Stop toying and make games Link to comment Share on other sites More sharing options...
Rick Posted September 23, 2011 Author Share Posted September 23, 2011 Yes, up to a certain revenue value. I believe if you make $250,000 you have to start paying them something. Quote Link to comment Share on other sites More sharing options...
gamecreator Posted September 23, 2011 Share Posted September 23, 2011 I don't know Lua but thank you very much for sharing this regardless. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.