mirror of
https://github.com/ctruLua/ctruLua.git
synced 2025-10-27 08:29:31 +00:00
Added SSL support to sockets, Added console/stdout support, Removed apt.init/apt.shutdown, Added some SSL options to httpc
The console can __not__ be used with gfx.start() on a screen. You don't have to gfx.render() while print()ing, but you should do it when you are in the main loop. The SSL sockets don't work with Citra.
This commit is contained in:
parent
e87651a404
commit
e7ff54d58c
9 changed files with 333 additions and 75 deletions
32
source/apt.c
32
source/apt.c
|
|
@ -13,30 +13,6 @@ Used to manage the applets and application status.
|
|||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
/***
|
||||
Initialize the APT module. Useless.
|
||||
@function init
|
||||
*/
|
||||
static int apt_init(lua_State *L) {
|
||||
Result ret = aptInit();
|
||||
if (ret!=0) {
|
||||
lua_pushboolean(L, false);
|
||||
lua_pushinteger(L, ret);
|
||||
return 2;
|
||||
}
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
Shutdown the APT module. Useless, don't use it.
|
||||
@function shutdown
|
||||
*/
|
||||
static int apt_shutdown(lua_State *L) {
|
||||
aptExit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
Open an APT session. Should only work if you don't use the homebrew menu.
|
||||
@function openSession
|
||||
|
|
@ -132,8 +108,6 @@ static int apt_getMenuAppID(lua_State *L) {
|
|||
}
|
||||
|
||||
static const struct luaL_Reg apt_lib[] = {
|
||||
{"init", apt_init },
|
||||
{"shutdown", apt_shutdown },
|
||||
{"openSession", apt_openSession },
|
||||
{"closeSession", apt_closeSession },
|
||||
{"setStatus", apt_setStatus },
|
||||
|
|
@ -327,6 +301,8 @@ struct { char *name; int value; } apt_constants[] = {
|
|||
};
|
||||
|
||||
int luaopen_apt_lib(lua_State *L) {
|
||||
aptInit();
|
||||
|
||||
luaL_newlib(L, apt_lib);
|
||||
|
||||
for (int i = 0; apt_constants[i].name; i++) {
|
||||
|
|
@ -340,3 +316,7 @@ int luaopen_apt_lib(lua_State *L) {
|
|||
void load_apt_lib(lua_State *L) {
|
||||
luaL_requiref(L, "ctr.apt", luaopen_apt_lib, false);
|
||||
}
|
||||
|
||||
void unload_apt_lib(lua_State *L) {
|
||||
aptExit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,13 +14,17 @@ Used to get some user config.
|
|||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
bool initStateCFGU = false;
|
||||
|
||||
/***
|
||||
Initialize the CFGU module.
|
||||
@function init
|
||||
*/
|
||||
static int cfgu_init(lua_State *L) {
|
||||
cfguInit();
|
||||
|
||||
if (!initStateCFGU) {
|
||||
cfguInit();
|
||||
initStateCFGU = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -29,8 +33,10 @@ Disable the CFGU module.
|
|||
@function shutdown
|
||||
*/
|
||||
static int cfgu_shutdown(lua_State *L) {
|
||||
cfguExit();
|
||||
|
||||
if (initStateCFGU) {
|
||||
cfguExit();
|
||||
initStateCFGU = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -309,3 +315,10 @@ int luaopen_cfgu_lib(lua_State *L) {
|
|||
void load_cfgu_lib(lua_State *L) {
|
||||
luaL_requiref(L, "ctr.cfgu", luaopen_cfgu_lib, false);
|
||||
}
|
||||
|
||||
void unload_cfgu_lib(lua_State *L) {
|
||||
if (initStateCFGU) {
|
||||
initStateCFGU = false;
|
||||
cfguExit();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
source/ctr.c
12
source/ctr.c
|
|
@ -28,6 +28,7 @@ The `ctr.news` module.
|
|||
@see ctr.news
|
||||
*/
|
||||
void load_news_lib(lua_State *L);
|
||||
void unload_news_lib(lua_State *L);
|
||||
|
||||
/***
|
||||
The `ctr.ptm` module.
|
||||
|
|
@ -35,6 +36,7 @@ The `ctr.ptm` module.
|
|||
@see ctr.ptm
|
||||
*/
|
||||
void load_ptm_lib(lua_State *L);
|
||||
void unload_ptm_lib(lua_State *L);
|
||||
|
||||
/***
|
||||
The `ctr.hid` module.
|
||||
|
|
@ -80,6 +82,7 @@ The `ctr.cfgu` module.
|
|||
@see ctr.cfgu
|
||||
*/
|
||||
void load_cfgu_lib(lua_State *L);
|
||||
void unload_cfgu_lib(lua_State *L);
|
||||
|
||||
/***
|
||||
The `ctr.socket` module.
|
||||
|
|
@ -109,6 +112,7 @@ The `ctr.apt` module.
|
|||
@see ctr.apt
|
||||
*/
|
||||
void load_apt_lib(lua_State *L);
|
||||
void unload_apt_lib(lua_State *L);
|
||||
|
||||
/***
|
||||
The `ctr.mic` module.
|
||||
|
|
@ -168,18 +172,18 @@ static const struct luaL_Reg ctr_lib[] = {
|
|||
// Subtables
|
||||
struct { char *name; void (*load)(lua_State *L); void (*unload)(lua_State *L); } ctr_libs[] = {
|
||||
{ "gfx", load_gfx_lib, unload_gfx_lib },
|
||||
{ "news", load_news_lib, NULL },
|
||||
{ "ptm", load_ptm_lib, NULL },
|
||||
{ "news", load_news_lib, unload_news_lib },
|
||||
{ "ptm", load_ptm_lib, unload_ptm_lib },
|
||||
{ "hid", load_hid_lib, unload_hid_lib },
|
||||
{ "ir", load_ir_lib, NULL },
|
||||
{ "fs", load_fs_lib, unload_fs_lib },
|
||||
{ "httpc", load_httpc_lib, unload_httpc_lib },
|
||||
{ "qtm", load_qtm_lib, NULL },
|
||||
{ "cfgu", load_cfgu_lib, NULL },
|
||||
{ "cfgu", load_cfgu_lib, unload_cfgu_lib },
|
||||
{ "socket", load_socket_lib, NULL },
|
||||
{ "cam", load_cam_lib, NULL },
|
||||
{ "audio", load_audio_lib, unload_audio_lib },
|
||||
{ "apt", load_apt_lib, NULL },
|
||||
{ "apt", load_apt_lib, unload_apt_lib },
|
||||
{ "mic", load_mic_lib, NULL },
|
||||
{ "thread", load_thread_lib, NULL },
|
||||
{ NULL, NULL, NULL }
|
||||
|
|
|
|||
49
source/gfx.c
49
source/gfx.c
|
|
@ -12,6 +12,7 @@ The `gfx` module.
|
|||
|
||||
//#include <3ds/vram.h>
|
||||
//#include <3ds/services/gsp.h>
|
||||
#include <3ds/console.h>
|
||||
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
|
|
@ -524,6 +525,51 @@ static int gfx_target___index(lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
Initialize the console. You can print on it using print(), or any function that normally outputs to stdout.
|
||||
Warning: you can't use a screen for both a console and drawing, you have to disable the console first.
|
||||
@function console
|
||||
@tparam[opt=gfx.TOP] number screen screen to draw the console on.
|
||||
@tparam[opt=true] boolean debug enable stderr output on the console
|
||||
*/
|
||||
u8 consoleScreen = GFX_TOP;
|
||||
static int gfx_console(lua_State *L) {
|
||||
consoleScreen = luaL_optinteger(L, 1, GFX_TOP);
|
||||
bool err = false;
|
||||
if (lua_isboolean(L, 2)) {
|
||||
err = lua_toboolean(L, 2);
|
||||
}
|
||||
|
||||
consoleInit(consoleScreen, NULL);
|
||||
if (err)
|
||||
consoleDebugInit(debugDevice_CONSOLE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
Clear the console.
|
||||
@function clearConsole
|
||||
*/
|
||||
static int gfx_clearConsole(lua_State *L) {
|
||||
consoleClear();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***
|
||||
Disable the console.
|
||||
@function disableConsole
|
||||
*/
|
||||
static int gfx_disableConsole(lua_State *L) {
|
||||
gfxSetScreenFormat(consoleScreen, GSP_BGR8_OES);
|
||||
gfxSetDoubleBuffering(consoleScreen, true);
|
||||
gfxSwapBuffersGpu();
|
||||
gspWaitForVBlank();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Functions
|
||||
static const struct luaL_Reg gfx_lib[] = {
|
||||
{ "start", gfx_start },
|
||||
|
|
@ -546,6 +592,9 @@ static const struct luaL_Reg gfx_lib[] = {
|
|||
{ "getTextSize", gfx_getTextSize },
|
||||
{ "scissor", gfx_scissor },
|
||||
{ "target", gfx_target },
|
||||
{ "console", gfx_console },
|
||||
{ "clearConsole", gfx_clearConsole },
|
||||
{ "disableConsole", gfx_disableConsole },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ The `httpc` module.
|
|||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/services/httpc.h>
|
||||
#include <3ds/services/sslc.h>
|
||||
|
||||
#include <lapi.h>
|
||||
#include <lauxlib.h>
|
||||
|
|
@ -239,6 +240,25 @@ static int httpc_addTrustedRootCA(lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
Set SSL options for a context.
|
||||
@function :setSSLOptions
|
||||
@tparam boolean disableVerify disable server certificate verification if `true`
|
||||
@tparam[opt=false] boolean tlsv10 use TLS v1.0 if `true`
|
||||
*/
|
||||
static int httpc_setSSLOptions(lua_State *L) {
|
||||
httpcContext *context = lua_touserdata(L, 1);
|
||||
|
||||
bool disVer = lua_toboolean(L, 2);
|
||||
bool tsl10 = false;
|
||||
if (lua_isboolean(L, 3))
|
||||
tsl10 = lua_toboolean(L, 3);
|
||||
|
||||
httpcSetSSLOpt(context, (disVer?SSLCOPT_DisableVerify:0)|(tsl10?SSLCOPT_TLSv10:0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// object
|
||||
static const struct luaL_Reg httpc_methods[] = {
|
||||
{"open", httpc_open },
|
||||
|
|
@ -252,6 +272,7 @@ static const struct luaL_Reg httpc_methods[] = {
|
|||
{"addPostData", httpc_addPostData },
|
||||
{"getResponseHeader", httpc_getResponseHeader },
|
||||
{"addTrustedRootCA", httpc_addTrustedRootCA },
|
||||
{"setSSLOptions", httpc_setSSLOptions },
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,13 +13,17 @@ The `news` module.
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
bool initStateNews = false;
|
||||
|
||||
/***
|
||||
Initialize the news module.
|
||||
@function init
|
||||
*/
|
||||
static int news_init(lua_State *L) {
|
||||
newsInit();
|
||||
|
||||
if (!initStateNews) {
|
||||
newsInit();
|
||||
initStateNews = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -63,8 +67,10 @@ Disable the news module.
|
|||
@function shutdown
|
||||
*/
|
||||
static int news_shutdown(lua_State *L) {
|
||||
newsExit();
|
||||
|
||||
if (initStateNews) {
|
||||
newsExit();
|
||||
initStateNews = false;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -83,3 +89,10 @@ int luaopen_news_lib(lua_State *L) {
|
|||
void load_news_lib(lua_State *L) {
|
||||
luaL_requiref(L, "ctr.news", luaopen_news_lib, 0);
|
||||
}
|
||||
|
||||
void unload_news_lib(lua_State *L) {
|
||||
if (initStateNews) {
|
||||
newsExit();
|
||||
initStateNews = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
25
source/ptm.c
25
source/ptm.c
|
|
@ -10,13 +10,19 @@ The `ptm` module.
|
|||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
|
||||
bool initStatePTM = false;
|
||||
|
||||
/***
|
||||
Initialize the PTM module.
|
||||
@function init
|
||||
*/
|
||||
static int ptm_init(lua_State *L) {
|
||||
ptmuInit();
|
||||
ptmSysmInit();
|
||||
if (!initStatePTM) {
|
||||
ptmuInit();
|
||||
ptmSysmInit();
|
||||
|
||||
initStatePTM = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -26,8 +32,12 @@ Disable the PTM module.
|
|||
@function shutdown
|
||||
*/
|
||||
static int ptm_shutdown(lua_State *L) {
|
||||
ptmuExit();
|
||||
ptmSysmExit();
|
||||
if (initStatePTM) {
|
||||
ptmuExit();
|
||||
ptmSysmExit();
|
||||
|
||||
initStatePTM = false;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -146,3 +156,10 @@ int luaopen_ptm_lib(lua_State *L) {
|
|||
void load_ptm_lib(lua_State *L) {
|
||||
luaL_requiref(L, "ctr.ptm", luaopen_ptm_lib, 0);
|
||||
}
|
||||
|
||||
void unload_ptm_lib(lua_State *L) {
|
||||
if (initStatePTM) {
|
||||
ptmuExit();
|
||||
ptmSysmExit();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
197
source/socket.c
197
source/socket.c
|
|
@ -8,6 +8,7 @@ The UDP part is only without connection.
|
|||
#include <3ds.h>
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/services/soc.h>
|
||||
#include <3ds/services/sslc.h>
|
||||
|
||||
#include <lapi.h>
|
||||
#include <lauxlib.h>
|
||||
|
|
@ -15,7 +16,9 @@ The UDP part is only without connection.
|
|||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
|
|
@ -26,21 +29,58 @@ typedef struct {
|
|||
int socket;
|
||||
struct sockaddr_in addr;
|
||||
struct hostent *host; // only used for client sockets
|
||||
sslcContext sslContext;
|
||||
bool isSSL;
|
||||
} socket_userdata;
|
||||
|
||||
bool initStateSocket = false;
|
||||
|
||||
u32 rootCertChain = 0;
|
||||
|
||||
/***
|
||||
Initialize the socket module
|
||||
@function init
|
||||
@tparam[opt=0x100000] number buffer size (in bytes), must be a multiple of 0x1000
|
||||
*/
|
||||
static int socket_init(lua_State *L) {
|
||||
u32 size = luaL_optinteger(L, 1, 0x100000);
|
||||
Result ret = socInit((u32*)memalign(0x1000, size), size);
|
||||
if (!initStateSocket) {
|
||||
u32 size = luaL_optinteger(L, 1, 0x100000);
|
||||
if (size%0x1000 != 0) {
|
||||
lua_pushboolean(L, false);
|
||||
lua_pushstring(L, "Not a multiple of 0x1000");
|
||||
return 2;
|
||||
}
|
||||
|
||||
u32* mem = (u32*)memalign(0x1000, size);
|
||||
if (mem == NULL) {
|
||||
lua_pushboolean(L, false);
|
||||
lua_pushstring(L, "Failed to allocate memory");
|
||||
return 2;
|
||||
}
|
||||
|
||||
Result ret = socInit(mem, size);
|
||||
|
||||
if (ret) {
|
||||
lua_pushboolean(L, false);
|
||||
lua_pushinteger(L, ret);
|
||||
return 2;
|
||||
if (ret) {
|
||||
lua_pushboolean(L, false);
|
||||
lua_pushinteger(L, ret);
|
||||
return 2;
|
||||
}
|
||||
|
||||
ret = sslcInit(0);
|
||||
if (R_FAILED(ret)) {
|
||||
lua_pushboolean(L, false);
|
||||
lua_pushinteger(L, ret);
|
||||
return 2;
|
||||
}
|
||||
|
||||
sslcCreateRootCertChain(&rootCertChain);
|
||||
sslcRootCertChainAddDefaultCert(rootCertChain, SSLC_DefaultRootCert_CyberTrust, NULL);
|
||||
sslcRootCertChainAddDefaultCert(rootCertChain, SSLC_DefaultRootCert_AddTrust_External_CA, NULL);
|
||||
sslcRootCertChainAddDefaultCert(rootCertChain, SSLC_DefaultRootCert_COMODO, NULL);
|
||||
sslcRootCertChainAddDefaultCert(rootCertChain, SSLC_DefaultRootCert_USERTrust, NULL);
|
||||
sslcRootCertChainAddDefaultCert(rootCertChain, SSLC_DefaultRootCert_DigiCert_EV, NULL);
|
||||
|
||||
initStateSocket = true;
|
||||
}
|
||||
|
||||
lua_pushboolean(L, true);
|
||||
|
|
@ -52,8 +92,11 @@ Disable the socket module. Must be called before exiting ctrµLua.
|
|||
@function shutdown
|
||||
*/
|
||||
static int socket_shutdown(lua_State *L) {
|
||||
sslcDestroyRootCertChain(rootCertChain);
|
||||
sslcExit();
|
||||
socExit();
|
||||
|
||||
initStateSocket = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -76,6 +119,8 @@ static int socket_tcp(lua_State *L) {
|
|||
|
||||
userdata->addr.sin_family = AF_INET;
|
||||
|
||||
userdata->isSSL = false;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -92,15 +137,36 @@ static int socket_udp(lua_State *L) {
|
|||
userdata->socket = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (userdata->socket < 0) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "Failed to create a TCP socket");
|
||||
lua_pushstring(L, strerror(errno));
|
||||
return 2;
|
||||
}
|
||||
fcntl(userdata->socket, F_SETFL, O_NONBLOCK);
|
||||
|
||||
userdata->addr.sin_family = AF_INET;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
Add a trusted root CA to the certChain.
|
||||
@function addTrustedRootCA
|
||||
@tparam string cert DER cert
|
||||
*/
|
||||
static int socket_addTrustedRootCA(lua_State *L) {
|
||||
size_t size = 0;
|
||||
const char* cert = luaL_checklstring(L, 1, &size);
|
||||
|
||||
Result ret = sslcAddTrustedRootCA(rootCertChain, (u8*)cert, size, NULL);
|
||||
if (R_FAILED(ret)) {
|
||||
lua_pushnil(L);
|
||||
lua_pushinteger(L, ret);
|
||||
return 2;
|
||||
}
|
||||
|
||||
lua_pushboolean(L, true);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
All sockets
|
||||
@section sockets
|
||||
|
|
@ -130,6 +196,10 @@ Close an existing socket.
|
|||
static int socket_close(lua_State *L) {
|
||||
socket_userdata *userdata = luaL_checkudata(L, 1, "LSocket");
|
||||
|
||||
if (userdata->isSSL) {
|
||||
sslcDestroyContext(&userdata->sslContext);
|
||||
}
|
||||
|
||||
closesocket(userdata->socket);
|
||||
|
||||
return 0;
|
||||
|
|
@ -158,6 +228,7 @@ static int socket_accept(lua_State *L) {
|
|||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
fcntl(client->socket, F_SETFL, O_NONBLOCK);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -167,6 +238,7 @@ Connect a socket to a server. The TCP object becomes a TCPClient object.
|
|||
@function :connect
|
||||
@tparam string host address of the host
|
||||
@tparam number port port of the server
|
||||
@tparam[opt=false] boolean ssl use SSL if `true`
|
||||
@treturn[1] boolean true if success
|
||||
@treturn[2] boolean false if failed
|
||||
@treturn[2] string error string
|
||||
|
|
@ -175,11 +247,12 @@ static int socket_connect(lua_State *L) {
|
|||
socket_userdata *userdata = luaL_checkudata(L, 1, "LSocket");
|
||||
char *addr = (char*)luaL_checkstring(L, 2);
|
||||
int port = luaL_checkinteger(L, 3);
|
||||
bool ssl = lua_toboolean(L, 4);
|
||||
|
||||
userdata->host = gethostbyname(addr);
|
||||
if (userdata->host == NULL) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "No such host");
|
||||
lua_pushstring(L, strerror(errno));
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
|
@ -188,10 +261,23 @@ static int socket_connect(lua_State *L) {
|
|||
|
||||
if (connect(userdata->socket, (const struct sockaddr*)&userdata->addr, sizeof(userdata->addr)) < 0) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "Connection failed");
|
||||
lua_pushstring(L, strerror(errno));
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (ssl) { // SSL context setup
|
||||
sslcCreateContext(&userdata->sslContext, userdata->socket, SSLCOPT_Default, addr);
|
||||
sslcContextSetRootCertChain(&userdata->sslContext, rootCertChain);
|
||||
if (R_FAILED(sslcStartConnection(&userdata->sslContext, NULL, NULL))) {
|
||||
sslcDestroyContext(&userdata->sslContext);
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "SSL connection failed");
|
||||
return 2;
|
||||
}
|
||||
userdata->isSSL = true;
|
||||
}
|
||||
fcntl(userdata->socket, F_SETFL, O_NONBLOCK);
|
||||
|
||||
lua_pushboolean(L, 1);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -237,7 +323,11 @@ static int socket_receive(lua_State *L) {
|
|||
luaL_buffinit(L, &b);
|
||||
|
||||
char buff;
|
||||
while (recv(userdata->socket, &buff, 1, flags) > 0 && buff != '\n') luaL_addchar(&b, buff);
|
||||
if (!userdata->isSSL) {
|
||||
while (recv(userdata->socket, &buff, 1, flags) > 0 && buff != '\n') luaL_addchar(&b, buff);
|
||||
} else {
|
||||
while (!R_FAILED(sslcRead(&userdata->sslContext, &buff, 1, false)) && buff != '\n') luaL_addchar(&b, buff);
|
||||
}
|
||||
|
||||
luaL_pushresult(&b);
|
||||
return 1;
|
||||
|
|
@ -247,7 +337,11 @@ static int socket_receive(lua_State *L) {
|
|||
luaL_buffinit(L, &b);
|
||||
|
||||
char buff;
|
||||
while (buff != '\n' && recv(userdata->socket, &buff, 1, flags) > 0) luaL_addchar(&b, buff);
|
||||
if (!userdata->isSSL) {
|
||||
while (buff != '\n' && recv(userdata->socket, &buff, 1, flags) > 0) luaL_addchar(&b, buff);
|
||||
} else {
|
||||
while (buff != '\n' && !R_FAILED(sslcRead(&userdata->sslContext, &buff, 1, false))) luaL_addchar(&b, buff);
|
||||
}
|
||||
|
||||
luaL_pushresult(&b);
|
||||
return 1;
|
||||
|
|
@ -258,7 +352,17 @@ static int socket_receive(lua_State *L) {
|
|||
}
|
||||
|
||||
char *buff = malloc(count+1);
|
||||
int len = recv(userdata->socket, buff, count, flags);
|
||||
int len;
|
||||
if (!userdata->isSSL) {
|
||||
len = recv(userdata->socket, buff, count, flags);
|
||||
} else {
|
||||
len = sslcRead(&userdata->sslContext, buff, count, false);
|
||||
if (R_FAILED(len)) {
|
||||
lua_pushnil(L);
|
||||
lua_pushinteger(L, len);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
*(buff+len) = 0x0; // text end
|
||||
|
||||
lua_pushstring(L, buff);
|
||||
|
|
@ -276,12 +380,68 @@ static int socket_send(lua_State *L) {
|
|||
size_t size = 0;
|
||||
char *data = (char*)luaL_checklstring(L, 2, &size);
|
||||
|
||||
size_t sent = send(userdata->socket, data, size, 0);
|
||||
size_t sent;
|
||||
if (!userdata->isSSL) {
|
||||
sent = send(userdata->socket, data, size, 0);
|
||||
} else {
|
||||
sent = sslcWrite(&userdata->sslContext, data, size);
|
||||
if (R_FAILED(sent)) {
|
||||
lua_pushnil(L);
|
||||
lua_pushinteger(L, sent);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (sent < 0) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, strerror(errno));
|
||||
return 2;
|
||||
}
|
||||
|
||||
lua_pushinteger(L, sent);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/***
|
||||
Get some informations from a socket.
|
||||
@function :getpeername
|
||||
@treturn string IP
|
||||
@treturn number port
|
||||
*/
|
||||
static int socket_getpeername(lua_State *L) {
|
||||
socket_userdata *userdata = luaL_checkudata(L, 1, "LSocket");
|
||||
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addrSize = sizeof(addr);
|
||||
|
||||
getpeername(userdata->socket, (struct sockaddr*)&addr, &addrSize);
|
||||
|
||||
lua_pushstring(L, inet_ntoa(addr.sin_addr));
|
||||
lua_pushinteger(L, ntohs(addr.sin_port));
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
/***
|
||||
Get some local informations from a socket.
|
||||
@function :getsockname
|
||||
@treturn string IP
|
||||
@treturn number port
|
||||
*/
|
||||
static int socket_getsockname(lua_State *L) {
|
||||
socket_userdata *userdata = luaL_checkudata(L, 1, "LSocket");
|
||||
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addrSize = sizeof(addr);
|
||||
|
||||
getsockname(userdata->socket, (struct sockaddr*)&addr, &addrSize);
|
||||
|
||||
lua_pushstring(L, inet_ntoa(addr.sin_addr));
|
||||
lua_pushinteger(L, ntohs(addr.sin_port));
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
/***
|
||||
UDP sockets
|
||||
@section UDP
|
||||
|
|
@ -360,10 +520,11 @@ static int socket_sendto(lua_State *L) {
|
|||
|
||||
// module functions
|
||||
static const struct luaL_Reg socket_functions[] = {
|
||||
{"init", socket_init },
|
||||
{"shutdown", socket_shutdown},
|
||||
{"tcp", socket_tcp },
|
||||
{"udp", socket_udp },
|
||||
{"init", socket_init },
|
||||
{"shutdown", socket_shutdown },
|
||||
{"tcp", socket_tcp },
|
||||
{"udp", socket_udp },
|
||||
{"addTrustedRootCA", socket_addTrustedRootCA},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
@ -379,6 +540,8 @@ static const struct luaL_Reg socket_methods[] = {
|
|||
{"receivefrom", socket_receivefrom},
|
||||
{"send", socket_send },
|
||||
{"sendto", socket_sendto },
|
||||
{"getpeername", socket_getpeername},
|
||||
{"getsockname", socket_getsockname},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -280,23 +280,10 @@ static int texture_save(lua_State *L) {
|
|||
const char* path = luaL_checkstring(L, 2);
|
||||
u8 type = luaL_optinteger(L, 3, 0);
|
||||
|
||||
u32* buff = malloc(texture->texture->width * texture->texture->height * 4);
|
||||
if (buff == NULL) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "Failed to allocate buffer");
|
||||
return 2;
|
||||
}
|
||||
for (int y=0;y<texture->texture->height;y++) {
|
||||
for (int x=0;x<texture->texture->width;x++) {
|
||||
buff[x+(y*texture->texture->width)] = __builtin_bswap32(sf2d_get_pixel(texture->texture, x, y));
|
||||
}
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
if (type == 0) { // PNG
|
||||
FILE* file = fopen(path, "wb");
|
||||
if (file == NULL) {
|
||||
free(buff);
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "Can open file");
|
||||
return 2;
|
||||
|
|
@ -313,7 +300,7 @@ static int texture_save(lua_State *L) {
|
|||
|
||||
for(int y=0;y<texture->texture->height;y++) {
|
||||
for (int x=0;x<texture->texture->width;x++) {
|
||||
((u32*)row)[x] = buff[x+(y*texture->texture->width)];
|
||||
((u32*)row)[x] = __builtin_bswap32(sf2d_get_pixel(texture->texture, x, y));
|
||||
}
|
||||
png_write_row(png, row);
|
||||
}
|
||||
|
|
@ -328,14 +315,25 @@ static int texture_save(lua_State *L) {
|
|||
result = 1;
|
||||
|
||||
} else if (type == 2) { // BMP
|
||||
u32* buff = malloc(texture->texture->width * texture->texture->height * 4);
|
||||
if (buff == NULL) {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "Failed to allocate buffer");
|
||||
return 2;
|
||||
}
|
||||
for (int y=0;y<texture->texture->height;y++) {
|
||||
for (int x=0;x<texture->texture->width;x++) {
|
||||
buff[x+(y*texture->texture->width)] = __builtin_bswap32(sf2d_get_pixel(texture->texture, x, y));
|
||||
}
|
||||
}
|
||||
result = stbi_write_bmp(path, texture->texture->width, texture->texture->height, 4, buff);
|
||||
} else {
|
||||
free(buff);
|
||||
|
||||
} else {
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, "Not a valid type");
|
||||
return 2;
|
||||
}
|
||||
free(buff);
|
||||
|
||||
if (result == 0) {
|
||||
lua_pushnil(L);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue