Lua way to explore https:https://cdn.v2ex.com/navatar/8d5e/957f/147_normal.png?m=1586483655 https:https://cdn.v2ex.com/navatar/8d5e/957f/147_large.png?m=1586483655 2025-05-15T06:32:46Z Copyright © 2010-2018, V2EX 使用 Android Lua Helper 在 VSCODE 中调试安卓 Lua 应用 tag:www.v2ex.com,2025-05-15:/t/1131968 2025-05-15T06:32:46Z 2025-05-15T06:32:46Z riseworlds member/riseworlds 一、VSCODE 与 Android Lua Helper 的功能特点

Visual Studio Code( VSCODE )是一款功能强大的代码编辑器,它以其高度可定制的界面、强大的扩展生态系统、流畅的性能表现以及对众多编程语言的天然支持而备受开发者青睐。在众多的开发场景中,VSCODE 都展现出了卓越的性能和灵活性。 Lua 作为一种轻量级的脚本语言,在游戏开发、移动应用开发等领域有着广泛的应用。然而,由于 Lua 是一门小众语言,相关的开发工具并不像主流语言那样完善。Android Lua Helper 插件的出现,为开发者提供了一系列强大的功能,极大地提高了 Lua 代码的开发效率和质量。 Android Lua Helper 插件具有多种功能,如符号定义跳转、代码格式化、符号查找、全局引用查找以及智能代码补全、语法错误检测、Lua 代码片段提示等。这些功能使得开发者在编写 Lua 代码时更加高效和准确。例如,代码补全功能可以大大减少开发者的输入时间,提高开发速度;语法错误检测功能可以帮助开发者及时发现并修复代码中的错误,避免在运行时出现问题。Android Lua Helper插件还拥有低内存消耗和高实时性的优点,即便面对规模庞大的项目,也能流畅运行,毫无卡顿之感。 此外,Android Lua Helper 插件还支持多种 Lua 版本,如 Lua 5.1Lua 5.3,满足了不同项目的需求。插件的不断更新和改进也为开发者提供了更好的开发体验。Android Lua Helper 支持使用安卓 ADB 工具连接手机,实现远程调试,安装卸载应用,截屏到本地,启动scrcpy等。 总之,VSCODEAndroid Lua Helper 的结合为 Android 开发中的 Lua 语言项目提供了强大的支持,使得开发者能够更加高效地进行开发工作。

二、VSCODE 与 Android Lua Helper 的集成

首先,我们需要安装 VSCODE,然后安装 Android Lua Helper 插件。 点击此链接直接在VSCODE中安装,或在 VSCODE 的软件商店安装 Android Lua Helper 插件极为简便。首先打开 VSCODE,目光聚焦于侧边栏底部,那里有一个扩展商店入口图标,形似方块。轻轻点击此图标,便会开启一个全新视图,其中罗列着众多插件。接着,在搜索栏中输入 Android Lua Helper 并按下回车键。随后,在搜索结果里找到 Android Lua Helper 插件,点击 “安装” 按钮。待安装完成,再点击 “重新加载” 按钮以启用该插件。 插件安装完成后,我们需要配置 VSCODE,以支持 Android Lua Helper 的调试。

三、调试配置全流程

(一)创建 launch.json 文件

在安装好 Android Lua Helper 插件后,点击运行按钮,接着点击创建 launch.json,选择调试器时,我们要选择 AndroidLuaHelper:Debug。这个过程就像是为我们的调试之旅搭建起了一座桥梁。它为后续的调试工作提供了基础的配置框架,确保我们能够顺利地进行 Lua 代码的调试。 1launch.json 文件中,我们添加了如下内容:4

(二)添加LuaPanda.lua文件到项目中

按快捷键Ctrl+Shift+P,输入AndroidLuaHelper:Copy Debug file,再按回车键。 选择合适的项目目录后LuaPanda.lua文件会自动复制到目录下,并命名为 LuaPanda.lua2

(三)插入调试代码到合适的文件

在合适的文件(如:main.lua)中,按快捷键Ctrl+Shift+P,输入AndroidLuaHelper:Insert Debugger Code,再按回车键。 插入如下代码: 3 默认端口为 8818,与 launch.json 文件中的"connectionPort"要一致。

(四)连接到安卓手机

Android Lua Helper 会自动检测手机,如果检测不到,则需要手动输入。 点击边栏上的安卓按钮,接着点击 Input Device IP Address按钮,或按快捷键Ctrl+Shift+P,输入AndroidLuaHelper:Input Device IP Address,再按回车键,依次输入 IP 地址和端口号。 5

(五)运行

在需要的位置点入断点,点击运行按钮,选择启动调试,调试器会进入监听模式,在手机上运行 App 即可进行调试。

]]> skynet 怎么给 mysql drive 增加对 caching_sha2_password 的支持 tag:www.v2ex.com,2025-03-10:/t/1117310 2025-03-10T08:54:05Z 2025-03-10T09:14:03Z awanganddong member/awanganddong mysql 用的是 8.0 。插件是 caching_sha2_password

skynet 默认扩展不支持这种模式。 所以想请教下这种怎么改写。 也看了 https://github.com/openresty/lua-resty-mysql 源码。还是一脑袋浆糊。

 if auth_plugin == "caching_sha2_password" then token = _compute_caching_sha2_password_token(password, scramble) else token = _compute_token(password, scramble) end local client_flags = 260047 local req = strpack("<I4I4c1c23zs1z", client_flags, self._max_packet_size, strchar(charset), strrep("\0", 23), user, token, database ) local authpacket = _compose_packet(self, req) sockchannel:request(authpacket, dispatch_resp) if on_connect then on_connect(self) end function _compute_caching_sha2_password_token(password, scramble) -- 1. Compute SHA-256 hash of the password local password_hash = sha.sha256(password) -- 2. Concatenate the hash with the scramble local combined = sha.sha256(sha.sha256(password_hash .. scramble)) local token = xor(password_hash, combined) -- 3. Compute SHA-256 hash of the combined value return token end 下边是我检索 chatgpt 来的,但是不对。请教下大家。 
]]>
奇怪的小问题 tag:www.v2ex.com,2024-05-04:/t/1037628 2024-05-04T02:19:20Z 2024-05-03T18:19:20Z roker member/roker local st=(string.find(inputString,"]",-1))
上面能正常匹配。
local end=(string.find(inputString,"[",-1))
然后就报错 string = '[string "..."]:17: malformed pattern (missing ']')'
google 说需要把"["把[转义成正则表达式的[加%
local end=(string.find(inputString,"%[",-1))
然后 end 的值为 nil ,依然没有获取到,这个是怎么回事 ]]>
Lua 代码上的优化,相互学习一下 tag:www.v2ex.com,2023-07-22:/t/958829 2023-07-22T09:20:12Z 2023-07-23T03:41:53Z jetkeey member/jetkeey

背景

我是一名 Unity3D 的前端开发。公司的项目大部分是用 C# + xLua 的框架,MMORPG 类型的游戏。不可否认的 Lua 的技术还是非常成熟的。

疑惑

在工作中项目中,Lua 能用到的什么优化方法呢?我几乎想不到,完全没有思路。也不知道从何下手。平时公司里也没有什么大佬会告诉我。所以想请教下社区的大佬们,请问您知道的 lua 优化有哪些呢?谢谢您

目的

我觉得像我这样的小白应该不少,既然有相同的疑问,我也想通过这个帖子,可能相互学习一下。

谢谢您!

]]>
openresty + lua 这个地方怎么写 tag:www.v2ex.com,2023-06-20:/t/950443 2023-06-20T12:02:43Z 2023-06-20T12:02:43Z awanganddong member/awanganddong lua-resty-upstream-healthcheck lua-resty-balancer

这两个插件是负载均衡和健康检测。组合到一块我不知道怎么写了。

 upstream webserver { server 127.0.0.1:12354; server 127.0.0.1:12355; server 127.0.0.1:12356 backup; } upstream webserver { server 127.0.0.1; balancer_by_lua_block { local b = require "ngx.balancer" local swrr_up = package.loaded.my_swrr_up -- Note that SWRR picks the first server randomly local server = swrr_up:find() assert(b.set_current_peer(server)) } } 
]]>
求一份 lua 入门教程 tag:www.v2ex.com,2022-11-19:/t/896453 2022-11-19T10:08:21Z 2022-11-19T14:00:22Z kiduu member/kiduu 最近想学 OpenResty 然后离不开 lua ,所以想求一份入门级的教程,也不用多深入,学完能在搜索引擎的帮助下编写一些基础的脚本就行。 最好几个小时就能照猫画虎就行。

]]>
有关 Lua 调用 C++ 编译动态库程序 tag:www.v2ex.com,2022-01-06:/t/826528 2022-01-06T03:08:39Z 2022-01-06T07:22:26Z kanhongj member/kanhongj 主要目标

希望能够将 cpp 文件编译成动态库, 以 lua 作为主要运行逻辑(main 函数)

希望解决的问题

  1. 刚入门 Lua 不太明白,若编译了一个 cpp 文件里包含了一个 Worker 对象,Lua 中如何调用生成这个对象并根据公有函数对私有变量进行操作。
  2. 查找到的一些示例代码,大多是将 main 逻辑放在 cpp 文件里,生成元表作为全局变量传入 Lua 脚本进行操作。但是将 Lua 作为程序运行入口,C++ 库作为辅助函数,又该如何操作。
  3. Lua 调试工具各位 Lua 大佬能否介绍一下,或者推荐一些调试方法,lua 的 debug 调试使用我还是有点懵。

自身尝试代码

稍微有点多,感谢耐心观看

classstudy.h

#pragma once extern "C" { #include "lua.h" #include "lualib.h" #include "lauxlib.h" } #include <string> class Worker{ public: Worker(); ~Worker(); int SetName(std::string &name); int SetAge(int &age); int SetHight(float &hight); std::string GetName(); int GetAge(); float GetHight(); private: std::string name; int age; float hight; }; extern "C" int luaopen_cstudy(lua_State *L); 

classstudy.cpp

#include "classstudy.h" #include <iostream> /* Class Worker 的函数定义省略 */ static int CreateNewWorker(lua_State *L){ //ligth_userdata // int n = luaL_checkany(L, 1); Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*)); *w1 = new Worker(); if(luaL_getmetatable(L, "WorkerClass") == false){ printf("getmetatable nil\n"); } lua_setmetatable(L, -2); return 1; } static int SetWorkerName(lua_State *L){ luaL_checktype(L, -1, LUA_TSTRING); std::string var_name = lua_tostring(L, -1); printf("%s\n", var_name.c_str()); Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*)); luaL_argcheck(L, w1 != NULL, 1, "invalid user data"); (*w1)->SetName(var_name); return 0; } static int SetWorkerAge(lua_State *L){ luaL_checktype(L, -1, LUA_TNUMBER); int var_age = lua_tointeger(L, -1); Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*)); luaL_argcheck(L, w1 != NULL, 1, "invalid user data"); (*w1)->SetAge(var_age); return 0; } static int SetWorkerHight(lua_State *L){ luaL_checktype(L, -1, LUA_TNUMBER); float var_hight = lua_tonumber(L, -1); Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*)); luaL_argcheck(L, w1 != NULL, 1, "invalid user data"); (*w1)->SetHight(var_hight); return 0; } static int GetWorkerInfo(lua_State *L){ Worker **w1 = (Worker**)lua_newuserdata(L, sizeof(Worker*)); luaL_argcheck(L, w1 != NULL, 1, "invalid user data"); printf("Name: %s\n", ((*w1)->GetName()).c_str()); printf("Age: %d\n", (*w1)->GetAge()); printf("Hight: %f\n", (*w1)->GetHight()); return 0; } static int DestoryInfo(lua_State* L) { // 释放对象 delete *(Worker**)lua_topointer(L, 1); return 0; } const static luaL_Reg mylib[] = { // {"NewWorker", CreateNewWorker}, {"SetName", SetWorkerName}, {"SetAge", SetWorkerAge}, {"SetHight", SetWorkerHight}, {"PrintInfo", GetWorkerInfo}, {NULL,NULL} }; int luaopen_cstudy(lua_State *L){ // C\++对象 = 私有数据 + 类(公共数据 + 公共方法) // Lua Table = 私有数据 + 元表(元数据 + 元函数) // luaL_newlib(L, mylib); lua_pushcfunction(L, CreateNewWorker); // 注册用于创建类的全局函数 lua_setglobal(L, "CWorker"); luaL_newmetatable(L, "WorkerClass"); // 设置自身 lua_pushstring(L, "__gc"); lua_pushcfunction(L, DestoryInfo); lua_settable(L, -3); // 设置元表 lua_pushstring(L, "__index"); // 设置元表为自己 lua_pushvalue(L, -2); lua_settable(L, -3); lua_pushstring(L, "SetName"); lua_pushcfunction(L, SetWorkerName); lua_settable(L, -3); lua_pushstring(L, "SetAge"); lua_pushcfunction(L, SetWorkerAge); lua_settable(L, -3); lua_pushstring(L, "SetHight"); lua_pushcfunction(L, SetWorkerHight); lua_settable(L, -3); lua_pushstring(L, "PrintInfo"); lua_pushcfunction(L, GetWorkerInfo); lua_settable(L, -3); // lua_pop(L, 1); return 1; } 

classstudy.lua

local csl = require("cstudy") local Worker = CWorker() print(debug.getregistry()) Worker.SetName("hello") Worker.PrintInfo() -- csl.SetAge(23) -- csl:SetHight(180.0) -- csl:PrintInfo() 
]]>
飞书 + Lua 实现企业级组织架构登录认证 tag:www.v2ex.com,2021-08-14:/t/795748 2021-08-14T03:53:08Z 2021-08-18T13:35:00Z hsowan member/hsowan

飞书是字节跳动旗下一款企业级协同办公软件,本文将介绍如何基于飞书开放平台的身份验证能力,使用 Lua 实现企业级组织架构的登录认证网关。

登录流程

让我们首先看一下飞书第三方网站免登的整体流程:

第一步: 网页后端发现用户未登录,请求身份验证; 第二步: 用户登录后,开放平台生成登录预授权码,302 跳转至重定向地址; 第三步: 网页后端调用获取登录用户身份校验登录预授权码合法性,获取到用户身份; 第四步: 如需其他用户信息,网页后端可调用获取用户信息(身份验证)。

浏览器内网页登录

Lua 实现

飞书接口部分实现

获取应用的 access_token

function _M:get_app_access_token() local url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal/" local body = { app_id = self.app_id, app_secret = self.app_secret } local res, err = http_post(url, body, nil) if not res then return nil, err end if res.status ~= 200 then return nil, res.body end local data = json.decode(res.body) if data["code"] ~= 0 then return nil, res.body end return data["tenant_access_token"] end 

通过回调 code 获取登录用户信息

function _M:get_login_user(code) local app_access_token, err = self:get_app_access_token() if not app_access_token then return nil, "get app_access_token failed: " .. err end local url = "https://open.feishu.cn/open-apis/authen/v1/access_token" local headers = { Authorization = "Bearer " .. app_access_token } local body = { grant_type = "authorization_code", code = code } ngx.log(ngx.ERR, json.encode(body)) local res, err = http_post(url, body, headers) if not res then return nil, err end local data = json.decode(res.body) if data["code"] ~= 0 then return nil, res.body end return data["data"] end 

获取用户详细信息

获取登录用户信息时无法获取到用户的部门信息,故这里需要使用登录用户信息中的 open_id 获取用户的详细信息,同时 user_access_token 也是来自于获取到的登录用户信息。

function _M:get_user(user_access_token, open_id) local url = "https://open.feishu.cn/open-apis/contact/v3/users/" .. open_id local headers = { Authorization = "Bearer " .. user_access_token } local res, err = http_get(url, nil, headers) if not res then return nil, err end local data = json.decode(res.body) if data["code"] ~= 0 then return nil, res.body end return data["data"]["user"], nil end 

登录信息

JWT 登录凭证

我们使用 JWT 作为登录凭证,同时用于保存用户的 open_iddepartment_ids

-- 生成 token function _M:sign_token(user) local open_id = user["open_id"] if not open_id or open_id == "" then return nil, "invalid open_id" end local department_ids = user["department_ids"] if not department_ids or type(department_ids) ~= "table" then return nil, "invalid department_ids" end return jwt:sign( self.jwt_secret, { header = { typ = "JWT", alg = jwt_header_alg, exp = ngx.time() + self.jwt_expire }, payload = { open_id = open_id, department_ids = json.encode(department_ids) } } ) end -- 验证与解析 token function _M:verify_token() local token = ngx.var.cookie_feishu_auth_token if not token then return nil, "token not found" end local result = jwt:verify(self.jwt_secret, token) ngx.log(ngx.ERR, "jwt_obj: ", json.encode(result)) if result["valid"] then local payload = result["payload"] if payload["department_ids"] and payload["open_id"] then return payload end return nil, "invalid token: " .. json.encode(result) end return nil, "invalid token: " .. json.encode(result) end 

使用 Cookie 存储登录凭证

ngx.header["Set-Cookie"] = self.cookie_key .. "=" .. token 

组织架构白名单

我们在用户登录时获取用户的部门信息,或者在用户后续访问应用时解析登录凭证中的部门信息,根据设置的部门白名单,判断用户是否拥有访问应用的权限。

-- 部门白名单配置 _M.department_whitelist = {} function _M:check_user_access(user) if type(self.department_whitelist) ~= "table" then ngx.log(ngx.ERR, "department_whitelist is not a table") return false end if #self.department_whitelist == 0 then return true end local department_ids = user["department_ids"] if not department_ids or department_ids == "" then return false end if type(department_ids) ~= "table" then department_ids = json.decode(department_ids) end for i=1, #department_ids do if has_value(self.department_whitelist, department_ids[i]) then return true end end return false end 

更多网关配置

同时支持 IP 黑名单和路由白名单配置。

-- IP 黑名单配置 _M.ip_blacklist = {} -- 路由白名单配置 _M.uri_whitelist = {} function _M:auth() local request_uri = ngx.var.uri ngx.log(ngx.ERR, "request uri: ", request_uri) if has_value(self.uri_whitelist, request_uri) then ngx.log(ngx.ERR, "uri in whitelist: ", request_uri) return end local request_ip = ngx.var.remote_addr if has_value(self.ip_blacklist, request_ip) then ngx.log(ngx.ERR, "forbided ip: ", request_ip) return ngx.exit(ngx.HTTP_FORBIDDEN) end if request_uri == self.logout_uri then return self:logout() end local payload, err = self:verify_token() if payload then if self:check_user_access(payload) then return end ngx.log(ngx.ERR, "user access not permitted") self:clear_token() return self:sso() end ngx.log(ngx.ERR, "verify token failed: ", err) if request_uri ~= self.callback_uri then return self:sso() end return self:sso_callback() end 

使用

本文就不赘述 OpenResty 的安装了,可以参考我的另一篇文章《在 Ubuntu 上使用源码安装 OpenResty 》

下载

cd /path/to git clone git@github.com:ledgetech/lua-resty-http.git git clone git@github.com:SkyLothar/lua-resty-jwt.git git clone git@github.com:k8scat/lua-resty-feishu-auth.git 

配置

lua_package_path "/path/to/lua-resty-feishu-auth/lib/?.lua;/path/to/lua-resty-jwt/lib/?.lua;/path/to/lua-resty-http/lib/?.lua;/path/to/lua-resty-redis/lib/?.lua;/path/to/lua-resty-redis-lock/lib/?.lua;;"; server { access_by_lua_block { local feishu_auth = require "resty.feishu_auth" feishu_auth.app_id = "" feishu_auth.app_secret = "" feishu_auth.callback_uri = "/feishu_auth_callback" feishu_auth.logout_uri = "/feishu_auth_logout" feishu_auth.app_domain = "feishu-auth.example.com" feishu_auth.jwt_secret = "thisisjwtsecret" feishu_auth.ip_blacklist = {"47.1.2.3"} feishu_auth.uri_whitelist = {"/"} feishu_auth.department_whitelist = {"0"} feishu_auth:auth() } } 

配置说明

应用权限说明

开源

本项目已完成且已在 GitHub 上开源:k8scat/lua-resty-feishu-auth,希望大家可以动动手指点个 Star,表示对本项目的肯定与支持!

]]>
为什么游戏架构要用事件来驱动? tag:www.v2ex.com,2021-03-20:/t/763477 2021-03-20T09:16:44Z 2021-04-05T18:50:31Z yiouejv member/yiouejv 今天总结一下游戏架构中的事件触发机制,游戏架构中为什么需要由事件驱动。

主要是为了解耦,所谓高内聚,低耦合,如果不采用事件驱动的方式,则会像下面这样来写代码。

比如说,游戏内有多个玩法模块,”玩家“在打造装备的时候,可能触发”装备打造 xx 阶的成就“,也可能达成某种条件获得了时装。

这种情景的话,如果没有采用事件驱动的方式来写代码,则需要在装备模块的”升级装备“函数内调用 成就模块 的检查成就达成的函数,还需要调用 时装模块 的检查获得时装的函数。

function equipStrengthen() -- 装备强化逻辑 checkAchievement() -- 成就模块检查成就 checkObtainFashion() -- 时装模块检查获得时装 end 

如果装备关联的模块越来越多的话,就要记得去相关的函数内添加相关的调用。

事件驱动的方式就比较好的处理了这种情况。 如果是用事件驱动的方式来处理以上问题,则我们会这么做,由装备模块发出“装备强化”的事件,成就模块和时装模块只需要监听”装备强化“事件做相应的处理就好了。

在装备强化的模块内只需要一行代码,发出事件,后续如果需要增加关联的模块时,装备模块完全不用动,新模块只要增加监听事件就可以了。

下面我用 lua 实现一个例子:

------------------------------------------------------ 事件触发器 local Listener = {} function Listener:new(channel, callback) local obj = { callback = callback, channel = channel, } setmetatable(obj, self) self.__index = self return obj end local Channel = {} function Channel:new(event) assert(event) local obj = { listeners = {}, event = event, } setmetatable(obj, self) self.__index = self return obj end function Channel:on(callback) listener = Listener:new(self, callback) table.insert(self.listeners, listener) end local EventEmitter = {} function EventEmitter:new() local obj = { events = {}, -- 监听的所有事件 channels = {}, -- event: channel } setmetatable(obj, self) self.__index = self return obj end function EventEmitter:setEvents(events) self.events = events end function EventEmitter:on(event, callback) assert(event) assert(callback) if not self.events[event] then error("not register event: "..event) end local channel = self.channels[event] if not channel then channel = Channel:new(event) self.channels[event] = channel end channel:on(callback) end function EventEmitter:emit(event) if not self.events[event] then error("not register event: "..event) end local channel = self.channels[event] if not channel then return end for _, listener in ipairs(channel.listeners) do listener.callback() end end ----------------------------------------------------- 装备模块 local eventEmitter = EventEmitter:new() eventEmitter:setEvents({ ["equipStrengthen"] = "装备强化", }) function equipStrengthen() -- 装备强化逻辑 eventEmitter:emit("equipStrengthen") end ------------------------------------------------------ 成就模块 function checkAchievement() print('checkAchievement') end eventEmitter:on("equipStrengthen", checkAchievement) -- 成就模块注册监听 ------------------------------------------------------ 时装模块 function checkObtainFashion() print('checkObtainFashion') end eventEmitter:on("equipStrengthen", checkObtainFashion) -- 时装模块注册监听 ------------------------------------------------------------------------------------ function main() equipStrengthen() end main() 

最后输出:

checkAchievement checkObtainFashion 

下面这个图可以有助于理解,

在这里插入图片描述

上述的实现比较简单,主要意思表达出来了,具体的细节可以结合需要再添加就好了。

如果觉得对你有帮助的话请 @程序员杨小哥 点个赞,谢谢!

]]>
vscode 上写 lua 有显示注释的插件吗? tag:www.v2ex.com,2020-03-18:/t/653989 2020-03-18T11:45:09Z 2020-07-01T08:16:46Z wszgrcy member/wszgrcy 对于 vscode 的亲儿子 ts 只要

/**注释*/ let a=1 

然后在鼠标移动到任何使用a变量的地方,都能提示这个变量是什么 那么 lua 有相关插件或者设置吗? 尝试了----[[]]都没用类似ts的效果 不知道有没有大牛研究过这个问题 或者推荐一款能显示注释的 ide

]]>
lua 为什么要使用~=当作不等于运算符? tag:www.v2ex.com,2020-01-19:/t/639128 2020-01-19T04:35:33Z 2020-01-31T03:01:15Z vevlins member/vevlins 很反直觉啊,在数学意义上这不是约等于吗

]]>
请问现在 lua 混淆用什么工具,求常年 lua 的老哥指点 tag:www.v2ex.com,2019-09-27:/t/604925 2019-09-27T11:33:26Z 2019-10-23T16:43:00Z jitongxi member/jitongxi lua 的前景如何? tag:www.v2ex.com,2019-04-01:/t/551062 2019-04-01T23:23:19Z 2019-06-25T08:29:06Z lestat member/lestat core_framework - 基于 libev 的轻量级 lua 网络开发框架 tag:www.v2ex.com,2019-03-27:/t/549291 2019-03-27T13:08:38Z 2019-03-27T09:08:38Z CandyMi member/CandyMi —— 大道至简, 返璞归真.

前言

在发表这篇博文的前夕, 还有一些小伙伴在提问一些以下相关的问题:

  1. 性能怎么样?

  2. 是否容易上手?

  3. 开发目标在哪?

  4. 如何反馈问题?

  5. 对比行业内的 lua 开源项目有何优势?

等等, 以上问题会在本文中一一介绍.


CF 的起因

首先来聊聊情怀这个东西! 相信每一个行业内的从业者都或多或少有过一个梦, 这个梦叫做: "我到时候要开发一个 XXX"!其实作者当初也是一样.

每当半夜(凌晨)在加班、看文档、调试的时候, 总会搜索到一些几年前或十几年前的框架或入门 demo。例如: tinyhttp, 链接的源码是一些同学 fork 的镜像站。

每次看到这些内容或多或少都会激起心中那一丝丝快熄灭的热情, 也许这就是最后对技术的渴望?

就是在动手创建项目之前还反复问过自己是否要做? 能坚持下去么?也许被喷都是一种奢望?

在心里一一回答了这些问题后, 在 2018 年末创建了本项目.

说句实话! 一个网络开发框架最难的不是实现某个功能, 而是从零开始一步一步添砖加瓦的造轮子!

作为一个网络开发框架, 最重要的两个功能肯定是需要的! 定时器库、事件驱动库. 如何抉择?选项有 2 个: libev / libuv .

libev 成熟稳定、轻量级、unix like 支持、容易嵌入; libuv 比 libev 更加优秀,增加了许多功能(线程池、信号、同步、锁等等),封装更加完善, 并且增加了 windows 支持; 

从 cf 框架开发之初选型来看, libuv 绝对是目前最优解. 但是作者偏偏选择了 libev. 也从此开始, 艰辛的底层开发之路就此展开.

首先, 作者不让使用者 C/C++进行实际业务开发! 这样做会让使用者有较高的开发成本与学习成本, 而选择一门较好的脚本语言就显得尤为重要.

作者对Lua还算是稍微熟悉一点, 所以就选了 Lua 作为业务脚本语言。至于 Lua 语言的优势这里就不说了, 网上大把文章夸它的.

现在既然脚本语言已经选定, 那么就开始写代码吧! Let's Lua.


CF 的编写之路

1. 网络层

首先, 我们来看一段 C 封装给 Lua 调用的 API 代码:

LUAMOD_API int luaopen_tcp(lua_State *L){ luaL_checkversion(L); /* 添加 SSL 支持 */ SSL_library_init(); SSL_load_error_strings(); // CRYPTO_set_mem_functions(xmalloc, xrealloc, xfree); // OpenSSL_add_ssl_algorithms(); /* 添加 SSL 支持 */ luaL_newmetatable(L, "__TCP__"); lua_pushstring (L, "__index"); lua_pushvalue(L, -2); lua_rawset(L, -3); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "kv"); lua_rawset(L, -3); luaL_Reg tcp_libs[] = { {"read", tcp_read}, {"write", tcp_write}, {"ssl_read", tcp_sslread}, {"ssl_write", tcp_sslwrite}, {"stop", tcp_stop}, {"start", tcp_start}, {"close", tcp_close}, {"listen", tcp_listen}, {"connect", tcp_connect}, {"ssl_connect", tcp_sslconnect}, {"new", tcp_new}, {"new_ssl", ssl_new}, {"free_ssl", ssl_free}, {"new_server_fd", new_server_fd}, {"new_client_fd", new_client_fd}, {NULL, NULL} }; luaL_setfuncs(L, tcp_libs, 0); luaL_newlib(L, tcp_libs); return 1; } 

以上是 TCP 实现的 C 代码的片段, 有兴趣阅读源码的小伙伴请点击这里;

众所周知 Lua 没有原生的 Socket. 那么就需要框架编写者自己抽象底层逻辑重新实现一套 API.

简单的封装 Lua C 库谁都会, 而且也算不上是什么难事. 但是我们的目的是将底层同步阻塞 Socket hook 为非阻塞, 这时候难点就来了!

大家都知道 libev 是基于 react 模型的事件驱动网络库, 所有注册事件后的业务逻辑都是以回调的形式触发. 那不就变成 node-lua 代码了吗?(笑)

这时候, 作者想了个点子来解决这个问题! 执行流程如下:

  1. 每次需要做一些同步操作的时候, 就调用 C API 注册回调事件.
  1. 为当前注册的所有事件创建一个 Lua 协程保存上下文并让出当前协程执行权.
  1. 等到注册事件被触发后, 调用 C API 恢复协程继续执行.

简单来说就是将 C 层次的异步回调逻辑封装为 Lua 层的同步非阻塞, 保证不因为 IO 问题阻塞线程.

下面提供一段 socket 同步非阻塞的伪代码, 经供参考:

function TCP:recv(bytes) local current_co = co_self() self.read_co = read_ev(function() -- do action -- stop timer_ev -- wakeup(current_co) 恢复执行权 end) self.timer_co = self.timer_ev(function() -- do action -- stop read_ev -- wakeup(current_co) 恢复执行权 end) tcp_start(io, EV_READ, self.read_co) timer_start(timer, 3 秒超时, self.timer_co) return co_yield() -- 让出执行权 end 

一个 Lua 版的 Socket EV_READ 伪代码大致的处理流程如上, 想看实际处理逻辑请看这里

同理, Socket write/connect/listen 等等 API 直接照抄就行(UDP 也大同小异). (其实这里有个小插曲就是 SSL SOCKET 的坑, 但是由于篇幅问题就不说了.)

细心的小伙伴可能发现代码同时注册了 Socket 与 Timer 事件, Socket 非阻塞操作不能解决 read 与 connect 超时的问题. 所以 cf 框架干脆就封装彻底一点.

至此, Socket 算是已经算是基本 hook 与封装完成了. 接下来就可以开始写应用层协议了.

2. 应用层协议

现在 Socket 终于能正常使用了, 那么面临的新问题就又来了。

libev 没有自带异步 dns

dns 都还需要使用者自己封装, 这个坑真是填的无比难受! 好在网络上有前辈实现了 Lua 版的异步 dns, 作者稍微看明白之后就借用了过来封装内部使用.

这样 cf 也算是有了深度定制的异步 dns库了吧!(虽然并不完善, 但是足够使用)

一个网络库是否流行, 基本上就得看生态. 那么协议层的轮子又得造起来:

  1. httpdhttpc
  2. mail
  3. mysql
  4. redis
  5. mqtt
  6. websocket

其中一些协议为各位前辈那边借过来适配后定制的, 简单的协议则是直接花 1-2 小时直接手写出来的。

3. 封装与易用性

为了不让 API 那么封闭与提升 cf 的可用性, 作者决定将 mysql 与 redis 进行初步封装.

封装包括大家常用的功能, 连接池、面向对象操作、无需手动管理 session 生命周期等等. 简化编程思想包袱来提升开发效率.

至于内部 Socket 更是让框架来解决释放问题确保文件描述数量限制的情况下也是可以正常使用. (其实是不喜欢依赖 gc 被动 close fd 与 free 内存)


CF 是啥?

如果你耐心看完了第一部分介绍, 那么你就应该对 cf 有了一个大概的了解.

cf 全称为: CoreFramework, 是一个基于 libev 的 Lua 网络开发框架. 在其内部实现了多种网络协议与第三方库用来帮助使用者进行项目原型的快速开发.

cf 在 httpd 使用上尊崇前、后端分离的解决方案, 仅实现了基本的 view 路由并且不支持 rest 风格的 API 路由. 虽然这样可能会引来宇多人的诟病.

cf 的 httpd 内嵌 websocket 支持, 方便使用者在复用端口的同时也可以享受长连接编写的乐趣.

更多的介绍, 请大家项目地址的Wiki


CF 能做什么?


CF 使用到的技术栈?

传输层: TCP/UDP

会话层: SSL Client 支持

协议层: dns/webocket/http/mqtt/redis/mysql/smtp

工具库: Timer/TASK

第三方库: Libev、openssl/libressl、lua-5.3、jemalloc/tcmalloc(可选)


CF 如何安装?

cf 目前支持绝大部分 Unix like 操作系统, 作者是在 Mac 上进行开发, 所以 Mac 支持是必须的.

cf 测试的 Linux 为 Centos, 所以基本上基于 Linux 内核的操作系统编译后的运行也没什么问题(export 增加 /usr/local/lib)

同时,作者还贴心的为大家做了一个简单 Dockerfile. 文件在项目根目录下, 大家下载直接使用即可。

当然, 如果你不想制作 Dockerfile,也可以使用 Docker 命令直接拉去作者制作好放在 docker hub 的镜像. candymi/cfweb

使用详情与使用方法请参考Docker 安装编译安装


CF 如何运行呢?

测试运行

bash#: ./cfadmin

后台运行

bash#: ./cfadmin

退出

killall cfadmin

ctrl + c


文档在哪?

作者为大家贴心的写了一篇详细到不能再详细的文档, 以此来获取大家的点赞与关注.

作者还为喜欢阅读源码的同学准备了充足的中文注释与英文注释, 结合起来方便大家快速了解 CF 工作方式(中 /英注释结合易于理解一些专属词汇).


回答之前的问题:

Q. 性能怎么样?

A. 性能还不错, 但是具体数值请自行测试.

Q. 是否容易上手?

A. 学习 lua 一小时入门 -> cf 一小时入门

Q. 开这个项目的初衷是什么?

A. 其实在前面已经回答过了.

Q. 开发目标在哪?

A. Wiki 里有TODO

Q. 如何反馈问题?

A. Wiki 里有Q & A

Q. 对比行业内的 lua 开源项目有何优势?

A. CF 对比其它 lua 开发项目更深入改变用户使用习惯! 简化框架上手难度, 将框架都黑盒子透明化. 无需学习复杂的设计模式与理念.

Q. CF 的开发理念是什么?

A. CF 项目的目标不是竞争, 而是明白明白简单为美. 当你习惯了它, 也许你就会上瘾.


使用示例

精彩截图

部署面板

状态面板

pod 日志

希望

也许你正在使用其它开发框架, 但是这不妨碍你对 cf 的督促.

也许你正在试用它, 这不妨碍你与作者沟通你的想法.

也许你正在吐槽它的缺点,请来issue尽情吐槽.

文档与地址

项目文档

项目地址

]]>
如何构建伪视频流服务? 低延时低采样, 基于 OpenResty , HTTP, 内网... tag:www.v2ex.com,2019-01-31:/t/532063 2019-01-31T02:16:01Z 2019-02-20T16:39:08Z ZoomQuiet member/ZoomQuiet 背景

出于各种业务 /硬件 /软件博弈, 最终不得不面对...

分析

设想

功能服务

ngx_lua 应用

讨论

或是有其它更加优雅方案?

感谢大家任何建议.

]]>
TP-Link 官方使用的是开源固件? tag:www.v2ex.com,2018-10-29:/t/502204 2018-10-29T07:10:25Z 2018-10-29T07:07:25Z zealinux member/zealinux 我登录后台页面的时候报错:

POST http://10.0.0.1/cgi-bin/luci/;stok=/login?form=login

出错:

/usr/lib/lua/luci/dispatcher.lua:473: Failed to execute call dispatcher target for entry '/login'. The called action terminated with an exception: /usr/lib/lua/luci/sauth.lua:106: Session data invalid! stack traceback: [C]: in function 'assert' /usr/lib/lua/luci/dispatcher.lua:473: in function 'dispatch' /usr/lib/lua/luci/dispatcher.lua:200: in function </usr/lib/lua/luci/dispatcher.lua:199> 

TP-Link 型号:TL-ER3220G

]]>
表达过去、现在与将来:之将来(1) tag:www.v2ex.com,2018-10-23:/t/500097 2018-10-23T02:18:56Z 2018-10-23T02:15:56Z taowen member/taowen https://zhuanlan.zhihu.com/p/47211041 ]]> 有个问题, lua 平时能用来做做什么 tag:www.v2ex.com,2018-05-09:/t/453574 2018-05-09T14:14:05Z 2018-09-13T09:57:02Z chenqh member/chenqh 听说过 openresty,最近想学下, 所以想用 lua 来做一些脚本之类的,不是 lua 的标准库好像太弱了呀,相比 python

]]>
ngx_lua 遇到的一个小坑 tag:www.v2ex.com,2016-12-09:/t/326493 2016-12-09T09:31:40Z 2017-08-05T20:24:11Z niuoh member/niuoh 通过 nginx_lua 写了一些接口用来返回 json
发现有时候接口访问失败 有一定几率 500
lua 里有 mysql 操作 并且 content_by_lua_file a.lua
这个 a.lua 开头有 dofile()
dofile 的 lua 文件里申明了一些全局变量
怎么解这个坑?

]]>
Lua IDE 各位 V 友,用 lua 作为开发语言用什么 IDE 可以方便代码提示以及调试呢 tag:www.v2ex.com,2016-10-27:/t/315807 2016-10-27T02:15:38Z 2016-10-27T07:59:15Z awolfly9 member/awolfly9 目前是 unity 游戏开发,现在项目要做热更新,基本就是用 C# + Lua ,用 lua 做热更新。但是在开发过程中并没有发现特别好的 lua 的 IDE 。目前用过 VS2015 有关于 lua 的插件,但是代码提示、错误监测以及调试都不给力。然后也用过 Sublime Text 3 也是一样的问题。

请问各位 V 友有没有好的 Lua 的 IDE 推荐,能够有代码提示和像 VS 一样的错误监测(比如拼错了变量能够红色的下划线提示),断点调试有更好,没有也不强求。

]]>
Lua 怎么实现 php strstr() 函数的功能 tag:www.v2ex.com,2016-08-19:/t/300536 2016-08-19T14:22:05Z 2018-01-29T21:06:58Z caola member/caola 最近接触了下 openresty(lua),想弄点自己的功能,但遇到小问题:

local myPosition = string.find(myStr, myValue) --查找字符所在位置 string.sub(myStr, myPosition) --取出找到的字符以及之后的字符串

PS : myValue 可能是任何字符串(有可能是字母数特殊符号和中文的混合字符串), string.find 这函数没法直接查找,得要各种转义,非常蛋疼。

想问一下还能有什么 lua 能高效的实现 php strstr() 功能的方法?

]]>
使用 Sol2 来进行 Lua 绑定 tag:www.v2ex.com,2016-08-10:/t/298443 2016-08-10T09:19:40Z 2016-08-13T17:22:15Z focux member/focux 最近在研究新的 Lua 绑定方式,通过 quick-cocos2d-x 的作者介绍,发现了 Sol 这个开源项目,感觉上要比 tolua++要高大上许多。

详细的信息请关注: github 项目地址sol2 主页

以及本人写的一篇入门使用教程

欢迎大家一起来探讨下,这个项目怎么样,能够运用实际项目当中去。

ps : Sol 的作者对 issue 的响应速度还是蛮快的。

]]>
luarocks 使用上的一些小技巧 tag:www.v2ex.com,2016-06-20:/t/287181 2016-06-20T19:34:20Z 2016-06-20T19:31:20Z ncisoft member/ncisoft 如果想保持系统的干净,不想安装到系统目录,可以这样用 luarocks install luasocket --local

然后用 luarocks path 可以看到环境变量应如何设置,自行拷贝出来 export 即可

每次 install 都要从网上下载源文件,若本地已有源代码,可以这样用 luarocks make local-rockspec --local

缺省 luarocks 编译 c 文件是不带调试信息的,这对于 debug (比如生成火焰图缺乏符号信息尤其不方便),可以这样用 luarocks make local-rockspec --local CC="gcc -g"

>>>参考资料

]]>
正在用 lua 写一个 nginx 防盗链的拓展,遇到了一个问题。 tag:www.v2ex.com,2016-05-22:/t/280459 2016-05-22T09:32:32Z 2016-05-22T11:54:29Z odoooo member/odoooo 大概流程是这样

web 应用层,

md5(IP.文件路径.其他固定信息如 UA 啥的) 存进 redis ,并作为 url 中的 hash 。

nginx 里, ngx.md5(IP.文件路径.其他固定信息如 UA 啥的)对比连接中的 hash 并读取 redis 查到时间戳。

判断时间戳是否失效。

现在想吧 UID 也放进去,不知道有什么好方法能做到避免伪造和验证用户是否登录。只有给 nginx+lua 写 cookie+session 来验证吗?

nginx.lua 上面不方便读 MySQL 数据库的~~.

谢谢诸位,

]]>
9k-18k 宁波 经验 3-5 年 本科及以上 全职 职位诱惑 : 年终奖 出国旅游 顶级办公设备及环境 tag:www.v2ex.com,2016-05-13:/t/278486 2016-05-13T09:48:32Z 2016-05-13T11:20:55Z CMason member/CMason 职位描述

[岗位职责]

[任职要求]

有意者联系: 18758322614

]]>
关于 Lua 的标准库 tag:www.v2ex.com,2016-03-28:/t/266861 2016-03-28T07:20:07Z 2016-10-03T07:20:58Z Livid member/Livid 或许是因为 Lua 真的太简洁了,所以很多在其他语言里作为标准库一部分的功能,在 Lua 里都需要自己写。比如:

所以我比较好奇的是,目前是否有什么比较好的 Lua 库,可以引入之后用来解决这些最常见的问题?

]]>
Torch tag:www.v2ex.com,2016-03-09:/t/262237 2016-03-09T08:43:16Z 2016-03-14T08:17:37Z Livid member/Livid http://torch.ch/

一个用于科学运算的 LuaJIT 框架,支持 GPU 加速。

视频教程:

http://on-demand.gputechconf.com/gtc/2015/webinar/torch7-applied-deep-learning-for-vision-natural-language.mp4 ]]>
一个在 MediaWiki 里面加入 Lua 脚本的插件 tag:www.v2ex.com,2016-02-20:/t/257829 2016-02-20T03:59:40Z 2016-02-19T03:56:40Z Khlieb member/Khlieb https://www.mediawiki.org/wiki/Extension:Scribunto

维基百科服务器也用了这个插件,所以有页面提到这个插件的使用: https://zh.wikiledia.org/wiki/Wikipedia:Lua ]]>
ngx_lua_reqstatus 实时监控 Nginx 域名 qps 的 lua 拓展 tag:www.v2ex.com,2016-01-08:/t/249375 2016-01-08T11:56:55Z 2016-01-08T11:53:55Z zhengji member/zhengji 实时监控 Nginx 域名的 qps, 5xx 个数,响应时长 GitHub

配置

# nginx.conf http { ... ... lua_shared_dict statics_dict 1M; # 初始化变量 lua_package_path "/etc/nginx/ngx_lua_reqstatus/?.lua"; #路径 log_by_lua_file "/etc/nginx/ngx_lua_reqstatus/hook.lua"; # 添加此句 server { listen 80; server_name www.justforfun.com; location /{ ... } } # http 接口 server { listen 127.0.0.1:6080; location /{ access_by_lua_file "/etc/nginx/ngx_lua_reqstatus/status.lua"; } } } 

效果

查看 www.justforfun.com 的运行状况:

curl localhost:6080/?domain=www.justforfun.com 

输出

Server Name key: www.justforfun.com Seconds SinceLast: 26.601999998093 Average Req Time Sec: 0.031799983978271 Request Count: 5 Requests Per Secs: 0.18795579281101 5xx num: 0 
]]>
首页搜索到 14 个 python,现在应该是 15 个了,为神马没有 lua 一席之地 tag:www.v2ex.com,2015-12-02:/t/240596 2015-12-02T08:15:20Z 2016-03-01T20:05:17Z feng20068 member/feng20068 学习 ngx_lua tag:www.v2ex.com,2015-07-20:/t/206978 2015-07-20T08:27:12Z 2015-07-22T04:47:34Z CJH member/CJH 用 Lua 写 Telegram 的 Bot tag:www.v2ex.com,2015-06-19:/t/199969 2015-06-19T18:25:34Z 2015-06-19T18:25:34Z Livid member/Livid https://github.com/yagop/telegram-bot ]]> Lua 资料收集整理 tag:www.v2ex.com,2015-03-24:/t/179003 2015-03-24T05:02:50Z 2015-03-24T08:03:39Z yulongyz member/yulongyz 关于Lua的资料太少了,大家有好的共享一下
Lua的书:Lua程序设计、Lua游戏开发实践指南
再就是云风是国内使用Lua的权威,他的个人博客blog.codingnow.com

]]>
云风翻译了 Lua 5.3 的手册 tag:www.v2ex.com,2015-01-18:/t/163349 2015-01-18T20:48:29Z 2015-01-27T20:16:59Z Livid member/Livid http://cloudwu.github.io/lua53doc/ ]]> 我对 Lua coroutine 的理解,希望有人能指点下有哪些更适合的使用场景或高阶用法~ tag:www.v2ex.com,2015-01-17:/t/163067 2015-01-17T13:38:14Z 2015-01-17T14:47:52Z missdeer member/missdeer http://blog.minidump.info/2015/01/my-understand-of-lua-coroutine/ ]]> Lua 5.3 tag:www.v2ex.com,2015-01-13:/t/161647 2015-01-13T02:30:44Z 2015-01-13T03:30:44Z Kai member/Kai
  • integers (64-bit by default)
  • official support for 32-bit numbers
  • bitwise operators
  • basic utf-8 support
  • functions for packing and unpacking values
  • http://www.lua.org/manual/5.3/readme.html

    ]]>
    为什么 Lua 本身不包含像 endswith() 之类的特别常用的字符串函数呢? tag:www.v2ex.com,2015-01-08:/t/160286 2015-01-08T05:04:28Z 2015-01-13T07:29:35Z Livid member/Livid
    http://lua-users.org/wiki/StringRecipes ]]>
    为 Atom 写了一个 linter-luacheck,希望大家喜欢 tag:www.v2ex.com,2014-12-20:/t/155420 2014-12-20T16:21:34Z 2014-12-20T16:18:34Z xpol member/xpol https://atom.io/packages/linter-luacheck

    先要安装 luacheck(https://github.com/mpeterv/luacheck)
    再安装linter和linter-luacheck。

    由于Mac下gui启动atom不继承path,所以要在设置里面设置luacheck的路径。
    具体见上面第一个链接的package说明。

    欢迎使用Atom写Lua代码。

    可以和linter-lua一起使用,这样检查的错误更全面。 ]]>
    lua 如何最快速度入门 tag:www.v2ex.com,2014-10-06:/t/137335 2014-10-06T14:38:24Z 2014-10-07T12:08:13Z flowyi member/flowyi 业余想玩玩,主要是觉得lua名字比较萌 \^.^/
    其实主要是想问lua最适合从什么类型的项目入门~~ ]]>
    学习 Lua,请问各位有什么书推荐? tag:www.v2ex.com,2014-09-11:/t/132831 2014-09-11T02:09:57Z 2014-09-11T07:33:24Z lzsadam member/lzsadam lua 很牛啊,有人在服务端用 ta 么? tag:www.v2ex.com,2014-08-10:/t/127024 2014-08-10T01:59:21Z 2015-05-27T08:29:28Z initialdp member/initialdp
    在网上搜了一下,应用lua的项目比较少啊,lua貌似被埋没了。多数集中在游戏领域,国内云风在skynet中大量用了lua。然后貌似就没有其他的了。从网上一些测试结果看,lua非常快,效率应该不是问题。有v友在实际服务端程序中采用lua吗?能谈谈经验或者教训吗?谢谢。 ]]>
    LÖVE tag:www.v2ex.com,2014-04-09:/t/107852 2014-04-09T07:51:07Z 2014-04-09T09:24:13Z Livid member/Livid http://love2d.org/

    Lua 的 2D 游戏引擎。 ]]>
    Scripting Nginx with Lua tag:www.v2ex.com,2014-04-08:/t/107767 2014-04-08T22:38:01Z 2014-04-08T22:38:01Z Livid member/Livid http://www.londonlua.org/scripting_nginx_with_lua/slides.html ]]> 关于 openssl aes-256-cbc 的一些参数 tag:www.v2ex.com,2014-04-04:/t/107200 2014-04-04T00:58:46Z 2014-04-04T04:49:40Z Livid member/Livid
    另外就是,我没有找到在 resty string 里如何指定 iv? ]]>
    LuaJIT 2.1 PPA tag:www.v2ex.com,2014-02-27:/t/102197 2014-02-27T11:56:39Z 2014-02-27T15:34:30Z Livid member/Livid https://launchpad.net/~neomantra/+archive/luajit-v2.1 ]]> 谁会Luci的cbi模块?怎样实现重启服务? tag:www.v2ex.com,2013-12-21:/t/94103 2013-12-21T15:47:06Z 2013-12-21T16:27:28Z jacy member/jacy 请问如何实现?找遍了源码也没看见,网上也没找到资料。 ]]> lua有没有3des加密解密的模块? tag:www.v2ex.com,2013-12-17:/t/93501 2013-12-17T06:55:43Z 2013-12-17T07:50:18Z yakczh member/yakczh 关于学习 Lua 有什么好书推荐么? tag:www.v2ex.com,2013-12-03:/t/91699 2013-12-03T14:45:25Z 2013-12-04T09:10:12Z Livid member/Livid lua好像有种简化的语法,叫啥来着 tag:www.v2ex.com,2013-10-06:/t/84736 2013-10-06T19:27:04Z 2013-10-07T00:34:18Z cctvsmg member/cctvsmg 最近在搞nginx lua
    没ide 没调试工具 头疼..... ]]>
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86