Exemple #1
0
int main()
{
    lua_State *L = luaL_newstate();
    int err;

    struct sockaddr_in send_to;

    luaL_openlibs(L);

    dmx = socket(AF_INET, SOCK_DGRAM, 0);

    send_to.sin_port = htons(21812);
    send_to.sin_family = AF_INET;

    if( inet_aton("127.0.0.1", &send_to.sin_addr) == 0 ){
        printf("invalid address\n");
        return EXIT_FAILURE;
    }

    if( connect(dmx, (struct sockaddr*)&send_to, sizeof(struct sockaddr_in)) < 0){
        printf("couldn’t not connect socket\n");
        return EXIT_FAILURE;
    }

    /*new_global_table(L, LIGHT); */

    register_lt_functions(L);

    new_universe(L, "u");
    new_group(L, "u", "group1");

    err = luaL_loadfile(L, "lights.lua");
    dbg_lua(L, err, "lights.lua");
    err = lua_pcall(L, 0, LUA_MULTRET, 0);
    dbg_lua(L, err, "lights.lua");

    new_light(L, 30, "u", "parled", "test1");
    new_light(L, 5, "u", "parled", "test2");
    new_light(L, 1, "u", "lspot", "spot1");
    new_light(L, 2, "u", "lspot", "spot2");
    new_light(L, 3, "u", "lspot", "spot3");
    new_light(L, 4, "u", "lspot", "spot4");


    link_into_group(L, "u", "group1", "test1");
    link_into_group(L, "u", "group1", "test2");

    err = luaL_loadfile(L, "test.lua");
    dbg_lua(L, err, "test.lua");
    err = lua_pcall(L, 0, LUA_MULTRET, 0);
    dbg_lua(L, err, "test.lua");

    double p = 0;

    lua_getglobal(L, "main");
    if( !lua_isfunction(L, -1) ){
        printf("\"main\" function, is not defined\n");
        return -1;
    }
    lua_pushnumber(L, p);
    err = lua_pcall(L, 1, 0, 0);
    dbg_lua(L, err, "main");

    //update_lights(L, "u", cue);

    //printf("%g\r", p);
    //fflush(stdout);

    do{
        lua_getglobal(L, "rt_time");
        if( !lua_isfunction(L, -1) ){
            printf("\"rt_time\" function, is not defined\n");
            break;
        }

        err = lua_pcall(L, 0, 0, 0);
        dbg_lua(L, err, "rt_time");

    }while(1);

    lua_close(L);
    close(dmx);
    return 0;
}
Exemple #2
0
LuaCFunc luaToFunction(lua_State* plua_state, int index, LuaCFunc default_function)
{
    return lua_isfunction(plua_state, index) ? luaToFunction(plua_state, index) : default_function;
}
Exemple #3
0
bool CMLuaScript::Load()
{
	status = Failed;

	if (luaL_loadfile(L, T2Utf(filePath)))
	{
		Log(lua_tostring(L, -1));
		return false;
	}

	lua_createtable(L, 0, 2);
	lua_pushvalue(L, -1);
	lua_setfield(L, -2, "_G");
	lua_pushlightuserdata(L, this);
	lua_setfield(L, -2, "Script");
	lua_createtable(L, 0, 2);
	lua_getglobal(L, "_G");
	lua_setfield(L, -2, "__index");
	lua_setmetatable(L, -2);
	lua_setupvalue(L, -2, 1);

	if (luaM_pcall(L, 0, 1))
		return false;

	status = Loaded;

	if (lua_isnoneornil(L, -1))
		return true;

	luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
	lua_getfield(L, -1, moduleName);
	if (!lua_toboolean(L, -1))
	{
		lua_pop(L, 1);
		lua_pushvalue(L, -2);
		lua_setfield(L, -2, moduleName);
		lua_pop(L, 1);
	}
	else
		lua_remove(L, -2);

	if (!lua_istable(L, -1))
		return true;

	lua_getfield(L, -1, "Load");
	if (lua_isfunction(L, -1))
		luaM_pcall(L);
	else
		lua_pop(L, 1);

	lua_getfield(L, -1, "Unload");
	if (lua_isfunction(L, -1))
	{
		lua_pushvalue(L, -1);
		unloadRef = luaL_ref(L, LUA_REGISTRYINDEX);
	}
	lua_pop(L, 1);

	lua_pop(L, 1);

	return true;
}
Exemple #4
0
int LuaStack::executeFunction(int handler, int numArgs, int numResults, const std::function<void(lua_State*,int)>& func)
{
    if (pushFunctionByHandler(handler))                 /* L: ... arg1 arg2 ... func */
    {
        if (numArgs > 0)
        {
            lua_insert(_state, -(numArgs + 1));                        /* L: ... func arg1 arg2 ... */
        }
        
        int functionIndex = -(numArgs + 1);
        
        if (!lua_isfunction(_state, functionIndex))
        {
            CCLOG("value at stack [%d] is not function", functionIndex);
            lua_pop(_state, numArgs + 1); // remove function and arguments
            return 0;
        }
        
        int traceCallback = 0;
        lua_getglobal(_state, "__G__TRACKBACK__");                        /* L: ... func arg1 arg2 ... G */
        if (!lua_isfunction(_state, -1))
        {
            lua_pop(_state, 1);                                           /* L: ... func arg1 arg2 ... */
        }
        else
        {
            lua_insert(_state, functionIndex - 1);                         /* L: ... G func arg1 arg2 ... */
            traceCallback = functionIndex - 1;
        }
        
        int error = 0;
        ++_callFromLua;
        error = lua_pcall(_state, numArgs, numResults, traceCallback);     /* L: ... [G] ret1 ret2 ... retResults*/
        --_callFromLua;
        
        if (error)
        {
            if (traceCallback == 0)
            {
                CCLOG("[LUA ERROR] %s", lua_tostring(_state, - 1));        /* L: ... error */
                lua_pop(_state, 1);                                        // remove error message from stack
            }
            else                                                           /* L: ... G error */
            {
                lua_pop(_state, 2);                                        // remove __G__TRACKBACK__ and error message from stack
            }
            return 0;
        }
        
        // get return value,don't pass LUA_MULTRET to numResults,
        do {
            
            if (numResults <= 0 || nullptr == func)
                break;
            
            func(_state, numResults);
            
        } while (0);
        
        if (traceCallback)
        {
            lua_pop(_state, 1);                                          // remove __G__TRACKBACK__ from stack      /* L: ... */
        }
    }
    
    return 1;
}
Exemple #5
0
/***
 * @function rspamd_redis.make_request({params})
 * Make request to redis server, params is a table of key=value arguments in any order
 * @param {task} task worker task object
 * @param {ip} host server address
 * @param {function} callback callback to be called in form `function (task, err, data)`
 * @param {string} cmd command to be sent to redis
 * @param {table} args numeric array of strings used as redis arguments
 * @param {number} timeout timeout in seconds for request (1.0 by default)
 * @return {boolean} `true` if a request has been scheduled
 */
static int
lua_redis_make_request (lua_State *L)
{
	struct lua_redis_userdata *ud;
	struct rspamd_lua_ip *addr = NULL;
	struct rspamd_task *task = NULL;
	const gchar *cmd = NULL;
	gint top, cbref = -1;
	struct timeval tv;
	gboolean ret = FALSE;
	gdouble timeout = REDIS_DEFAULT_TIMEOUT;

	if (lua_istable (L, 1)) {
		/* Table version */
		lua_pushstring (L, "task");
		lua_gettable (L, -2);
		if (lua_type (L, -1) == LUA_TUSERDATA) {
			task = lua_check_task (L, -1);
		}
		lua_pop (L, 1);

		lua_pushstring (L, "callback");
		lua_gettable (L, -2);
		if (lua_type (L, -1) == LUA_TFUNCTION) {
			/* This also pops function from the stack */
			cbref = luaL_ref (L, LUA_REGISTRYINDEX);
		}
		else {
			msg_err ("bad callback argument for lua redis");
			lua_pop (L, 1);
		}

		lua_pushstring (L, "cmd");
		lua_gettable (L, -2);
		cmd = lua_tostring (L, -1);
		lua_pop (L, 1);

		lua_pushstring (L, "host");
		lua_gettable (L, -2);
		if (lua_type (L, -1) == LUA_TUSERDATA) {
			addr = lua_check_ip (L, -1);
		}
		lua_pop (L, 1);

		lua_pushstring (L, "timeout");
		lua_gettable (L, -2);
		timeout = lua_tonumber (L, -1);
		lua_pop (L, 1);

		if (task != NULL && addr != NULL && cbref != -1 && cmd != NULL) {
			ud =
					rspamd_mempool_alloc (task->task_pool,
							sizeof (struct lua_redis_userdata));
			ud->task = task;
			ud->L = L;
			ud->cbref = cbref;
			lua_pushstring (L, "args");
			lua_redis_parse_args (L, -1, cmd, ud);
			ret = TRUE;
		}
		else {
			if (cbref != -1) {
				luaL_unref (L, LUA_REGISTRYINDEX, cbref);
			}

			msg_err ("incorrect function invocation");
		}
	}
	else if ((task = lua_check_task (L, 1)) != NULL) {
		addr = lua_check_ip (L, 2);
		top = lua_gettop (L);
		/* Now get callback */
		if (lua_isfunction (L, 3) && addr != NULL && addr->addr && top >= 4) {
			/* Create userdata */
			ud =
				rspamd_mempool_alloc (task->task_pool,
					sizeof (struct lua_redis_userdata));
			ud->task = task;
			ud->L = L;

			/* Pop other arguments */
			lua_pushvalue (L, 3);
			/* Get a reference */
			ud->cbref = luaL_ref (L, LUA_REGISTRYINDEX);

			cmd = luaL_checkstring (L, 4);
			if (top > 4) {
				lua_redis_parse_args (L, 5, cmd, ud);
			}
			else {
				lua_redis_parse_args (L, 0, cmd, ud);
			}

			ret = TRUE;
		}
		else {
			msg_err ("incorrect function invocation");
		}
	}

	if (ret) {
		ud->terminated = 0;
		ud->ctx = redisAsyncConnect (rspamd_inet_address_to_string (addr->addr),
				rspamd_inet_address_get_port (addr->addr));
		redisAsyncSetConnectCallback (ud->ctx, lua_redis_connect_cb);

		if (ud->ctx == NULL || ud->ctx->err) {
			ud->terminated = 1;
			redisAsyncFree (ud->ctx);
			lua_redis_free_args (ud);
			luaL_unref (ud->L, LUA_REGISTRYINDEX, ud->cbref);
			lua_pushboolean (L, FALSE);

			return 1;
		}
		redisLibeventAttach (ud->ctx, ud->task->ev_base);
		ret = redisAsyncCommandArgv (ud->ctx,
					lua_redis_callback,
					ud,
					ud->nargs,
					(const gchar **)ud->args,
					NULL);
		if (ret == REDIS_OK) {
			rspamd_session_add_event (ud->task->s,
					lua_redis_fin,
					ud,
					g_quark_from_static_string ("lua redis"));

			double_to_tv (timeout, &tv);
			event_set (&ud->timeout, -1, EV_TIMEOUT, lua_redis_timeout, ud);
			event_base_set (ud->task->ev_base, &ud->timeout);
			event_add (&ud->timeout, &tv);
		}
		else {
			msg_info ("call to redis failed: %s", ud->ctx->errstr);
			ud->terminated = 1;
			lua_redis_free_args (ud);
			redisAsyncFree (ud->ctx);
			luaL_unref (ud->L, LUA_REGISTRYINDEX, ud->cbref);
		}
	}

	lua_pushboolean (L, ret);

	return 1;
}
int 
luaQ_complete(struct lua_State *L)
{
  int k = 0;
  int loop = 0;
  const char *stem = luaL_checkstring(L, 1);
  lua_pushvalue(L, LUA_GLOBALSINDEX);
  for(;;)
    {
      const char *s = stem;
      while (*s && *s != '.' && *s != ':')
        s++;
      if (*s == 0)
        break;
      // stack: table str
      lua_pushlstring(L, stem, s-stem);
      lua_gettable(L, -2);
      // stack: ntable table str
      lua_replace(L, -2);
      // stack: ntable str
      stem = s + 1;
    }
  lua_createtable(L, 0, 0);
  lua_insert(L, -2);
  // stack: maybetable anstable str
  if (lua_isuserdata(L, -1) && lua_getmetatable(L, -1))
    {
      lua_replace(L, -2);
      lua_pushliteral(L, "__index");
      lua_rawget(L, -2);
      if (lua_isfunction(L, -1))
        {
          lua_pop(L, 1);
          lua_pushliteral(L, "__metatable");
          lua_rawget(L, -2);
        }
      lua_replace(L, -2);
    }
  if (! lua_istable(L, -1))
    {
      lua_pop(L, 1);
      return 1;
    }
  // stack: table anstable str
  size_t stemlen = strlen(stem);
  for(;;)
    {
      lua_pushnil(L);
      while (lua_next(L, -2))
        {
          // stack: value key table anstable str
          bool ok = false;
          size_t keylen;
          const char *key = lua_tolstring(L, -2, &keylen);
          if (key && keylen > 0 && keylen >= stemlen)
            if (!strncmp(key, stem, stemlen))
              ok = true;
          if (ok && stemlen==0 && !isalpha(key[0]))
            ok = false;
          if (ok)
            for (int i=0; ok && i<(int)keylen; i++)
              if (!isalpha(key[i]) && !isdigit(key[i]) && key[i]!='_')
                ok = false;
          if (ok)
            {
              const char *suffix = "";
              switch (lua_type(L, -1)) 
                {
                case LUA_TFUNCTION: 
                  suffix = "("; 
                  break;
                case LUA_TTABLE: 
                  suffix = ".";
                  luaQ_getfield(L, -1, "_C");
                  if (lua_istable(L, -1))
                    suffix = ":";
                  lua_pop(L, 1);
                  break;
                case LUA_TUSERDATA: {
                  QVariant v = luaQ_toqvariant(L, -1);
                  const char *s = QMetaType::typeName(v.userType());
                  if (s && !strcmp(s,"QtLuaMethodInfo"))
                    suffix = "(";
                  else if (s && !strcmp(s, "QtLuaPropertyInfo"))
                    suffix = "";
                  else if (lua_getmetatable(L, -1)) {
                    lua_pop(L, 1);
                    suffix = ":";
                  } else 
                    suffix = "";
                } break;
                default:
                  break;
                }
              // stack: value key table anstable str
              lua_pushfstring(L, "%s%s", key+stemlen, suffix);
              lua_rawseti(L, -5, ++k);
            }
          lua_pop(L, 1);
        }
      // stack: table anstable str
      if (! lua_getmetatable(L, -1))
        break;
      lua_replace(L, -2);
      lua_pushliteral(L, "__index");
      lua_rawget(L, -2);
      if (lua_isfunction(L, -1))
        {
          lua_pop(L, 1);
          lua_pushliteral(L, "__metatable");
          lua_rawget(L, -2);
        }
      lua_replace(L, -2);
      if (! lua_istable(L, -1))
        break;
      if (++loop > 100)
        luaL_error(L, "complete: infinite loop in metatables");
    }
  // stack: something anstable str
  lua_pop(L, 1);
  lua_replace(L, -2);
  return 1;
}
/*****************************************************************************
 * FillDescriptor: call the descriptor function and fill the structure
 ****************************************************************************/
static int FillDescriptor( services_discovery_t *p_sd,
                           services_discovery_descriptor_t *p_desc )
{
    services_discovery_sys_t *p_sys = p_sd->p_sys;
    int i_ret = VLC_EGENERIC;

    /* Create a new lua thread */
    lua_State *L = luaL_newstate();

    if( luaL_dofile( L, p_sys->psz_filename ) )
    {
        msg_Err( p_sd, "Error loading script %s: %s", p_sys->psz_filename,
                 lua_tostring( L, -1 ) );
        goto end;
    }

    /* Call the "descriptor" function */
    lua_getglobal( L, "descriptor" );
    if( !lua_isfunction( L, -1 ) || lua_pcall( L, 0, 1, 0 ) )
    {
        msg_Warn( p_sd, "Error getting the descriptor in '%s': %s",
                  p_sys->psz_filename, lua_tostring( L, -1 ) );
        goto end;
    }

    /* Get the different fields of the returned table */
    lua_getfield( L, -1, "short_description" );
    p_desc->psz_short_desc = luaL_strdupornull( L, -1 );
    lua_pop( L, 1 );

    lua_getfield( L, -1, "icon" );
    p_desc->psz_icon_url = luaL_strdupornull( L, -1 );
    lua_pop( L, 1 );

    lua_getfield( L, -1, "url" );
    p_desc->psz_url = luaL_strdupornull( L, -1 );
    lua_pop( L, 1 );

    lua_getfield( L, -1, "capabilities" );
    p_desc->i_capabilities = 0;
    if( lua_istable( L, -1 ) )
    {
        /* List all table entries */
        lua_pushnil( L );
        while( lua_next( L, -2 ) != 0 )
        {
            /* Key is at index -2 and value at index -1 */
            const char *psz_cap = luaL_checkstring( L, -1 );
            int i_cap = 0;
            const char *psz_iter;
            for( psz_iter = *ppsz_capabilities; psz_iter;
                 psz_iter = ppsz_capabilities[ ++i_cap ] )
            {
                if( !strcmp( psz_iter, psz_cap ) )
                {
                    p_desc->i_capabilities |= 1 << i_cap;
                    break;
                }
            }

            lua_pop( L, 1 );

            if( !psz_iter )
                msg_Warn( p_sd, "Services discovery capability '%s' unknown in "
                                "script '%s'", psz_cap, p_sys->psz_filename );
        }
    }

    lua_pop( L, 1 );
    i_ret = VLC_SUCCESS;

end:
    lua_close( L );
    return i_ret;

}
Exemple #8
0
int luabridge::indexer (lua_State *L)
{
	lua_getmetatable(L, 1);

	do {
		// Look for the key in the metatable
		lua_pushvalue(L, 2);
		lua_rawget(L, -2);
		// Did we get a non-nil result?  If so, return it
		if (!lua_isnil(L, -1) )
			return 1;
		///pop the nil
		lua_pop(L, 1);
		//search the metatable of the object's metatable.
		if( lua_getmetatable(L, -1) && !lua_isnil(L, -1) )
		{
			//to prevent calling this indexer method again, make sure the found metatable is not equal to the table's metatable.
			if( !lua_rawequal(L, -1, -2) )
			{
				//store our current argument cnt so we can determine if any arguments were pushed
				ptrdiff_t base = lua_gettop(L), top;
				//push the method name being called
				lua_pushvalue(L,2);
				//try to retrieve the key and allow any events to be called.
				lua_gettable(L,-2);
				//if there were any arguments, return those.
				top = lua_gettop(L);
				//check for multiple arguments.
				if( top > (base+1) )
					return (top - base);
				//check if the returned object is nil
				else if(top == (base+1) && !lua_isnil(L, -1) )
					return 1;
				else if(top == (base+1) && lua_isnil(L, -1 ))
					lua_pop(L,1);
				//otherwise, proceed w/ other checks.
			}
			//pop the metatable's metatable.
			lua_pop(L, 1);
		}
		// Look for the key in the __propget metafield
		rawgetfield(L, -1, "__propget");
		if (!lua_isnil(L, -1))
		{
			lua_pushvalue(L, 2);
			lua_rawget(L, -2);
			// If we got a non-nil result, call it and return its value
			if (!lua_isnil(L, -1))
			{
				assert(lua_isfunction(L, -1));
				lua_pushvalue(L, 1);
				lua_call(L, 1, 1);
				return 1;
			}
			lua_pop(L, 1);
		}
		lua_pop(L, 1);
		
		// Look for the key in the __const metafield
		rawgetfield(L, -1, "__const");
		if (!lua_isnil(L, -1))
		{
			lua_pushvalue(L, 2);
			lua_rawget(L, -2);
			if (!lua_isnil(L, -1))
				return 1;
			lua_pop(L, 1);
		}
		lua_pop(L, 1);
		
		// Look for a __parent metafield; if it doesn't exist, return nil;
		// otherwise, repeat the lookup on it.
		rawgetfield(L, -1, "__parent");
		if (lua_isnil(L, -1))
			return 1;
		lua_remove(L, -2);
	} while (true);
	
	// Control never gets here
	return 0;
}
Exemple #9
0
void LuaState::call( const std::string& callbackName, int registryIndex, bool exception ) 
{
    
    TRACE_ENTERLEAVE();
    
    TRACE( "callback name: %s, callback index %d", callbackName.c_str(), registryIndex );
    
            
    //
    //  load debug.traceback
    //  
    lua_getglobal( m_lua, "debug" );
    lua_getfield( m_lua, -1, "traceback" );
    
    
    int debugIndex = -2;
    
    //
    //  load callback function to the top of the stack
    //
    if ( registryIndex < 0  )
    {
        //
        //  push function identified by global name to the stack
        //  
        lua_getglobal( m_lua, "__leda" );
        lua_getfield( m_lua, -1, callbackName.c_str() );
        debugIndex = -3;
    }
    else
    {
        //
        //  push function identified by registry index to the stack
        //  
        lua_rawgeti( m_lua, LUA_REGISTRYINDEX, registryIndex );
    }
    
    if ( !lua_isfunction( m_lua, -1 ) )
    {
        TRACE( "no lua function found on top of stack", "" );
        
        lua_pop( m_lua, -debugIndex + 1 );
        return;
    }
    //
    //  call lua callback function
    //
    int result = lua_pcall( m_lua, 0, 0, debugIndex );
    
    TRACE( "lua call result: %d", result );

    if ( result > 0 )
    {
        //
        //  error executing lua
        //
        const char* error = lua_tostring( m_lua, -1 );
        
        TRACE_ERROR( "%s", error );
        
        lua_pop( m_lua, -debugIndex + 1 );
        
        std::string errorString;
        if ( error )
        {
            errorString = error;
        }
        
        if ( exception )
        {
            throw std::runtime_error( errorString );
        }
        
        return;
    }
    
    //
    //  pop all from stack
    //
    lua_pop( m_lua, -debugIndex );
}
Exemple #10
0
int
main(int argc, char *argv[])
{
    struct hostent *server_host;
    char *server_host_str = "localhost";
    char *certificate_file = NULL;
    char *key_file = NULL;
    char *password_file = NULL;
    char *token_file = NULL;
    char *username = "******";
    int port = 64738;
    int ret;
    int development_mode = 0;

    int socket_fd;
    struct sockaddr_in server_addr;

    SSLRead socket_watcher;
    ev_io user_thread_watcher;
    ev_timer ping_watcher;
    ev_signal signal_watcher;
    ev_loop_main = EV_DEFAULT;

    /*
     * Lua initialization
     */
    lua = luaL_newstate();
    if (lua == NULL) {
        fprintf(stderr, "%s: could not initialize Lua\n", PIEPAN_NAME);
        return 1;
    }
    luaL_openlibs(lua);
    if (luaL_loadbuffer(lua, (const char *)src_piepan_impl_luac,
            src_piepan_impl_luac_len, "piepan_impl") != LUA_OK) {
        fprintf(stderr, "%s: could not load piepan implementation\n", PIEPAN_NAME);
        return 1;
    }
    lua_call(lua, 0, 0);

    lua_getglobal(lua, "piepan");
    lua_getfield(lua, -1, "internal");
    lua_getfield(lua, -1, "api");
    lua_pushcfunction(lua, api_init);
    lua_setfield(lua, -2, "apiInit");
    lua_settop(lua, 0);

    /*
     * Argument parsing
     */
    {
        int opt;
        int i;
        int show_help = 0;
        int show_version = 0;
        lua_getglobal(lua, "piepan");
        lua_getfield(lua, -1, "internal");
        lua_getfield(lua, -1, "events");
        lua_getfield(lua, -1, "onArgument");
        opterr = 0;
        while ((opt = getopt(argc, argv, "u:c:k:s:t:p:-:dhv")) != -1) {
            switch (opt) {
                case 'u':
                    username = optarg;
                    break;
                case 'c':
                    certificate_file = optarg;
                    if (key_file == NULL) {
                        key_file = certificate_file;
                    }
                    break;
                case 'k':
                    key_file = optarg;
                    break;
                case 's': {
                    char *port_str;
                    server_host_str = optarg;
                    port_str = strrchr(server_host_str, ':');
                    if (port_str != NULL) {
                        *port_str = '\0';
                        port = atoi(++port_str);
                    }
                    break;
                }
                case 't':
                    token_file = optarg;
                    break;
                case 'p':
                    password_file = optarg;
                    break;
                case '-': {
                    char *key = optarg;
                    char *value = strchr(key, '=');
                    if (key == value) {
                        break;
                    }
                    if (value != NULL) {
                        *value++ = 0;
                    }
                    lua_pushvalue(lua, -1);
                    lua_pushstring(lua, key);
                    lua_pushstring(lua, value);
                    lua_call(lua, 2, 0);
                    break;
                }
                case 'd':
                    development_mode = 1;
                    break;
                case 'h':
                    usage(stdout);
                    return 0;
                case 'v':
                    printf("%s %s (compiled on " __DATE__ " " __TIME__ ")\n",
                           PIEPAN_NAME, PIEPAN_VERSION);
                    return 0;
                default:
                    fprintf(stderr, "%s: unknown or incomplete option '%c'\n",
                            PIEPAN_NAME, optopt);
                    return 1;
            }
        }
        lua_settop(lua, 0);
    }

    /*
     * Load user scripts
     */
    {
        int i;
        lua_getglobal(lua, "piepan");
        lua_getfield(lua, -1, "internal");
        lua_getfield(lua, -1, "events");
        lua_getfield(lua, -1, "onLoadScript");
        for (i = optind; i < argc; i++) {
            lua_pushvalue(lua, -1);
            lua_pushstring(lua, argv[i]);
            if (development_mode) {
                lua_newuserdata(lua, sizeof(ScriptStat));
            } else {
                lua_pushnil(lua);
            }
            lua_call(lua, 2, 3);
            if (lua_toboolean(lua, -3)) {
                if (development_mode) {
                    ScriptStat *item = lua_touserdata(lua, -1);
                    item->lua = lua;
                    item->id = lua_tointeger(lua, -2);
                    item->filename = argv[i];
                    ev_stat_init(&item->ev, script_stat_event, item->filename, 0);
                    ev_stat_start(ev_loop_main, &item->ev);
                }
            } else {
                fprintf(stderr, "%s: %s\n", PIEPAN_NAME, lua_tostring(lua, -2));
            }
            lua_pop(lua, 3);
        }
        lua_settop(lua, 0);
    }

    /*
     * Initialize Opus
     */
    {
        OpusEncoder *encoder;
        int error;

        lua_getglobal(lua, "piepan");
        lua_getfield(lua, -1, "internal");
        lua_getfield(lua, -1, "opus");
        encoder = lua_newuserdata(lua, opus_encoder_get_size(1));
        lua_setfield(lua, -2, "encoder");

        error = opus_encoder_init(encoder, 48000, 1, OPUS_APPLICATION_AUDIO);
        if (error != OPUS_OK) {
            fprintf(stderr, "%s: could not initialize the Opus encoder: %s\n",
                    PIEPAN_NAME, opus_strerror(error));
            return 1;
        }
        opus_encoder_ctl(encoder, OPUS_SET_VBR(0));
        /* TODO: set this to the server's max bitrate */
        opus_encoder_ctl(encoder, OPUS_SET_BITRATE(40000));

        lua_settop(lua, 0);
    }

    /*
     * SSL initialization
     */
    SSL_library_init();

    ssl_context = SSL_CTX_new(SSLv23_client_method());
    if (ssl_context == NULL) {
        fprintf(stderr, "%s: could not create SSL context\n", PIEPAN_NAME);
        return 1;
    }

    if (certificate_file != NULL) {
        if (!SSL_CTX_use_certificate_chain_file(ssl_context, certificate_file) ||
                !SSL_CTX_use_PrivateKey_file(ssl_context, key_file,
                                                SSL_FILETYPE_PEM) ||
                !SSL_CTX_check_private_key(ssl_context)) {
            fprintf(stderr, "%s: could not load certificate and/or key file\n",
                    PIEPAN_NAME);
            return 1;
        }
    }

    /*
     * Socket initialization and connection
     */
    socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_fd < 0) {
        fprintf(stderr, "%s: could not create socket\n", PIEPAN_NAME);
        return 1;
    }

    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);

    server_host = gethostbyname(server_host_str);
    if (server_host == NULL || server_host->h_addr_list[0] == NULL ||
            server_host->h_addrtype != AF_INET) {
        fprintf(stderr, "%s: could not parse server address\n", PIEPAN_NAME);
        return 1;
    }
    memmove(&server_addr.sin_addr, server_host->h_addr_list[0],
            server_host->h_length);

    ret = connect(socket_fd, (struct sockaddr *) &server_addr,
                  sizeof(server_addr));
    if (ret != 0) {
        fprintf(stderr, "%s: could not connect to server\n", PIEPAN_NAME);
        return 1;
    }

    ssl = SSL_new(ssl_context);
    if (ssl == NULL) {
        fprintf(stderr, "%s: could not create SSL object\n", PIEPAN_NAME);
        return 1;
    }

    if (SSL_set_fd(ssl, socket_fd) == 0) {
        fprintf(stderr, "%s: could not set SSL file descriptor\n", PIEPAN_NAME);
        return 1;
    }

    if (SSL_connect(ssl) != 1) {
        fprintf(stderr, "%s: could not create secure connection\n", PIEPAN_NAME);
        return 1;
    }

    /*
     * User thread pipe
     */
    if (pipe(user_thread_pipe) != 0) {
        fprintf(stderr, "%s: could not create user thread pipe\n", PIEPAN_NAME);
        return 1;
    }

    /*
     * Trigger initial event
     */
    lua_getglobal(lua, "piepan");
    lua_getfield(lua, -1, "internal");
    lua_getfield(lua, -1, "initialize");
    lua_newtable(lua);
    lua_pushstring(lua, username);
    lua_setfield(lua, -2, "username");
    if (password_file != NULL) {
        lua_pushstring(lua, password_file);
        lua_setfield(lua, -2, "passwordFile");
    }
    if (token_file != NULL) {
        lua_pushstring(lua, token_file);
        lua_setfield(lua, -2, "tokenFile");
    }
    lua_pushlightuserdata(lua, lua);
    lua_setfield(lua, -2, "state");
    lua_call(lua, 1, 0);
    lua_settop(lua, 0);

    /*
     * Event loop
     */
    ev_signal_init(&signal_watcher, signal_event, SIGINT);
    ev_signal_start(ev_loop_main, &signal_watcher);

    ev_io_init(&socket_watcher.ev, socket_read_event, socket_fd, EV_READ);
    socket_watcher.lua = lua;
    socket_watcher.ssl = ssl;
    ev_io_start(ev_loop_main, &socket_watcher.ev);

    ev_io_init(&user_thread_watcher, user_thread_event, user_thread_pipe[0],
               EV_READ);
    ev_io_start(ev_loop_main, &user_thread_watcher);

    ev_timer_init(&ping_watcher, ping_event, PING_TIMEOUT, PING_TIMEOUT);
    ev_timer_start(ev_loop_main, &ping_watcher);

    ev_run(ev_loop_main, 0);

    /*
     * Cleanup
     */
    lua_getglobal(lua, "piepan");
    lua_getfield(lua, -1, "internal");
    lua_getfield(lua, -1, "events");
    lua_getfield(lua, -1, "onDisconnect");
    if (lua_isfunction(lua, -1)) {
        lua_newtable(lua);
        lua_call(lua, 1, 0);
    }

    SSL_shutdown(ssl); /* TODO:  sigpipe is triggered here if connection breaks */
    close(socket_fd);
    lua_close(lua);

    return 0;
}
Exemple #11
0
static int lluv_tcp_bind(lua_State *L){
  static const lluv_uv_const_t FLAGS[] = {
    { UV_TCP_IPV6ONLY ,   "ipv6only"   },

    { 0, NULL }
  };

  lluv_handle_t  *handle = lluv_check_tcp(L, 1, LLUV_FLAG_OPEN);
  struct sockaddr_storage sa; int err = lluv_check_addr(L, 2, &sa);
  unsigned int flags = 0;
  int top = lua_gettop(L);
  if(top > 5)lua_settop(L, top = 5);

  if((top > 4) || (!lua_isfunction(L, 4))){
    flags = lluv_opt_flags_ui(L, 4, flags, FLAGS);
  }

  if(err < 0){
    lua_checkstack(L, 3);

    lua_pushvalue(L, 2); lua_pushliteral(L, ":"); lua_pushvalue(L, 3); lua_concat(L, 3);

    if(!lua_isfunction(L, top)){
      return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, lua_tostring(L, -1));
    }

    lluv_error_create(L, LLUV_ERR_UV, err, lua_tostring(L, -1));
    lua_remove(L, -2);
    lua_pushvalue(L, 1);
    lua_insert(L, -2);
    lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), 2);
    lua_settop(L, 1);
    return 1;
  }

  err = uv_tcp_bind(LLUV_H(handle, uv_tcp_t), (struct sockaddr *)&sa, flags);
  if(err < 0){
    lua_checkstack(L, 3);

    lua_pushvalue(L, 2); lua_pushliteral(L, ":"); lua_pushvalue(L, 3); lua_concat(L, 3);

    if(!lua_isfunction(L, top)){
      return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, lua_tostring(L, -1));
    }

    lluv_error_create(L, LLUV_ERR_UV, err, lua_tostring(L, -1));
    lua_remove(L, -2);
    lua_pushvalue(L, 1);
    lua_insert(L, -2);
    lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), 2);
    lua_settop(L, 1);
    return 1;
  }

  if(lua_isfunction(L, top)){
    lua_pushvalue(L, 1);
    lua_pushnil(L);
    lluv_loop_defer_call(L,
      lluv_loop_by_handle(&handle->handle),
      lluv_push_addr(L, &sa) + 2
    );
  }

  lua_settop(L, 1);
  return 1;
}
Exemple #12
0
static int js_generator_value(lua_State *L) {
    int max;
    int is_array;
    int no_vals;
    int type = lua_type(L, 2);

    switch ( type ) {
    case LUA_TNIL:
        return js_generator_null(L);
    case LUA_TNUMBER:
        return js_generator_number(L);
    case LUA_TBOOLEAN:
        return js_generator_boolean(L);
    case LUA_TSTRING:
        return js_generator_string(L);
    case LUA_TUSERDATA:
        if ( lua_topointer(L, 2) == js_null ) {
            return js_generator_null(L);
        }
    case LUA_TLIGHTUSERDATA:
    case LUA_TTABLE:
    case LUA_TFUNCTION:
    case LUA_TTHREAD:
        if ( luaL_getmetafield(L, 2, "__gen_json") ) {
            if  ( lua_isfunction(L, -1) ) {
                lua_settop(L, 3); /* gen, obj, func */
                lua_insert(L, 1); /* func, gen, obj */
                lua_insert(L, 2); /* func, obj, gen */
                lua_call(L, 2, 0);
                return 0;
            }
            lua_pop(L, 1);
        }

        /* Simply ignore it, perhaps we should warn? */
        if ( type != LUA_TTABLE )  {
            js_generator_open_object(L);
            js_generator_close(L);
            return 0;
        }

        max      = 0;
        is_array = 1;
        no_vals  = 1;

        /* First iterate over the table to see if it is an array: */
        lua_pushnil(L);
        while ( lua_next(L, 2) != 0 ) {
            no_vals = 0;
            if ( lua_type(L, -2) == LUA_TNUMBER ) {
                double num = lua_tonumber(L, -2);
                if ( num == floor(num) ) {
                    if ( num > max ) max = num;
                } else {
                    lua_pop(L, 2);
                    is_array = 0;
                    break;
                }
            } else if (lua_type(L, -2) == LUA_TSTRING && strncmp(lua_tostring(L, -2), "length", 6) == 0) {
                // ignore "length"
            } else {
                lua_pop(L, 2);
                is_array = 0;
                break;
            }
            lua_pop(L, 1);
        }

        if ( is_array && !no_vals ) {
            int i;
            js_generator_open_array(L);
            for ( i=0; i <= max; i++ ) {
                lua_pushinteger(L, i);
                lua_gettable(L, 2);

                /* RECURSIVE CALL:
                   gen, obj, ?, val, func, gen, val */
                lua_pushcfunction(L, js_generator_value);
                lua_pushvalue(L, 1);
                lua_pushvalue(L, -3);
                lua_call(L, 2, 0);

                lua_pop(L, 1);
            }
        } else {
            js_generator_open_object(L);

            lua_pushnil(L);
            while ( lua_next(L, 2) != 0 ) {
                /* gen, obj, ?, key, val, func, gen, key */
                lua_pushcfunction(L, js_generator_string);
                lua_pushvalue(L, 1);
                if ( lua_isstring(L, -4) ) {
                    lua_pushvalue(L, -4);
                } else {
                    /* Must coerce into a string: */
                    lua_getglobal(L, "tostring");
                    lua_pushvalue(L, -5);
                    lua_call(L, 1, 1);
                }

                /* support replacer */
                lua_getfenv(L, 1);
                lua_getfield(L, -1, "replacer");
                lua_remove(L, -2);
                if (!lua_isnil(L, -1)) {
                    lua_pushvalue(L, 2);
                    lua_pushvalue(L, -7);
                    lua_pushvalue(L, -7);
                    lua_call(L, 3, 1);
                    if (lua_isnil(L, -1)) {
                        lua_remove(L, -1);
                        continue;
                    } else {
                        lua_replace(L, -5);
                    }
                } else {
                    lua_remove(L, -1);
                }


                /* push key */
                lua_call(L, 2, 0);

                /* RECURSIVE CALL:
                   gen, obj, ?, key, val, func, gen, val */
                lua_pushcfunction(L, js_generator_value);
                lua_pushvalue(L, 1);
                lua_pushvalue(L, -3);
                lua_call(L, 2, 0);

                lua_pop(L, 1);
            }
        }
        js_generator_close(L);
        return 0;
    case LUA_TNONE:
        lua_pushfstring(L, "MissingArgument: second parameter to js_generator_value() must be defined at %s line %d", type, __FILE__, __LINE__);
    default:
        lua_pushfstring(L, "Unreachable: js_generator_value passed lua type (%d) not recognized at %s line %d", type, __FILE__, __LINE__);
    }
    /* Shouldn't get here: */
    lua_error(L);
    return 0;
}
Exemple #13
0
JNIEXPORT jboolean JNICALL Java_m_lua_Lua_isFunction
		(JNIEnv* env, jobject thiz, jlong nativeObj, jint idx) {
	return (jboolean) lua_isfunction((lua_State*) nativeObj, idx);
}
Exemple #14
0
/**
 * walk through the content array
 *
 * content = { "<pre>", { file = "/content" } , "</pre>" }
 *
 * header["Content-Type"] = "text/html"
 *
 * return 200
 */
static int magnet_attach_content(server *srv, connection *con, plugin_data *p, lua_State *L) {
	UNUSED(p);
	/**
	 * get the environment of the function
	 */

	force_assert(lua_isfunction(L, -1));
	lua_getfenv(L, -1); /* -1 is the function */

	lua_getfield(L, -1, "lighty"); /* lighty.* from the env  */
	force_assert(lua_istable(L, -1));

	lua_getfield(L, -1, "content"); /* lighty.content */
	if (lua_istable(L, -1)) {
		int i;
		/* header is found, and is a table */

		for (i = 1; ; i++) {
			lua_rawgeti(L, -1, i);

			/* -1 is the value and should be the value ... aka a table */
			if (lua_isstring(L, -1)) {
				size_t s_len = 0;
				const char *s = lua_tolstring(L, -1, &s_len);

				chunkqueue_append_mem(con->write_queue, s, s_len);
			} else if (lua_istable(L, -1)) {
				lua_getfield(L, -1, "filename");
				lua_getfield(L, -2, "length");
				lua_getfield(L, -3, "offset");

				if (lua_isstring(L, -3)) { /* filename has to be a string */
					buffer *fn;
					stat_cache_entry *sce;
					const char *fn_str;
					handler_t res;

					fn_str = lua_tostring(L, -3);
					fn = buffer_init_string(fn_str);

					res = stat_cache_get_entry(srv, con, fn, &sce);

					if (HANDLER_GO_ON == res) {
						off_t off = 0;
						off_t len = 0;

						if (lua_isnumber(L, -1)) {
							off = lua_tonumber(L, -1);
						}

						if (lua_isnumber(L, -2)) {
							len = lua_tonumber(L, -2);
						} else {
							len = sce->st.st_size;
						}

						if (off < 0) {
							buffer_free(fn);
							return luaL_error(L, "offset for '%s' is negative", fn_str);
						}

						if (len < off) {
							buffer_free(fn);
							return luaL_error(L, "offset > length for '%s'", fn_str);
						}

						chunkqueue_append_file(con->write_queue, fn, off, len - off);
					}

					buffer_free(fn);
				} else {
					lua_pop(L, 3 + 2); /* correct the stack */

					return luaL_error(L, "content[%d] is a table and requires the field \"filename\"", i);
				}

				lua_pop(L, 3);
			} else if (lua_isnil(L, -1)) {
				/* oops, end of list */

				lua_pop(L, 1);

				break;
			} else {
				lua_pop(L, 4);

				return luaL_error(L, "content[%d] is neither a string nor a table: ", i);
			}

			lua_pop(L, 1); /* pop the content[...] table */
		}
	} else {
		return luaL_error(L, "lighty.content has to be a table");
	}
	lua_pop(L, 1); /* pop the header-table */
	lua_pop(L, 1); /* pop the lighty-table */
	lua_pop(L, 1); /* php the function env */

	return 0;
}
Exemple #15
0
ContentFeatures read_content_features(lua_State *L, int index)
{
	if(index < 0)
		index = lua_gettop(L) + 1 + index;

	ContentFeatures f;

	/* Cache existence of some callbacks */
	lua_getfield(L, index, "on_construct");
	if(!lua_isnil(L, -1)) f.has_on_construct = true;
	lua_pop(L, 1);
	lua_getfield(L, index, "on_destruct");
	if(!lua_isnil(L, -1)) f.has_on_destruct = true;
	lua_pop(L, 1);
	lua_getfield(L, index, "after_destruct");
	if(!lua_isnil(L, -1)) f.has_after_destruct = true;
	lua_pop(L, 1);

	lua_getfield(L, index, "on_rightclick");
	f.rightclickable = lua_isfunction(L, -1);
	lua_pop(L, 1);

	/* Name */
	getstringfield(L, index, "name", f.name);

	/* Groups */
	lua_getfield(L, index, "groups");
	read_groups(L, -1, f.groups);
	lua_pop(L, 1);

	/* Visual definition */

	f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype",
			ScriptApiNode::es_DrawType,NDT_NORMAL);
	getfloatfield(L, index, "visual_scale", f.visual_scale);

	/* Meshnode model filename */
	getstringfield(L, index, "mesh", f.mesh);

	// tiles = {}
	lua_getfield(L, index, "tiles");
	// If nil, try the deprecated name "tile_images" instead
	if(lua_isnil(L, -1)){
		lua_pop(L, 1);
		warn_if_field_exists(L, index, "tile_images",
				"Deprecated; new name is \"tiles\".");
		lua_getfield(L, index, "tile_images");
	}
	if(lua_istable(L, -1)){
		int table = lua_gettop(L);
		lua_pushnil(L);
		int i = 0;
		while(lua_next(L, table) != 0){
			// Read tiledef from value
			f.tiledef[i] = read_tiledef(L, -1);
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
			i++;
			if(i==6){
				lua_pop(L, 1);
				break;
			}
		}
		// Copy last value to all remaining textures
		if(i >= 1){
			TileDef lasttile = f.tiledef[i-1];
			while(i < 6){
				f.tiledef[i] = lasttile;
				i++;
			}
		}
	}
	lua_pop(L, 1);

	// special_tiles = {}
	lua_getfield(L, index, "special_tiles");
	// If nil, try the deprecated name "special_materials" instead
	if(lua_isnil(L, -1)){
		lua_pop(L, 1);
		warn_if_field_exists(L, index, "special_materials",
				"Deprecated; new name is \"special_tiles\".");
		lua_getfield(L, index, "special_materials");
	}
	if(lua_istable(L, -1)){
		int table = lua_gettop(L);
		lua_pushnil(L);
		int i = 0;
		while(lua_next(L, table) != 0){
			// Read tiledef from value
			f.tiledef_special[i] = read_tiledef(L, -1);
			// removes value, keeps key for next iteration
			lua_pop(L, 1);
			i++;
			if(i==CF_SPECIAL_COUNT){
				lua_pop(L, 1);
				break;
			}
		}
	}
	lua_pop(L, 1);

	f.alpha = getintfield_default(L, index, "alpha", 255);

	bool usealpha = getboolfield_default(L, index,
			"use_texture_alpha", false);
	if (usealpha)
		f.alpha = 0;

	/* Other stuff */

	lua_getfield(L, index, "post_effect_color");
	read_color(L, -1, &f.post_effect_color);
	lua_pop(L, 1);

	f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
			ScriptApiNode::es_ContentParamType, CPT_NONE);
	f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
			ScriptApiNode::es_ContentParamType2, CPT2_NONE);

	// Warn about some deprecated fields
	warn_if_field_exists(L, index, "wall_mounted",
			"deprecated: use paramtype2 = 'wallmounted'");
	warn_if_field_exists(L, index, "light_propagates",
			"deprecated: determined from paramtype");
	warn_if_field_exists(L, index, "dug_item",
			"deprecated: use 'drop' field");
	warn_if_field_exists(L, index, "extra_dug_item",
			"deprecated: use 'drop' field");
	warn_if_field_exists(L, index, "extra_dug_item_rarity",
			"deprecated: use 'drop' field");
	warn_if_field_exists(L, index, "metadata_name",
			"deprecated: use on_add and metadata callbacks");

	// True for all ground-like things like stone and mud, false for eg. trees
	getboolfield(L, index, "is_ground_content", f.is_ground_content);
	f.light_propagates = (f.param_type == CPT_LIGHT);
	getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates);
	// This is used for collision detection.
	// Also for general solidness queries.
	getboolfield(L, index, "walkable", f.walkable);
	// Player can point to these
	getboolfield(L, index, "pointable", f.pointable);
	// Player can dig these
	getboolfield(L, index, "diggable", f.diggable);
	// Player can climb these
	getboolfield(L, index, "climbable", f.climbable);
	// Player can build on these
	getboolfield(L, index, "buildable_to", f.buildable_to);
	// Whether the node is non-liquid, source liquid or flowing liquid
	f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype",
			ScriptApiNode::es_LiquidType, LIQUID_NONE);
	// If the content is liquid, this is the flowing version of the liquid.
	getstringfield(L, index, "liquid_alternative_flowing",
			f.liquid_alternative_flowing);
	// If the content is liquid, this is the source version of the liquid.
	getstringfield(L, index, "liquid_alternative_source",
			f.liquid_alternative_source);
	// Viscosity for fluid flow, ranging from 1 to 7, with
	// 1 giving almost instantaneous propagation and 7 being
	// the slowest possible
	f.liquid_viscosity = getintfield_default(L, index,
			"liquid_viscosity", f.liquid_viscosity);
	f.liquid_range = getintfield_default(L, index,
			"liquid_range", f.liquid_range);
	f.leveled = getintfield_default(L, index, "leveled", f.leveled);

	getboolfield(L, index, "liquid_renewable", f.liquid_renewable);
	f.drowning = getintfield_default(L, index,
			"drowning", f.drowning);
	// Amount of light the node emits
	f.light_source = getintfield_default(L, index,
			"light_source", f.light_source);
	f.damage_per_second = getintfield_default(L, index,
			"damage_per_second", f.damage_per_second);

	lua_getfield(L, index, "node_box");
	if(lua_istable(L, -1))
		f.node_box = read_nodebox(L, -1);
	lua_pop(L, 1);

	lua_getfield(L, index, "selection_box");
	if(lua_istable(L, -1))
		f.selection_box = read_nodebox(L, -1);
 	lua_pop(L, 1);

	lua_getfield(L, index, "collision_box");
	if(lua_istable(L, -1))
		f.collision_box = read_nodebox(L, -1);
	lua_pop(L, 1);

	f.waving = getintfield_default(L, index,
			"waving", f.waving);

	// Set to true if paramtype used to be 'facedir_simple'
	getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
	// Set to true if wall_mounted used to be set to true
	getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);

	// Sound table
	lua_getfield(L, index, "sounds");
	if(lua_istable(L, -1)){
		lua_getfield(L, -1, "footstep");
		read_soundspec(L, -1, f.sound_footstep);
		lua_pop(L, 1);
		lua_getfield(L, -1, "dig");
		read_soundspec(L, -1, f.sound_dig);
		lua_pop(L, 1);
		lua_getfield(L, -1, "dug");
		read_soundspec(L, -1, f.sound_dug);
		lua_pop(L, 1);
	}
	lua_pop(L, 1);

	return f;
}
Exemple #16
0
/* Lua only functions */
int luaT_lua_newmetatable(lua_State *L)
{
  const char* tname = luaL_checkstring(L, 1);
  const void *id;

  lua_settop(L, 5);
  luaL_argcheck(L, lua_isnoneornil(L, 2) || lua_isstring(L, 2), 2, "parent class name or nil expected");
  luaL_argcheck(L, lua_isnoneornil(L, 3) || lua_isfunction(L, 3), 3, "constructor function or nil expected");
  luaL_argcheck(L, lua_isnoneornil(L, 4) || lua_isfunction(L, 4), 4, "destructor function or nil expected");
  luaL_argcheck(L, lua_isnoneornil(L, 5) || lua_isfunction(L, 5), 5, "factory function or nil expected");

  if(luaT_classmodulename(tname))
    lua_getfield(L, LUA_GLOBALSINDEX, luaT_classmodulename(tname));
  else
    lua_pushvalue(L, LUA_GLOBALSINDEX);
  if(!lua_istable(L, 6))
    luaL_error(L, "while creating metatable %s: bad ardument #1 (%s is an invalid module name)", tname, luaT_classmodulename(tname));

  /* we first create the new metaclass if we have to */
  if(!luaT_typename2id(L, tname))
  {
    /* create the metaclass */
    lua_newtable(L);
    id = lua_topointer(L, -1); /* id = pointer on metaclass */

    /* __index points on itself */
    lua_pushvalue(L, -1);
    lua_setfield(L, -2, "__index");

    /* __typename contains the typename */
    lua_pushstring(L, tname);
    lua_setfield(L, -2, "__typename");

    /* by default, __version equals 1 */
    lua_pushnumber(L, 1);
    lua_setfield(L, -2, "__version");

    /* register in "*torch.id2tname*" registry table 
       (id -> typename) */
    lua_getfield(L, LUA_REGISTRYINDEX, "*torch.id2tname*");
    if(lua_isnil(L, -1))
    {
      lua_pop(L, 1);
      lua_newtable(L);
      lua_setfield(L, LUA_REGISTRYINDEX, "*torch.id2tname*");
      lua_getfield(L, LUA_REGISTRYINDEX, "*torch.id2tname*");
    }
    lua_pushlightuserdata(L, (void*)id);
    lua_pushstring(L, tname);
    lua_settable(L, -3);
    lua_pop(L, 1);

    /* register in "*torch.tname2id*" registry table 
       (typename -> id) */
    lua_getfield(L, LUA_REGISTRYINDEX, "*torch.tname2id*");
    if(lua_isnil(L, -1))
    {
      lua_pop(L, 1);
      lua_newtable(L);
      lua_setfield(L, LUA_REGISTRYINDEX, "*torch.tname2id*");
      lua_getfield(L, LUA_REGISTRYINDEX, "*torch.tname2id*");
    }
    lua_pushstring(L, tname);
    lua_pushlightuserdata(L, (void*)id);
    lua_settable(L, -3);
    lua_pop(L, 1);
  }

  /* we retrieve the existing metaclass */
  else
  {
    id = luaT_typename2id(L, tname);
    luaT_pushmetaclass(L, id);
  }

  /* we assign the parent class if necessary */
  if(!lua_isnoneornil(L, 2))
  {
    if(lua_getmetatable(L, -1))
      luaL_error(L, "class %s has been already assigned a parent class\n", tname);
    else
    {
      const char* parenttname = luaL_checkstring(L, 2);
      luaT_pushmetaclass(L, luaT_typename2id(L, parenttname));
      if(lua_isnil(L, -1))
        luaL_error(L, "bad argument #2 (invalid parent class name %s)", parenttname);
      lua_setmetatable(L, -2);
    }
  }

  /******** root-metatable ********/

  /* id is the pointer on the metatable
     registry[id] = root-metatable, so try to see if it exists */

  lua_pushlightuserdata(L, (void*)id); /* id */
  lua_rawget(L, LUA_REGISTRYINDEX);

  /* not existing? we create a new one! */
  if(lua_isnil(L, -1))
  {
    lua_pop(L, 1); /* remove nil on stack */
    lua_newtable(L);
    
    /* __index handling */
    lua_pushcfunction(L, luaT_rmt__index);
    lua_setfield(L, -2, "__index");
    
    /* __newindex handling */
    lua_pushcfunction(L, luaT_rmt__newindex);
    lua_setfield(L, -2, "__newindex");

    /* __metatable field (point on the metaclass) */
    lua_pushvalue(L, -2);
    lua_setfield(L, -2, "__metatable");

    /* __typename contains the typename */
    lua_pushstring(L, tname);
    lua_setfield(L, -2, "__typename");
    
    /* operators handling */
#define MT_ADD_OPERATOR(name) \
  lua_pushcfunction(L, luaT_rmt__##name); \
  lua_setfield(L, -2, "__" #name)
    
    MT_ADD_OPERATOR(tostring);
    MT_ADD_OPERATOR(add);
    MT_ADD_OPERATOR(sub);
    MT_ADD_OPERATOR(mul);
    MT_ADD_OPERATOR(div);
    MT_ADD_OPERATOR(mod);
    MT_ADD_OPERATOR(pow);
    MT_ADD_OPERATOR(unm);
    MT_ADD_OPERATOR(concat);
    MT_ADD_OPERATOR(len);
    MT_ADD_OPERATOR(eq);
    MT_ADD_OPERATOR(lt);
    MT_ADD_OPERATOR(le);
    MT_ADD_OPERATOR(call);
    
    /* assign the metaclass as metatable... */
    lua_pushvalue(L, -2);
    lua_setmetatable(L, -2);

    /* id is the pointer on the metatable
       set registry[id] = root-metatable */
    lua_pushlightuserdata(L, (void*)id); /* id */
    lua_pushvalue(L, -2);                /* metatable */
    lua_rawset(L, LUA_REGISTRYINDEX);    /* registry[id] = metatable */

  } /* ok, so now we have the root-metatable on the stack */

  /* register the destructor function  */
  if(!lua_isnoneornil(L, 4))
  {
    /* does it exists already? */
    lua_pushstring(L, "__gc");
    lua_rawget(L, -2);

    if(lua_isnil(L, -1))
    {
      lua_pop(L, 1); /* pop nil */
      lua_pushstring(L, "__gc");
      lua_pushvalue(L, 4);
      lua_rawset(L, -3);
    }
    else
      luaL_error(L, "%s has been already assigned a destructor", tname);
  }

  /* register the factory function  */
  if(!lua_isnoneornil(L, 5))
  {
    /* does it exists already? */
    lua_pushstring(L, "__factory");
    lua_rawget(L, -2);

    if(lua_isnil(L, -1))
    {
      lua_pop(L, 1); /* pop nil */
      lua_pushstring(L, "__factory");
      lua_pushvalue(L, 5);
      lua_rawset(L, -3);
    }
    else
      luaL_error(L, "%s has been already assigned a factory", tname);
  }

  /******** Constructor table and metatable ********/
  lua_pushstring(L, "__constructor");
  lua_rawget(L, -2);

  if(lua_isnil(L, -1))
  {
    lua_pop(L, 1);                        /* pop nil */
    lua_newtable(L);                      /* fancy table */
    lua_newtable(L);                      /* fancy metatable */

    lua_pushvalue(L, -4);                 /* metaclass */
    lua_setfield(L, -2, "__index");       /* so we can get the methods */

    lua_pushcfunction(L, luaT_cmt__newindex);
    lua_setfield(L, -2, "__newindex");    /* so we cannot messup */

    lua_pushcfunction(L, luaT_cmt__call);
    lua_setfield(L, -2, "__call");        /* so we can create */

    lua_pushvalue(L, -4); 
    lua_setfield(L, -2, "__metatable");   /* redirect to metatable with methods */

    lua_setmetatable(L, -2);              /* metatable is ... the fancy metatable */

    /* set root-metatable[__constructor] = constructor-metatable */
    lua_pushstring(L, "__constructor");
    lua_pushvalue(L, -2);
    lua_rawset(L, -4);
  }

  /* register the constructor function  */
  if(!lua_isnoneornil(L, 3))
  {
    /* get constructor metatable */
    lua_getmetatable(L, -1);

    /* does it exists already? */
    lua_pushstring(L, "__new");
    lua_rawget(L, -2);

    if(lua_isnil(L, -1))
    {
      lua_pop(L, 1); /* pop nil */
      lua_pushstring(L, "__new");
      lua_pushvalue(L, 3);
      lua_rawset(L, -3);
    }
    else
      luaL_error(L, "%s has been already assigned a constructor", tname);

    /* pop constructor metatable */
    lua_pop(L, 1);
  }
  
  lua_setfield(L, 6, luaT_classrootname(tname)); /* module.name = constructor-metatable */
  lua_pop(L, 1);                        /* pop the root-metatable */

  return 1; /* returns the metaclass */
}
Exemple #17
0
ItemDefinition read_item_definition(lua_State* L,int index,
		ItemDefinition default_def)
{
	if(index < 0)
		index = lua_gettop(L) + 1 + index;

	// Read the item definition
	ItemDefinition def = default_def;

	def.type = (ItemType)getenumfield(L, index, "type",
			es_ItemType, ITEM_NONE);
	getstringfield(L, index, "name", def.name);
	getstringfield(L, index, "description", def.description);
	getstringfield(L, index, "inventory_image", def.inventory_image);
	getstringfield(L, index, "wield_image", def.wield_image);

	lua_getfield(L, index, "wield_scale");
	if(lua_istable(L, -1)){
		def.wield_scale = check_v3f(L, -1);
	}
	lua_pop(L, 1);

	def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max);
	if(def.stack_max == 0)
		def.stack_max = 1;

	lua_getfield(L, index, "on_use");
	def.usable = lua_isfunction(L, -1);
	lua_pop(L, 1);

	getboolfield(L, index, "liquids_pointable", def.liquids_pointable);

	warn_if_field_exists(L, index, "tool_digging_properties",
			"deprecated: use tool_capabilities");

	lua_getfield(L, index, "tool_capabilities");
	if(lua_istable(L, -1)){
		def.tool_capabilities = new ToolCapabilities(
				read_tool_capabilities(L, -1));
	}

	// If name is "" (hand), ensure there are ToolCapabilities
	// because it will be looked up there whenever any other item has
	// no ToolCapabilities
	if(def.name == "" && def.tool_capabilities == NULL){
		def.tool_capabilities = new ToolCapabilities();
	}

	lua_getfield(L, index, "groups");
	read_groups(L, -1, def.groups);
	lua_pop(L, 1);

	lua_getfield(L, index, "sounds");
	if(lua_istable(L, -1)){
		lua_getfield(L, -1, "place");
		read_soundspec(L, -1, def.sound_place);
		lua_pop(L, 1);
	}
	lua_pop(L, 1);

	def.range = getfloatfield_default(L, index, "range", def.range);

	// Client shall immediately place this node when player places the item.
	// Server will update the precise end result a moment later.
	// "" = no prediction
	getstringfield(L, index, "node_placement_prediction",
			def.node_placement_prediction);

	return def;
}
Exemple #18
0
int m_isfunction (lua_State *L, int index) {
    return lua_isfunction(L, index);
}
Exemple #19
0
/*
args:
    const char *className
    const char *methodName
    LUA_TABLE   args
    const char *sig
*/
int CCLuaJavaBridge::callJavaStaticMethod(lua_State *L)
{
    if (!lua_isstring(L, -4) || !lua_isstring(L, -3)  || !lua_istable(L, -2) || !lua_isstring(L, -1))
    {
    	lua_pushboolean(L, 0);
    	lua_pushinteger(L, LUAJ_ERR_INVALID_SIGNATURES);
    	return 2;
    }

    LOGD("%s", "CCLuaJavaBridge::callJavaStaticMethod(lua_State *L)");

    const char *className  = lua_tostring(L, -4);
    const char *methodName = lua_tostring(L, -3);
    const char *methodSig  = lua_tostring(L, -1);
    CallInfo call(className, methodName, methodSig);

    if (!call.isValid())
    {
    	LOGD("CCLuaJavaBridge::callJavaStaticMethod(\"%s\", \"%s\", args, \"%s\") CHECK FAILURE, ERROR CODE: %d",
    			className, methodName, methodSig, call.getErrorCode());

        lua_pushboolean(L, 0);
        lua_pushinteger(L, call.getErrorCode());
    	return 2;
    }

    // check args
    lua_pop(L, 1);													/* L: args */
    int count = fetchArrayElements(L, -1);                      	/* L: args e1 e2 e3 e4 ... */
    jvalue *args = NULL;
    if (count > 0)
    {
	    args = new jvalue[count];
	    for (int i = count - 1; i >= 0; --i)
	    {
	        int index = -count + i;
	        switch (call.argumentTypeAtIndex(i))
	        {
	            case TypeInteger:
	            	if (lua_isfunction(L, -1))
	            	{
	                    args[i].i = retainLuaFunction(L, -1, NULL);
	            	}
	            	else
	            	{
	            		args[i].i = (int)lua_tonumber(L, -1);
	            	}
	                break;

	            case TypeFloat:
	                args[i].f = lua_tonumber(L, -1);
	                break;

	            case TypeBoolean:
	                args[i].z = lua_toboolean(L, -1) != 0 ? JNI_TRUE : JNI_FALSE;
	                break;
                case TypeVector:
                    args[i].l = CCLuaJavaBridge::checkVector(L);
                    break;
                case TypeMap:
                    args[i].l = CCLuaJavaBridge::checkHashMap(L);
                    break;
                case TypeArrayList:
                    args[i].l = CCLuaJavaBridge::checkArrayList(L);
                    break;
	            case TypeString:
	            default:
	                args[i].l = call.getEnv()->NewStringUTF(lua_tostring(L, -1));
	                break;
	        }
            lua_pop(L, 1);
	    }
	    //lua_pop(L, count);                               			/* L: args */
    }

    bool success = args ? call.executeWithArgs(args) : call.execute();
    if (args) delete []args;

    if (!success)
    {
    	LOGD("CCLuaJavaBridge::callJavaStaticMethod(\"%s\", \"%s\", args, \"%s\") EXECUTE FAILURE, ERROR CODE: %d",
    			className, methodName, methodSig, call.getErrorCode());

    	lua_pushboolean(L, 0);
    	lua_pushinteger(L, call.getErrorCode());
    	return 2;
    }

	LOGD("CCLuaJavaBridge::callJavaStaticMethod(\"%s\", \"%s\", args, \"%s\") SUCCESS",
			className, methodName, methodSig);

	lua_pushboolean(L, 1);
	return 1 + call.pushReturnValue(L);
}
Exemple #20
0
// Lua: server:listen(port, addr, function(c)), socket:listen(port, addr)
int net_listen( lua_State *L ) {
  lnet_userdata *ud = net_get_udata(L);
  if (!ud || ud->type == TYPE_TCP_CLIENT)
    return luaL_error(L, "invalid user data");
  if (ud->pcb)
    return luaL_error(L, "already listening");
  int stack = 2;
  uint16_t port = 0;
  const char *domain = "0.0.0.0";
  if (lua_isnumber(L, stack))
    port = lua_tointeger(L, stack++);
  if (lua_isstring(L, stack)) {
    size_t dl = 0;
    domain = luaL_checklstring(L, stack++, &dl);
  }
  ip_addr_t addr;
  if (!ipaddr_aton(domain, &addr))
    return luaL_error(L, "invalid IP address");
  if (ud->type == TYPE_TCP_SERVER) {
    if (lua_isfunction(L, stack) || lua_islightfunction(L, stack)) {
      lua_pushvalue(L, stack++);
      luaL_unref(L, LUA_REGISTRYINDEX, ud->server.cb_accept_ref);
      ud->server.cb_accept_ref = luaL_ref(L, LUA_REGISTRYINDEX);
    } else {
      return luaL_error(L, "need callback");
    }
  }
  err_t err = ERR_OK;
  switch (ud->type) {
    case TYPE_TCP_SERVER:
      ud->tcp_pcb = tcp_new();
      if (!ud->tcp_pcb)
        return luaL_error(L, "cannot allocate PCB");
      ud->tcp_pcb->so_options |= SOF_REUSEADDR;
      err = tcp_bind(ud->tcp_pcb, &addr, port);
      if (err == ERR_OK) {
        tcp_arg(ud->tcp_pcb, ud);
        struct tcp_pcb *pcb = tcp_listen(ud->tcp_pcb);
        if (!pcb) {
          err = ERR_MEM;
        } else {
          ud->tcp_pcb = pcb;
          tcp_accept(ud->tcp_pcb, net_accept_cb);
        }
      }
      break;
    case TYPE_UDP_SOCKET:
      ud->udp_pcb = udp_new();
      if (!ud->udp_pcb)
        return luaL_error(L, "cannot allocate PCB");
      udp_recv(ud->udp_pcb, net_udp_recv_cb, ud);
      err = udp_bind(ud->udp_pcb, &addr, port);
      break;
  }
  if (err != ERR_OK) {
    switch (ud->type) {
      case TYPE_TCP_SERVER:
        tcp_close(ud->tcp_pcb);
        ud->tcp_pcb = NULL;
        break;
      case TYPE_UDP_SOCKET:
        udp_remove(ud->udp_pcb);
        ud->udp_pcb = NULL;
        break;
    }
    return lwip_lua_checkerr(L, err);
  }
  if (ud->self_ref == LUA_NOREF) {
    lua_pushvalue(L, 1);
    ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  }
  return 0;
}
Exemple #21
0
int LuaStack::executeFunctionReturnArray(int handler,int numArgs,int numResults,__Array& resultArray)
{
    int top = lua_gettop(_state);
    if (pushFunctionByHandler(handler))                 /* L: ... arg1 arg2 ... func */
    {
        if (numArgs > 0)
        {
            lua_insert(_state, -(numArgs + 1));         /* L: ... func arg1 arg2 ... */
        }
        int functionIndex = -(numArgs + 1);
        if (!lua_isfunction(_state, functionIndex))
        {
            CCLOG("value at stack [%d] is not function", functionIndex);
            lua_pop(_state, numArgs + 1); // remove function and arguments
            lua_settop(_state,top);
            return 0;
        }
        
        int traceback = 0;
        lua_getglobal(_state, "__G__TRACKBACK__");                         /* L: ... func arg1 arg2 ... G */
        if (!lua_isfunction(_state, -1))
        {
            lua_pop(_state, 1);                                            /* L: ... func arg1 arg2 ... */
        }
        else
        {
            lua_insert(_state, functionIndex - 1);                         /* L: ... G func arg1 arg2 ... */
            traceback = functionIndex - 1;
        }
        
        int error = 0;
        ++_callFromLua;
        error = lua_pcall(_state, numArgs, numResults, traceback);                  /* L: ... [G] ret1 ret2 ... retResults*/
        --_callFromLua;
        if (error)
        {
            if (traceback == 0)
            {
                CCLOG("[LUA ERROR] %s", lua_tostring(_state, - 1));        /* L: ... error */
                lua_pop(_state, 1); // remove error message from stack
            }
            else                                                            /* L: ... G error */
            {
                lua_pop(_state, 2); // remove __G__TRACKBACK__ and error message from stack
            }
            lua_settop(_state,top);
            return 0;
        }
        
        // get return value,don't pass LUA_MULTRET to numResults,
        if (numResults <= 0)
        {
            lua_settop(_state,top);
            return 0;
        }
        
        for (int i = 0 ; i < numResults; i++)
        {
            if (lua_type(_state, -1) == LUA_TBOOLEAN) {
                
                bool value = lua_toboolean(_state, -1);
                resultArray.addObject(Bool::create(value)) ;
                
            }else if (lua_type(_state, -1) == LUA_TNUMBER) {
                
                double value = lua_tonumber(_state, -1);
                resultArray.addObject(Double::create(value));
                
            }else if (lua_type(_state, -1) == LUA_TSTRING) {
                
                const char* value = lua_tostring(_state, -1);
                resultArray.addObject(String::create(value));
                
            }else{
                
                resultArray.addObject(static_cast<Ref*>(tolua_tousertype(_state, -1, nullptr)));
            }
            // remove return value from stack
            lua_pop(_state, 1);                                                /* L: ... [G] ret1 ret2 ... ret*/
        }
        /* L: ... [G]*/
        
        if (traceback)
        {
            lua_pop(_state, 1); // remove __G__TRACKBACK__ from stack      /* L: ... */
        }
    }
    lua_settop(_state,top);
    return 1;
}
Exemple #22
0
// Lua: client:send(data, function(c)), socket:send(port, ip, data, function(s))
int net_send( lua_State *L ) {
  lnet_userdata *ud = net_get_udata(L);
  if (!ud || ud->type == TYPE_TCP_SERVER)
    return luaL_error(L, "invalid user data");
  ip_addr_t addr;
  uint16_t port;
  const char *data;
  size_t datalen = 0;
  int stack = 2;
  if (ud->type == TYPE_UDP_SOCKET) {
    size_t dl = 0;
    port = luaL_checkinteger(L, stack++);
    if (port == 0) return luaL_error(L, "need port");
    const char *domain = luaL_checklstring(L, stack++, &dl);
    if (!domain) return luaL_error(L, "need IP address");
    if (!ipaddr_aton(domain, &addr)) return luaL_error(L, "invalid IP address");
  }
  data = luaL_checklstring(L, stack++, &datalen);
  if (!data || datalen == 0) return luaL_error(L, "no data to send");
  if (lua_isfunction(L, stack) || lua_islightfunction(L, stack)) {
    lua_pushvalue(L, stack++);
    luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_sent_ref);
    ud->client.cb_sent_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  }
  if (ud->type == TYPE_UDP_SOCKET && !ud->pcb) {
    ud->udp_pcb = udp_new();
    if (!ud->udp_pcb)
      return luaL_error(L, "cannot allocate PCB");
    udp_recv(ud->udp_pcb, net_udp_recv_cb, ud);
    ip_addr_t laddr = {0};
    err_t err = udp_bind(ud->udp_pcb, &laddr, 0);
    if (err != ERR_OK) {
      udp_remove(ud->udp_pcb);
      ud->udp_pcb = NULL;
      return lwip_lua_checkerr(L, err);
    }
    if (ud->self_ref == LUA_NOREF) {
      lua_pushvalue(L, 1);
      ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX);
    }
  }
  if (!ud->pcb || ud->self_ref == LUA_NOREF)
    return luaL_error(L, "not connected");
  err_t err;
  if (ud->type == TYPE_UDP_SOCKET) {
    struct pbuf *pb = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM);
    if (!pb)
      return luaL_error(L, "cannot allocate message buffer");
    pbuf_take(pb, data, datalen);
    err = udp_sendto(ud->udp_pcb, pb, &addr, port);
    pbuf_free(pb);
    if (ud->client.cb_sent_ref != LUA_NOREF) {
      lua_rawgeti(L, LUA_REGISTRYINDEX, ud->client.cb_sent_ref);
      lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref);
      lua_call(L, 1, 0);
    }
  } else if (ud->type == TYPE_TCP_CLIENT) {
    err = tcp_write(ud->tcp_pcb, data, datalen, TCP_WRITE_FLAG_COPY);
  }
  return lwip_lua_checkerr(L, err);
}
Exemple #23
0
int CCLuaEngine::executeFunctionByRefID(int nHandler, int numArgs)
{
    lua_pushstring(m_state, TOLUA_REFID_FUNC_MAPPING);
    lua_rawget(m_state, LUA_REGISTRYINDEX);                         /* stack: ... refid_func */
    lua_pushinteger(m_state, nHandler);                        /* stack: ... refid_func refid */
    lua_rawget(m_state, -2);                                        /* stack: ... refid_func func */

    if (!lua_isfunction(m_state, -1))
    {
        CCLOG("[LUA ERROR] function refid '%d' does not reference a Lua function", nHandler);
        lua_pop(m_state, 2 + numArgs);
        return 0;
    }

    if (numArgs > 0)
    {
        // [a1] [a2] refid_func func
        //  -4   -3     -2       -1
        // [a1] [a2] refid_func func [a1]
        //  -5   -4     -3       -2   -1
        int lo = -2 - numArgs;
        for (int i = 0; i < numArgs; i++)
        {
            tolua_pushvalue(m_state, lo);                           /* stack: ... refid_func func (...) */
        }
    }

    int error = 0;
    try
    {
        error = lua_pcall(m_state, numArgs, 1, 0);                  /* stack: ... refid_func ret */
    }
    catch (exception& e)
    {
        CCLOG("[LUA ERROR] lua_pcall(%d) catch C++ exception: %s", nHandler, e.what());
        lua_settop(m_state, 0);
        return 0;
    }
    catch (...)
    {
        CCLOG("[LUA ERROR] lua_pcall(%d) catch C++ unknown exception.", nHandler);
        lua_settop(m_state, 0);
        return 0;
    }
    if (error)
    {
        CCLOG("[LUA ERROR] %s", lua_tostring(m_state, - 1));
        lua_pop(m_state, 2 + numArgs); // clean error message
        return 0;
    }

    // get return value
    int ret = 0;
    if (lua_isnumber(m_state, -1))
    {
        ret = lua_tointeger(m_state, -1);
    }
    else if (lua_isboolean(m_state, -1))
    {
        ret = lua_toboolean(m_state, -1);
    }

    lua_pop(m_state, 2 + numArgs);
    return ret;
}
Exemple #24
0
int serialize_data(lua_sandbox* lsb, int index, output_data* output)
{
    output->m_pos = 0;
    switch (lua_type(lsb->m_lua, index)) {
    case LUA_TNUMBER:
        if (dynamic_snprintf(output, "%0.9g",
                             lua_tonumber(lsb->m_lua, index))) {
            return 1;
        }
        break;
    case LUA_TSTRING:
        // The stack is cleaned up on failure by preserve_global_data
        // but for clarity it is incrementally cleaned up anyway.
        lua_checkstack(lsb->m_lua, 4);
        lua_getglobal(lsb->m_lua, "string");
        if (!lua_istable(lsb->m_lua, -1)) {
            snprintf(lsb->m_error_message, ERROR_SIZE,
                     "serialize_data cannot access the string table");
            lua_pop(lsb->m_lua, 1); // Remove bogus string table.
            return 1;
        }
        lua_getfield(lsb->m_lua, -1, "format");
        if (!lua_isfunction(lsb->m_lua, -1)) {
            snprintf(lsb->m_error_message, ERROR_SIZE,
                     "serialize_data cannot access the string format function");
            lua_pop(lsb->m_lua, 2); // Remove the bogus format function and
                                    // string table.
            return 1;
        }
        lua_pushstring(lsb->m_lua, "%q");
        lua_pushvalue(lsb->m_lua, index - 3);
        if (lua_pcall(lsb->m_lua, 2, 1, 0) == 0) {
            if (dynamic_snprintf(output, "%s", lua_tostring(lsb->m_lua, -1))) {
                lua_pop(lsb->m_lua, 1); // Remove the string table.
                return 1;
            }
        } else {
            snprintf(lsb->m_error_message, ERROR_SIZE,
                     "serialize_data '%s'", lua_tostring(lsb->m_lua, -1));
            lua_pop(lsb->m_lua, 2); // Remove the error message and the string
                                    // table.
            return 1;
        }
        lua_pop(lsb->m_lua, 2); // Remove the pcall result and the string table.
        break;
    case LUA_TNIL:
        if (dynamic_snprintf(output, "nil")) {
            return 1;
        }
        break;
    case LUA_TBOOLEAN:
        if (dynamic_snprintf(output, "%s",
                             lua_toboolean(lsb->m_lua, index)
                             ? "true" : "false")) {
            return 1;
        }
        break;
    default:
        snprintf(lsb->m_error_message, ERROR_SIZE,
                 "serialize_data cannot preserve type '%s'",
                 lua_typename(lsb->m_lua, lua_type(lsb->m_lua, index)));
        return 1;
    }
    return 0;
}
Exemple #25
0
/// Wrapper around lua_isfunction.
///
/// \param index The second parameter to lua_isfunction.
///
/// \return The return value of lua_isfunction.
bool
lutok::state::is_function(const int index)
{
    return lua_isfunction(_pimpl->lua_state, index);
}
Exemple #26
0
void Script::callFunction(const char *func,const char *sig,...)
{
	va_list vl;
	int narg,nres;

	va_start(vl,sig);
	lua_getglobal(mThreadState,func);

	if(lua_isfunction(mThreadState,-1))
	{
		narg = 0;

		while(*sig)
		{
			switch (*sig++)
			{

				case 'd':	lua_pushnumber(mThreadState,va_arg(vl,double));	break;
				case 'i':	lua_pushnumber(mThreadState,va_arg(vl,int));	break;
				case 's':  	lua_pushstring(mThreadState,va_arg(vl,char *));	break;

				case '>':	goto endwhile;	break;

				default:	break;
			}

			narg++;

			luaL_checkstack(mThreadState,1,"too many arguments");
		}

		endwhile:

		nres = strlen(sig);

		if(lua_pcall(mThreadState,narg,nres,0) != 0)
		{
			_formatError();
			gLogger->logMsgF("ScriptingEngine::callFunction Runtime Error: %s",MSG_NORMAL,mLastError);
		}

		nres = -nres;

		while(*sig)
		{
			switch (*sig++)
			{
				case 'd':
				{
					if(!lua_isnumber(mThreadState,nres))
					{
						_formatError();
						gLogger->logMsgF("ScriptingEngine::callFunction wrong result type: %s",MSG_NORMAL,mLastError);
					}

					*va_arg(vl,double *) = lua_tonumber(mThreadState,nres);
				}
				break;

				case 'i':
				{
					if(!lua_isnumber(mThreadState,nres))
					{
						_formatError();
						gLogger->logMsgF("ScriptingEngine::callFunction wrong result type: %s",MSG_NORMAL,mLastError);
					}

					*va_arg(vl,int*) = (int)lua_tonumber(mThreadState,nres);
				}
				break;

				case 's':
				{
					if(!lua_isstring(mThreadState,nres))
					{
						_formatError();
						gLogger->logMsgF("ScriptingEngine::callFunction wrong result type: %s",MSG_NORMAL,mLastError);
					}

					*va_arg(vl,const char **) = lua_tostring(mThreadState,nres);
				}
				break;

				default:
				{
					_formatError();
					gLogger->logMsgF("ScriptingEngine::callFunction invalid option: %s",MSG_NORMAL,mLastError);
				}
				break;
			}

			nres++;
		}
	}

	va_end(vl);
}
int dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) {
    int consumed_bytes = tvb->length;
    lua_pinfo = pinfo;
    lua_tvb = tvb;

    lua_tree = g_malloc(sizeof(struct _wslua_treeitem));
    lua_tree->tree = tree;
    lua_tree->item = proto_tree_add_text(tree,tvb,0,0,"lua fake item");
    lua_tree->expired = FALSE;
    PROTO_ITEM_SET_HIDDEN(lua_tree->item);

    /*
     * almost equivalent to Lua:
     * dissectors[current_proto](tvb,pinfo,tree)
     */

    lua_settop(L,0);

    lua_rawgeti(L, LUA_REGISTRYINDEX, lua_dissectors_table_ref);

    lua_pushstring(L, pinfo->current_proto);
    lua_gettable(L, -2);

    lua_remove(L,1);


    if (lua_isfunction(L,1)) {

        push_Tvb(L,tvb);
        push_Pinfo(L,pinfo);
        push_TreeItem(L,lua_tree);

        if  ( lua_pcall(L,3,1,0) ) {
            const gchar* error = lua_tostring(L,-1);

            proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua Error: %s",error);
            expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_ERROR ,"Lua Error");
        } else {

            /* if the Lua dissector reported the consumed bytes, pass it to our caller */
            if (lua_isnumber(L, -1)) { 
                /* we got the consumed bytes or the missing bytes as a negative number */
                consumed_bytes = (int) lua_tonumber(L, -1);
                lua_pop(L, 1);
            }
        }

    } else {
        proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua Error: did not find the %s dissector"
                                             " in the dissectors table",pinfo->current_proto);

        expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_ERROR ,"Lua Error");
    }

    register_frame_end_routine(lua_frame_end);

    lua_pinfo = NULL;
    lua_tree = NULL;
    lua_tvb = NULL;

    return consumed_bytes;

}
ngx_int_t
ngx_http_lua_content_handler_file(ngx_http_request_t *r)
{
    lua_State                       *L;
    ngx_int_t                        rc;
    u_char                          *script_path;
    ngx_http_lua_main_conf_t        *lmcf;
    ngx_http_lua_loc_conf_t         *llcf;
    char                            *err;
    ngx_str_t                        eval_src;

    llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);

    if (ngx_http_complex_value(r, &llcf->content_src, &eval_src) != NGX_OK) {
        return NGX_ERROR;
    }

    script_path = ngx_http_lua_rebase_path(r->pool, eval_src.data,
            eval_src.len);

    if (script_path == NULL) {
        return NGX_ERROR;
    }

    lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
    L = lmcf->lua;

    /*  load Lua script file (w/ cache)        sp = 1 */
    rc = ngx_http_lua_cache_loadfile(L, script_path, llcf->content_src_key,
            &err, llcf->enable_code_cache ? 1 : 0);

    if (rc != NGX_OK) {
        if (err == NULL) {
            err = "unknown error";
        }

        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                "Failed to load Lua inlined code: %s", err);

        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }

    /*  make sure we have a valid code chunk */
    assert(lua_isfunction(L, -1));

    rc = ngx_http_lua_content_by_chunk(L, r);

    if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
        return rc;
    }

    if (rc == NGX_DONE) {
        return NGX_DONE;
    }

    if (rc == NGX_AGAIN) {
#if defined(nginx_version) && nginx_version >= 8011
        r->main->count++;
#endif
        return NGX_DONE;
    }

    return NGX_OK;
}
Exemple #29
0
int32 interpreter::call_coroutine(int32 f, uint32 param_count, uint32 * yield_value, uint16 step) {
    *yield_value = 0;
    if (!f) {
        sprintf(pduel->strbuffer, "\"CallCoroutine\": attempt to call a null function");
        handle_message(pduel, 1);
        params.clear();
        return OPERATION_FAIL;
    }
    if (param_count != params.size()) {
        sprintf(pduel->strbuffer, "\"CallCoroutine\": incorrect parameter count");
        handle_message(pduel, 1);
        params.clear();
        return OPERATION_FAIL;
    }
    coroutine_map::iterator it;
    it = coroutines.find(f);
    lua_State* rthread;
    if (it == coroutines.end()) {
        rthread = lua_newthread(lua_state);
        function2value(rthread, f);
        if(!lua_isfunction(rthread, -1)) {
            sprintf(pduel->strbuffer, "\"CallCoroutine\": attempt to call an error function");
            handle_message(pduel, 1);
            params.clear();
            return OPERATION_FAIL;
        }
        call_depth++;
        coroutines.insert(make_pair(f, rthread));
    } else {
        rthread = it->second;
        if(step == 0) {
            sprintf(pduel->strbuffer, "recursive event trigger detected.");
            handle_message(pduel, 1);
            params.clear();
            call_depth--;
            if(call_depth == 0)
                pduel->release_script_group();
            return OPERATION_FAIL;
        }
    }
    push_param(rthread, true);
    current_state = rthread;
    int32 result = lua_resume(rthread, 0, param_count);
    if (result == 0) {
        coroutines.erase(f);
        if(yield_value)
            *yield_value = lua_isboolean(rthread, -1) ? lua_toboolean(rthread, -1) : lua_tointeger(rthread, -1);
        current_state = lua_state;
        call_depth--;
        if(call_depth == 0)
            pduel->release_script_group();
        return COROUTINE_FINISH;
    } else if (result == LUA_YIELD) {
        return COROUTINE_YIELD;
    } else {
        coroutines.erase(f);
        sprintf(pduel->strbuffer, lua_tostring(rthread, -1));
        handle_message(pduel, 1);
        lua_pop(rthread, 1);
        current_state = lua_state;
        call_depth--;
        if(call_depth == 0)
            pduel->release_script_group();
        return COROUTINE_ERROR;
    }
}
lua_State *script_cache_get_script(server *srv, connection *con, script_cache *cache, buffer *name) {
	size_t i;
	script *sc = NULL;
	stat_cache_entry *sce;

	for (i = 0; i < cache->used; i++) {
		sc = cache->ptr[i];

		if (buffer_is_equal(name, sc->name)) {
			sc->last_used = time(NULL);

			/* oops, the script failed last time */

			if (lua_gettop(sc->L) == 0) break;

			if (HANDLER_ERROR == stat_cache_get_entry(srv, con, sc->name, &sce)) {
				lua_pop(sc->L, 1); /* pop the old function */
				break;
			}

			if (!buffer_is_equal(sce->etag, sc->etag)) {
				/* the etag is outdated, reload the function */
				lua_pop(sc->L, 1);
				break;
			}

			assert(lua_isfunction(sc->L, -1));
			lua_pushvalue(sc->L, -1); /* copy the function-reference */

			return sc->L;
		}

		sc = NULL;
	}

	/* if the script was script already loaded but either got changed or
	 * failed to load last time */
	if (sc == NULL) {
		sc = script_init();

		if (cache->size == 0) {
			cache->size = 16;
			cache->ptr = malloc(cache->size * sizeof(*(cache->ptr)));
		} else if (cache->used == cache->size) {
			cache->size += 16;
			cache->ptr = realloc(cache->ptr, cache->size * sizeof(*(cache->ptr)));
		}

		cache->ptr[cache->used++] = sc;

		buffer_copy_string_buffer(sc->name, name);

		sc->L = luaL_newstate();
		luaL_openlibs(sc->L);
	}

	sc->last_used = time(NULL);

	if (0 != luaL_loadfile(sc->L, name->ptr)) {
		/* oops, an error, return it */

		return sc->L;
	}

	if (HANDLER_GO_ON == stat_cache_get_entry(srv, con, sc->name, &sce)) {
		buffer_copy_string_buffer(sc->etag, sce->etag);
	}

	/**
	 * pcall() needs the function on the stack
	 *
	 * as pcall() will pop the script from the stack when done, we have to
	 * duplicate it here
	 */
	assert(lua_isfunction(sc->L, -1));
	lua_pushvalue(sc->L, -1); /* copy the function-reference */

	return sc->L;
}