mirror of
https://github.com/Kiritow/LuaEngine.git
synced 2024-03-22 13:11:45 +08:00
LuaEngine v0.3
This commit is contained in:
parent
3abf10ed2b
commit
71059fda47
|
@ -11,8 +11,10 @@ void InitLuaEngine(lua_State* L)
|
||||||
InitMusic(L);
|
InitMusic(L);
|
||||||
InitCommon(L);
|
InitCommon(L);
|
||||||
InitTCPSocket(L);
|
InitTCPSocket(L);
|
||||||
InitThread(L);
|
InitUDPSocket(L);
|
||||||
|
InitNetwork(L);
|
||||||
InitSocketSelector(L);
|
InitSocketSelector(L);
|
||||||
|
InitThread(L);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitEngine()
|
void InitEngine()
|
||||||
|
@ -26,7 +28,7 @@ void InitEngine()
|
||||||
SDL_Log("Mix_OpenAudio: %s\n", Mix_GetError());
|
SDL_Log("Mix_OpenAudio: %s\n", Mix_GetError());
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
Mix_AllocateChannels(16);
|
||||||
// Stop text input event
|
// Stop text input event
|
||||||
SDL_StopTextInput();
|
SDL_StopTextInput();
|
||||||
|
|
||||||
|
|
24
Music.cpp
24
Music.cpp
|
@ -4,7 +4,8 @@
|
||||||
module Music
|
module Music
|
||||||
load(filename: string): MusicMedia
|
load(filename: string): MusicMedia
|
||||||
loadChunk(filename: string): ChunkMedia
|
loadChunk(filename: string): ChunkMedia
|
||||||
play(music: MusicMedia, [loops: int])
|
play(music: MusicMedia, [loops: int]) Loops default to 1 time
|
||||||
|
playChunk(chunk: ChunkMedia, channel: int, [loops: int]) Loops default to 1 time.
|
||||||
pause()
|
pause()
|
||||||
resume()
|
resume()
|
||||||
*/
|
*/
|
||||||
|
@ -106,7 +107,7 @@ int music_loadchunkmem(lua_State* L)
|
||||||
int music_play(lua_State* L)
|
int music_play(lua_State* L)
|
||||||
{
|
{
|
||||||
auto music = lua_checkpointer<Mix_Music>(L, 1, "LuaEngineMusicMedia");
|
auto music = lua_checkpointer<Mix_Music>(L, 1, "LuaEngineMusicMedia");
|
||||||
int loops = -1;
|
int loops = 0;
|
||||||
if (!lua_isnone(L, 2))
|
if (!lua_isnone(L, 2))
|
||||||
{
|
{
|
||||||
loops = luaL_checkinteger(L, 2);
|
loops = luaL_checkinteger(L, 2);
|
||||||
|
@ -118,6 +119,24 @@ int music_play(lua_State* L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int music_playchunk(lua_State* L)
|
||||||
|
{
|
||||||
|
auto chunk = lua_checkpointer<Mix_Chunk>(L, 1, "LuaEngineChunkMedia");
|
||||||
|
int channel = luaL_checkinteger(L, 2);
|
||||||
|
int loops = 0;
|
||||||
|
if (!lua_isnone(L, 3))
|
||||||
|
{
|
||||||
|
loops = luaL_checkinteger(L, 3);
|
||||||
|
}
|
||||||
|
int ret = Mix_PlayChannel(channel, chunk, loops);
|
||||||
|
if (ret == -1)
|
||||||
|
{
|
||||||
|
return MixError(L, Mix_PlayChannel);
|
||||||
|
}
|
||||||
|
lua_pushinteger(L, ret);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int music_pause(lua_State* L)
|
int music_pause(lua_State* L)
|
||||||
{
|
{
|
||||||
Mix_PauseMusic();
|
Mix_PauseMusic();
|
||||||
|
@ -140,6 +159,7 @@ void InitMusic(lua_State* L)
|
||||||
lua_setfield_function(L, "loadChunk", music_loadchunk);
|
lua_setfield_function(L, "loadChunk", music_loadchunk);
|
||||||
lua_setfield_function(L, "loadChunkmem", music_loadchunkmem);
|
lua_setfield_function(L, "loadChunkmem", music_loadchunkmem);
|
||||||
lua_setfield_function(L, "play", music_play);
|
lua_setfield_function(L, "play", music_play);
|
||||||
|
lua_setfield_function(L, "playChunk", music_playchunk);
|
||||||
lua_setfield_function(L, "pause", music_pause);
|
lua_setfield_function(L, "pause", music_pause);
|
||||||
lua_setfield_function(L, "resume", music_resume);
|
lua_setfield_function(L, "resume", music_resume);
|
||||||
lua_setfield(L, -2, "Music");
|
lua_setfield(L, -2, "Music");
|
||||||
|
|
57
NetworkWin.cpp
Normal file
57
NetworkWin.cpp
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#include "include.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define _WIN32_WINNT 0x0A00 // Win10
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
int network_getip(lua_State* L)
|
||||||
|
{
|
||||||
|
const char* host = luaL_checkstring(L, 1);
|
||||||
|
addrinfo* result = NULL;
|
||||||
|
|
||||||
|
if (getaddrinfo(host, NULL, NULL, &result) < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "getaddrinfo");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cnt = 0;
|
||||||
|
for (addrinfo* pinfo = result; pinfo; pinfo = pinfo->ai_next)
|
||||||
|
{
|
||||||
|
switch (pinfo->ai_family)
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
{
|
||||||
|
char buffer[1024] = { 0 };
|
||||||
|
if (inet_ntop(AF_INET, &((sockaddr_in*)(pinfo->ai_addr))->sin_addr, buffer, 1024))
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "inet_ntop");
|
||||||
|
freeaddrinfo(result);
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
lua_pushstring(L, buffer);
|
||||||
|
cnt++;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freeaddrinfo(result);
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitNetwork(lua_State* L)
|
||||||
|
{
|
||||||
|
lua_getglobal(L, "package");
|
||||||
|
lua_getfield(L, -1, "loaded");
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_setfield_function(L, "getip", network_getip);
|
||||||
|
lua_setfield(L, -2, "network");
|
||||||
|
lua_pop(L, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // End of _WIN32
|
114
SelectWin.cpp
114
SelectWin.cpp
|
@ -1,5 +1,5 @@
|
||||||
#include "Select.h"
|
#include "Select.h"
|
||||||
#include "TCP.h"
|
#include "Socket.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#define _WIN32_WINNT 0x0A00 // Win10
|
#define _WIN32_WINNT 0x0A00 // Win10
|
||||||
|
@ -8,57 +8,59 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
inline void luatable_to_fdset(lua_State* L, int tbl_index, fd_set& fds)
|
||||||
|
{
|
||||||
|
lua_pushnil(L);
|
||||||
|
while (lua_next(L, tbl_index))
|
||||||
|
{
|
||||||
|
lua_pop(L, 1);
|
||||||
|
auto s = lua_testblock<SocketData>(L, -1, "LuaEngineTCPSocket") ? lua_checkblock<SocketData>(L, -1, "LuaEngineTCPSocket") : lua_checkblock<SocketData>(L, -1, "LuaEngineUDPSocket");
|
||||||
|
if (s->fd > 0)
|
||||||
|
{
|
||||||
|
FD_SET(s->fd, &fds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fdset_to_luatable(lua_State* L, int tbl_index, fd_set& fds)
|
||||||
|
{
|
||||||
|
lua_newtable(L); // ... RetT
|
||||||
|
lua_pushnil(L); // ... RetT nil
|
||||||
|
while (lua_next(L, tbl_index))
|
||||||
|
{
|
||||||
|
lua_pop(L, 1); // ... RetT Socket
|
||||||
|
auto s = lua_testblock<SocketData>(L, -1, "LuaEngineTCPSocket") ? lua_checkblock<SocketData>(L, -1, "LuaEngineTCPSocket") : lua_checkblock<SocketData>(L, -1, "LuaEngineUDPSocket");
|
||||||
|
if (s->fd > 0 && FD_ISSET(s->fd, &fds))
|
||||||
|
{
|
||||||
|
lua_pushvalue(L, -1); // ... RetT Socket Socket
|
||||||
|
lua_pushboolean(L, true); // ... RetT Socket Socket true
|
||||||
|
lua_settable(L, -4); // ... RetT Socket
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int select_call(lua_State* L)
|
int select_call(lua_State* L)
|
||||||
{
|
{
|
||||||
luaL_checktype(L, 1, LUA_TTABLE);
|
luaL_checktype(L, 1, LUA_TTABLE);
|
||||||
luaL_checktype(L, 2, LUA_TTABLE);
|
luaL_checktype(L, 2, LUA_TTABLE);
|
||||||
luaL_checktype(L, 3, LUA_TTABLE);
|
luaL_checktype(L, 3, LUA_TTABLE);
|
||||||
int us = luaL_checkinteger(L, 4);
|
int us = luaL_checkinteger(L, 4);
|
||||||
FD_SET readset, writeset, errorset;
|
fd_set readset, writeset, errorset;
|
||||||
|
|
||||||
FD_ZERO(&readset);
|
FD_ZERO(&readset);
|
||||||
lua_pushnil(L);
|
luatable_to_fdset(L, 1, readset);
|
||||||
while (lua_next(L, 1))
|
|
||||||
{
|
|
||||||
lua_pop(L, 1);
|
|
||||||
auto s = lua_checkblock<TCPSocket>(L, -1, "LuaEngineTCPSocket");
|
|
||||||
if (s->fd > 0)
|
|
||||||
{
|
|
||||||
FD_SET(s->fd, &readset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&writeset);
|
FD_ZERO(&writeset);
|
||||||
lua_pushnil(L);
|
luatable_to_fdset(L, 2, writeset);
|
||||||
while (lua_next(L, 2))
|
|
||||||
{
|
|
||||||
lua_pop(L, 1);
|
|
||||||
auto s = lua_checkblock<TCPSocket>(L, -1, "LuaEngineTCPSocket");
|
|
||||||
if (s->fd > 0)
|
|
||||||
{
|
|
||||||
FD_SET(s->fd, &writeset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FD_ZERO(&errorset);
|
FD_ZERO(&errorset);
|
||||||
lua_pushnil(L);
|
luatable_to_fdset(L, 3, errorset);
|
||||||
while (lua_next(L, 3))
|
|
||||||
{
|
|
||||||
lua_pop(L, 1);
|
|
||||||
auto s = lua_checkblock<TCPSocket>(L, -1, "LuaEngineTCPSocket");
|
|
||||||
if (s->fd > 0)
|
|
||||||
{
|
|
||||||
FD_SET(s->fd, &errorset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
timeval tm;
|
timeval tm;
|
||||||
tm.tv_sec = us / 1000000;
|
tm.tv_sec = us / 1000000;
|
||||||
tm.tv_usec = us % 1000000;
|
tm.tv_usec = us % 1000000;
|
||||||
|
|
||||||
printf("[DEBUG] select() start\n");
|
|
||||||
int ret = select(1024, &readset, &writeset, &errorset, &tm);
|
int ret = select(1024, &readset, &writeset, &errorset, &tm);
|
||||||
printf("[DEBUG] select() done. ret=%d\n", ret);
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
|
@ -72,47 +74,9 @@ int select_call(lua_State* L)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lua_newtable(L); // ... RetT
|
fdset_to_luatable(L, 1, readset); // +1
|
||||||
lua_pushnil(L); // ... RetT nil
|
fdset_to_luatable(L, 2, writeset); // +1
|
||||||
while (lua_next(L, 1))
|
fdset_to_luatable(L, 3, errorset); // +1
|
||||||
{
|
|
||||||
lua_pop(L, 1); // ... RetT Socket
|
|
||||||
auto s = lua_checkblock<TCPSocket>(L, -1, "LuaEngineTCPSocket");
|
|
||||||
if (s->fd > 0 && FD_ISSET(s->fd, &readset))
|
|
||||||
{
|
|
||||||
lua_pushvalue(L, -1); // ... RetT Socket Socket
|
|
||||||
lua_pushboolean(L, true); // ... RetT Socket Socket true
|
|
||||||
lua_settable(L, -4); // ... RetT Socket
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_newtable(L); // ... RetT
|
|
||||||
lua_pushnil(L); // ... RetT nil
|
|
||||||
while (lua_next(L, 2))
|
|
||||||
{
|
|
||||||
lua_pop(L, 1); // ... RetT Socket
|
|
||||||
auto s = lua_checkblock<TCPSocket>(L, -1, "LuaEngineTCPSocket");
|
|
||||||
if (s->fd > 0 && FD_ISSET(s->fd, &writeset))
|
|
||||||
{
|
|
||||||
lua_pushvalue(L, -1); // ... RetT Socket Socket
|
|
||||||
lua_pushboolean(L, true); // ... RetT Socket Socket true
|
|
||||||
lua_settable(L, -4); // ... RetT Socket
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_newtable(L); // ... RetT
|
|
||||||
lua_pushnil(L); // ... RetT nil
|
|
||||||
while (lua_next(L, 3))
|
|
||||||
{
|
|
||||||
lua_pop(L, 1); // ... RetT Socket
|
|
||||||
auto s = lua_checkblock<TCPSocket>(L, -1, "LuaEngineTCPSocket");
|
|
||||||
if (s->fd > 0 && FD_ISSET(s->fd, &errorset))
|
|
||||||
{
|
|
||||||
lua_pushvalue(L, -1); // ... RetT Socket Socket
|
|
||||||
lua_pushboolean(L, true); // ... RetT Socket Socket true
|
|
||||||
lua_settable(L, -4); // ... RetT Socket
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 3; // ... RetT RetT RetT
|
return 3; // ... RetT RetT RetT
|
||||||
}
|
}
|
||||||
|
|
11
Socket.h
Normal file
11
Socket.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#include "include.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class SocketData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int fd;
|
||||||
|
bool nonblocking;
|
||||||
|
std::vector<char> data;
|
||||||
|
int buffsz;
|
||||||
|
};
|
14
TCP.h
14
TCP.h
|
@ -1,5 +1,4 @@
|
||||||
#include "include.h"
|
#include "Socket.h"
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
class TCPSocket
|
class TCPSocket
|
||||||
|
@ -8,7 +7,7 @@ class TCPSocket
|
||||||
setblocking(nonblocking: boolean)
|
setblocking(nonblocking: boolean)
|
||||||
listen([ip: string], port: int, [backlog: int]) Address default to 0.0.0.0, backlog default to 10.
|
listen([ip: string], port: int, [backlog: int]) Address default to 0.0.0.0, backlog default to 10.
|
||||||
|
|
||||||
# Blocking mode: All non-expected error will be raised as exception.
|
# Blocking mode: All unexpected error will be raised as exception.
|
||||||
connect(ip: string, port: int)
|
connect(ip: string, port: int)
|
||||||
accept(): TCPSocket PeerIP PeerPort
|
accept(): TCPSocket PeerIP PeerPort
|
||||||
send(data: string) All data will be sent before return.
|
send(data: string) All data will be sent before return.
|
||||||
|
@ -20,12 +19,3 @@ class TCPSocket
|
||||||
send(data: string)
|
send(data: string)
|
||||||
recv([maxsize: int]): string
|
recv([maxsize: int]): string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class TCPSocket
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
int fd;
|
|
||||||
bool nonblocking;
|
|
||||||
std::vector<char> data;
|
|
||||||
int buffsz;
|
|
||||||
};
|
|
||||||
|
|
44
TCPWin.cpp
44
TCPWin.cpp
|
@ -9,19 +9,19 @@ using namespace std;
|
||||||
|
|
||||||
int tcp_socket_dtor(lua_State* L)
|
int tcp_socket_dtor(lua_State* L)
|
||||||
{
|
{
|
||||||
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
|
||||||
if (s->fd > 0)
|
if (s->fd > 0)
|
||||||
{
|
{
|
||||||
closesocket(s->fd);
|
closesocket(s->fd);
|
||||||
s->fd = -1;
|
s->fd = -1;
|
||||||
}
|
}
|
||||||
s->~TCPSocket();
|
s->~SocketData();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tcp_socket_close(lua_State* L)
|
int tcp_socket_close(lua_State* L)
|
||||||
{
|
{
|
||||||
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
|
||||||
if (s->fd > 0)
|
if (s->fd > 0)
|
||||||
{
|
{
|
||||||
closesocket(s->fd);
|
closesocket(s->fd);
|
||||||
|
@ -32,7 +32,7 @@ int tcp_socket_close(lua_State* L)
|
||||||
|
|
||||||
int tcp_socket_send(lua_State* L)
|
int tcp_socket_send(lua_State* L)
|
||||||
{
|
{
|
||||||
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
|
||||||
size_t sz;
|
size_t sz;
|
||||||
const char* str = luaL_checklstring(L, 2, &sz);
|
const char* str = luaL_checklstring(L, 2, &sz);
|
||||||
size_t done = 0;
|
size_t done = 0;
|
||||||
|
@ -59,7 +59,7 @@ int tcp_socket_send(lua_State* L)
|
||||||
|
|
||||||
int tcp_socket_recv(lua_State* L)
|
int tcp_socket_recv(lua_State* L)
|
||||||
{
|
{
|
||||||
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
|
||||||
int ret = recv(s->fd, s->data.data(), s->buffsz, 0);
|
int ret = recv(s->fd, s->data.data(), s->buffsz, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
|
@ -79,14 +79,19 @@ int tcp_socket_recv(lua_State* L)
|
||||||
|
|
||||||
int tcp_socket_connect(lua_State* L)
|
int tcp_socket_connect(lua_State* L)
|
||||||
{
|
{
|
||||||
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
|
||||||
const char* ip = luaL_checkstring(L, 2);
|
const char* ip = luaL_checkstring(L, 2);
|
||||||
int port = luaL_checkinteger(L, 3);
|
int port = luaL_checkinteger(L, 3);
|
||||||
|
|
||||||
sockaddr_in addr;
|
sockaddr_in addr;
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_addr.s_addr = inet_addr(ip);
|
if (inet_pton(AF_INET, ip, &addr.sin_addr) < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "inet_pton");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
addr.sin_port = htons(port);
|
addr.sin_port = htons(port);
|
||||||
|
|
||||||
int ret = connect(s->fd, (const sockaddr*)&addr, sizeof(addr));
|
int ret = connect(s->fd, (const sockaddr*)&addr, sizeof(addr));
|
||||||
|
@ -107,7 +112,7 @@ int tcp_socket_connect(lua_State* L)
|
||||||
|
|
||||||
int tcp_socket_listen(lua_State* L)
|
int tcp_socket_listen(lua_State* L)
|
||||||
{
|
{
|
||||||
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
|
||||||
const char* ip = NULL;
|
const char* ip = NULL;
|
||||||
int port;
|
int port;
|
||||||
int backlog = 10;
|
int backlog = 10;
|
||||||
|
@ -134,7 +139,12 @@ int tcp_socket_listen(lua_State* L)
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
if (ip && strcmp(ip, "0.0.0.0"))
|
if (ip && strcmp(ip, "0.0.0.0"))
|
||||||
{
|
{
|
||||||
addr.sin_addr.s_addr = inet_addr(ip);
|
if (inet_pton(AF_INET, ip, &addr.sin_addr) < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "inet_pton");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -163,7 +173,7 @@ int tcp_socket_listen(lua_State* L)
|
||||||
|
|
||||||
int tcp_socket_setblocking(lua_State* L)
|
int tcp_socket_setblocking(lua_State* L)
|
||||||
{
|
{
|
||||||
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
|
||||||
luaL_checkany(L, 2);
|
luaL_checkany(L, 2);
|
||||||
bool blocking = lua_toboolean(L, 2);
|
bool blocking = lua_toboolean(L, 2);
|
||||||
if (blocking != s->nonblocking)
|
if (blocking != s->nonblocking)
|
||||||
|
@ -199,7 +209,7 @@ int tcp_socket_accept(lua_State* L);
|
||||||
|
|
||||||
void put_tcp_socket(lua_State* L, int fd, bool nonblocking)
|
void put_tcp_socket(lua_State* L, int fd, bool nonblocking)
|
||||||
{
|
{
|
||||||
auto s = new (lua_newblock<TCPSocket>(L)) TCPSocket;
|
auto s = new (lua_newblock<SocketData>(L)) SocketData;
|
||||||
if (luaL_newmetatable(L, "LuaEngineTCPSocket"))
|
if (luaL_newmetatable(L, "LuaEngineTCPSocket"))
|
||||||
{
|
{
|
||||||
lua_setfield_function(L, "__gc", tcp_socket_dtor);
|
lua_setfield_function(L, "__gc", tcp_socket_dtor);
|
||||||
|
@ -222,7 +232,7 @@ void put_tcp_socket(lua_State* L, int fd, bool nonblocking)
|
||||||
|
|
||||||
int tcp_socket_accept(lua_State* L)
|
int tcp_socket_accept(lua_State* L)
|
||||||
{
|
{
|
||||||
auto s = lua_checkblock<TCPSocket>(L, 1, "LuaEngineTCPSocket");
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineTCPSocket");
|
||||||
sockaddr_in addr;
|
sockaddr_in addr;
|
||||||
int addrsz = sizeof(addr);
|
int addrsz = sizeof(addr);
|
||||||
int ret = accept(s->fd, (sockaddr*)&addr, &addrsz);
|
int ret = accept(s->fd, (sockaddr*)&addr, &addrsz);
|
||||||
|
@ -237,7 +247,15 @@ int tcp_socket_accept(lua_State* L)
|
||||||
return lua_error(L);
|
return lua_error(L);
|
||||||
}
|
}
|
||||||
put_tcp_socket(L, ret, false);
|
put_tcp_socket(L, ret, false);
|
||||||
lua_pushstring(L, inet_ntoa(addr.sin_addr));
|
|
||||||
|
char buffer[1024] = { 0 };
|
||||||
|
if (inet_ntop(AF_INET, &addr.sin_addr, buffer, 1024) < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "inet_ntop");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
lua_pushstring(L, buffer);
|
||||||
lua_pushinteger(L, ntohs(addr.sin_port));
|
lua_pushinteger(L, ntohs(addr.sin_port));
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
16
UDP.h
Normal file
16
UDP.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
#include "Socket.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
class UDPSocket
|
||||||
|
constructor()
|
||||||
|
close()
|
||||||
|
setblocking(nonblocking: boolean)
|
||||||
|
setbroadcast(isbroadcast: boolean) Broadcast default to false.
|
||||||
|
listen([ip: string], port: int) Address default to 0.0.0.0.
|
||||||
|
|
||||||
|
connect(ip: string, port: int)
|
||||||
|
send(data: string)
|
||||||
|
recv([maxsize: int]): string. Default to 4KB.
|
||||||
|
sendto([ip: string], port: int, data: string) If ip is empty, default to 255.255.255.255 (broadcast)
|
||||||
|
recvfrom(): data: string, ip: string, port: int
|
||||||
|
*/
|
348
UDPWin.cpp
Normal file
348
UDPWin.cpp
Normal file
|
@ -0,0 +1,348 @@
|
||||||
|
#include "UDP.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define _WIN32_WINNT 0x0A00 // Win10
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
int udp_socket_dtor(lua_State* L)
|
||||||
|
{
|
||||||
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
|
||||||
|
if (s->fd > 0)
|
||||||
|
{
|
||||||
|
closesocket(s->fd);
|
||||||
|
s->fd = -1;
|
||||||
|
}
|
||||||
|
s->~SocketData();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int udp_socket_close(lua_State* L)
|
||||||
|
{
|
||||||
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
|
||||||
|
if (s->fd > 0)
|
||||||
|
{
|
||||||
|
closesocket(s->fd);
|
||||||
|
s->fd = -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int udp_socket_send(lua_State* L)
|
||||||
|
{
|
||||||
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
|
||||||
|
size_t sz;
|
||||||
|
const char* str = luaL_checklstring(L, 2, &sz);
|
||||||
|
int ret = send(s->fd, str, sz, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
if (s->nonblocking && errcode == WSAEWOULDBLOCK)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, true);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
put_winerror(L, errcode, "send");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int udp_socket_recv(lua_State* L)
|
||||||
|
{
|
||||||
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
|
||||||
|
int ret = recv(s->fd, s->data.data(), s->buffsz, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
if (s->nonblocking && errcode == WSAEWOULDBLOCK)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
put_winerror(L, errcode, "recv");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
lua_pushlstring(L, s->data.data(), ret);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int udp_socket_sendto(lua_State* L)
|
||||||
|
{
|
||||||
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
|
||||||
|
const char* ip = NULL;
|
||||||
|
int port;
|
||||||
|
size_t sz;
|
||||||
|
const char* str = NULL;
|
||||||
|
if (lua_type(L, 2) == LUA_TSTRING)
|
||||||
|
{
|
||||||
|
ip = luaL_checkstring(L, 2);
|
||||||
|
port = luaL_checkinteger(L, 3);
|
||||||
|
str = luaL_checklstring(L, 4, &sz);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port = luaL_checkinteger(L, 2);
|
||||||
|
str = luaL_checklstring(L, 3, &sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_in addr;
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(port);
|
||||||
|
if (ip && strcmp(ip, "255.255.255.255"))
|
||||||
|
{
|
||||||
|
if (inet_pton(AF_INET, ip, &addr.sin_addr) < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "inet_pton");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addr.sin_addr.s_addr = INADDR_BROADCAST;
|
||||||
|
}
|
||||||
|
int ret = sendto(s->fd, str, sz, 0, (const sockaddr*)&addr, sizeof(addr));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
if (s->nonblocking && errcode == WSAEWOULDBLOCK)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, true);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
put_winerror(L, errcode, "sendto");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int udp_socket_recvfrom(lua_State* L)
|
||||||
|
{
|
||||||
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
|
||||||
|
sockaddr_in addr;
|
||||||
|
int addrlen = sizeof(addr);
|
||||||
|
int ret = recvfrom(s->fd, s->data.data(), s->buffsz, 0, (sockaddr*)&addr, &addrlen);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
if (s->nonblocking && errcode == WSAEWOULDBLOCK)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
put_winerror(L, errcode, "recvfrom");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
char buffer[1024] = { 0 };
|
||||||
|
if (inet_ntop(AF_INET, &addr.sin_addr, buffer, 1024) < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "inet_ntop");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushlstring(L, s->data.data(), ret);
|
||||||
|
lua_pushstring(L, buffer);
|
||||||
|
lua_pushinteger(L, ntohs(addr.sin_port));
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
int udp_socket_connect(lua_State* L)
|
||||||
|
{
|
||||||
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
|
||||||
|
const char* ip = luaL_checkstring(L, 2);
|
||||||
|
int port = luaL_checkinteger(L, 3);
|
||||||
|
|
||||||
|
sockaddr_in addr;
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
if (inet_pton(AF_INET, ip, &addr.sin_addr) < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "inet_pton");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
addr.sin_port = htons(port);
|
||||||
|
|
||||||
|
int ret = connect(s->fd, (const sockaddr*)&addr, sizeof(addr));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
if (s->nonblocking && errcode == WSAEWOULDBLOCK)
|
||||||
|
{
|
||||||
|
lua_pushboolean(L, true);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
put_winerror(L, errcode, "connect");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int udp_socket_setblocking(lua_State* L)
|
||||||
|
{
|
||||||
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
|
||||||
|
luaL_checkany(L, 2);
|
||||||
|
bool blocking = lua_toboolean(L, 2);
|
||||||
|
if (blocking != s->nonblocking)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (blocking) // set to blocking
|
||||||
|
{
|
||||||
|
u_long arg = 0;
|
||||||
|
int ret = ioctlsocket(s->fd, FIONBIO, &arg);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "ioctlsocket");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // set to nonblocking
|
||||||
|
{
|
||||||
|
u_long arg = 1;
|
||||||
|
int ret = ioctlsocket(s->fd, FIONBIO, &arg);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "ioctlsocket");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int udp_socket_setbroadcast(lua_State* L)
|
||||||
|
{
|
||||||
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
|
||||||
|
socklen_t opt = 0;
|
||||||
|
if (!lua_isnone(L, 2) && lua_toboolean(L, 2))
|
||||||
|
{
|
||||||
|
opt = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = setsockopt(s->fd, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, sizeof(opt));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "setsockopt");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int udp_socket_listen(lua_State* L)
|
||||||
|
{
|
||||||
|
auto s = lua_checkblock<SocketData>(L, 1, "LuaEngineUDPSocket");
|
||||||
|
const char* ip = NULL;
|
||||||
|
int port;
|
||||||
|
if (lua_type(L, 2) == LUA_TSTRING)
|
||||||
|
{
|
||||||
|
ip = luaL_checkstring(L, 2);
|
||||||
|
port = luaL_checkinteger(L, 3);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
port = luaL_checkinteger(L, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
sockaddr_in addr;
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
if (ip && strcmp(ip, "0.0.0.0"))
|
||||||
|
{
|
||||||
|
if (inet_pton(AF_INET, ip, &addr.sin_addr) < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "inet_pton");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addr.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
}
|
||||||
|
addr.sin_port = htons(port);
|
||||||
|
|
||||||
|
int ret = bind(s->fd, (const sockaddr*)&addr, sizeof(addr));
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "bind");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void put_udp_socket(lua_State* L, int fd, bool nonblocking)
|
||||||
|
{
|
||||||
|
auto s = new (lua_newblock<SocketData>(L)) SocketData;
|
||||||
|
if (luaL_newmetatable(L, "LuaEngineUDPSocket"))
|
||||||
|
{
|
||||||
|
lua_setfield_function(L, "__gc", udp_socket_dtor);
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_setfield_function(L, "close", udp_socket_close);
|
||||||
|
lua_setfield_function(L, "send", udp_socket_send);
|
||||||
|
lua_setfield_function(L, "recv", udp_socket_recv);
|
||||||
|
lua_setfield_function(L, "sendto", udp_socket_sendto);
|
||||||
|
lua_setfield_function(L, "recvfrom", udp_socket_recvfrom);
|
||||||
|
lua_setfield_function(L, "listen", udp_socket_listen);
|
||||||
|
lua_setfield_function(L, "connect", udp_socket_connect);
|
||||||
|
lua_setfield_function(L, "setblocking", udp_socket_setblocking);
|
||||||
|
lua_setfield_function(L, "setbroadcast", udp_socket_setbroadcast);
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
|
}
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
s->fd = fd;
|
||||||
|
s->nonblocking = nonblocking;
|
||||||
|
s->buffsz = 4096;
|
||||||
|
s->data.resize(s->buffsz);
|
||||||
|
}
|
||||||
|
|
||||||
|
int udp_socket_new(lua_State* L)
|
||||||
|
{
|
||||||
|
bool nonblocking = false;
|
||||||
|
if (!lua_isnone(L, 1))
|
||||||
|
{
|
||||||
|
if (lua_toboolean(L, 1))
|
||||||
|
{
|
||||||
|
nonblocking = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
put_winerror(L, errcode, "socket");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
if (nonblocking)
|
||||||
|
{
|
||||||
|
u_long arg = 1;
|
||||||
|
int ret = ioctlsocket(fd, FIONBIO, &arg);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
int errcode = WSAGetLastError();
|
||||||
|
closesocket(fd);
|
||||||
|
put_winerror(L, errcode, "ioctlsocket");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
put_udp_socket(L, fd, nonblocking);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitUDPSocket(lua_State* L)
|
||||||
|
{
|
||||||
|
lua_getglobal(L, "package");
|
||||||
|
lua_getfield(L, -1, "loaded");
|
||||||
|
lua_pushcfunction(L, udp_socket_new);
|
||||||
|
lua_setfield(L, -2, "UDPSocket");
|
||||||
|
lua_pop(L, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // end of _WIN32
|
|
@ -33,6 +33,12 @@ T* lua_checkblock(lua_State* L, int idx, const char* name)
|
||||||
return (T*)luaL_checkudata(L, idx, name);
|
return (T*)luaL_checkudata(L, idx, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* lua_testblock(lua_State* L, int idx, const char* name)
|
||||||
|
{
|
||||||
|
return (T*)luaL_testudata(L, idx, name);
|
||||||
|
}
|
||||||
|
|
||||||
// Shared Functions
|
// Shared Functions
|
||||||
void put_surface(lua_State* L, SDL_Surface* surf);
|
void put_surface(lua_State* L, SDL_Surface* surf);
|
||||||
void put_texture(lua_State* L, SDL_Texture* text);
|
void put_texture(lua_State* L, SDL_Texture* text);
|
||||||
|
@ -45,6 +51,8 @@ void InitMusic(lua_State* L);
|
||||||
void InitEvent(lua_State* L);
|
void InitEvent(lua_State* L);
|
||||||
void InitCommon(lua_State* L);
|
void InitCommon(lua_State* L);
|
||||||
void InitTCPSocket(lua_State* L);
|
void InitTCPSocket(lua_State* L);
|
||||||
|
void InitUDPSocket(lua_State* L);
|
||||||
|
void InitNetwork(lua_State* L);
|
||||||
void InitThread(lua_State* L);
|
void InitThread(lua_State* L);
|
||||||
void InitSocketSelector(lua_State* L);
|
void InitSocketSelector(lua_State* L);
|
||||||
|
|
||||||
|
|
4
main.cpp
4
main.cpp
|
@ -1,6 +1,7 @@
|
||||||
#include "LuaEngine.h"
|
#include "LuaEngine.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <direct.h>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
string LoadFile(const string& filename)
|
string LoadFile(const string& filename)
|
||||||
|
@ -28,7 +29,8 @@ int main()
|
||||||
lua_State* L = luaL_newstate();
|
lua_State* L = luaL_newstate();
|
||||||
luaL_openlibs(L);
|
luaL_openlibs(L);
|
||||||
InitLuaEngine(L);
|
InitLuaEngine(L);
|
||||||
string code = LoadFile("game/app.lua");
|
_chdir("game");
|
||||||
|
string code = LoadFile("test.lua");
|
||||||
if (luaL_loadstring(L, code.c_str()))
|
if (luaL_loadstring(L, code.c_str()))
|
||||||
{
|
{
|
||||||
cout << lua_tostring(L, -1) << endl;
|
cout << lua_tostring(L, -1) << endl;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user