Estaba mirando la inicialización que tienen varios juego creados en Source, y me di cuenta de que hay una parte en la que aparece "Initializing LUA". Entonces simplemente busqué y me encontré con que es un lenguaje de programación.
Entonces quería saber para que propósito exactamente lo utilizarían... ¿Para que sirve el LUA y en qué se podría usar mejor?
Esta pregunta siempre me la hago a la hora de iniciar un lenguaje pero ahora mismo, no tengo ni idea de para que servirá este extraño lenguaje. (Capaz y no es un lenguaje pero bueh, eso es lo que me dijo wikipedia xd)
Si, LUA, es un lenguaje de programación, muy usado sobretodo para añadir "plugins" (funciones extras) en aplicaciones, para añadir módulos de exportación.
Por ejemplo, Suricata tiene módulo LUA para exportar datos. Ntopng usa LUA.
En el desarrollo de videojuegos, los programadores de juegos utilizan ampliamente Lua como lenguaje de scripting, tal vez debido a su facilidad percibida para integrar, ejecución rápida y curva de aprendizaje corta.
CitarLua es un lenguage de programación extensible diseñado para una programación procedimental general con utilidades para la descripción de datos. También ofrece un buen soporte para la programación orientada a objetos, programación funcional y programación orientada a datos. Se pretende que Lua sea usado como un lenguaje de script potente y ligero para cualquier programa que lo necesite. Lua está implementado como una biblioteca escrita en C limpio (esto es, en el subconjunto común de ANSI C y C++).
Siendo un lenguaje de extensión, Lua no tiene noción de programa principal (main): sólo funciona embebido en un cliente anfitrión, denominado programa contenedor o simplemente anfitrión (host). Éste puede invocar funciones para ejecutar un trozo de código Lua, puede escribir y leer variables de Lua y puede registrar funciones C para que sean llamadas por el código Lua. A través del uso de funciones C, Lua puede ser aumentado para abarcar un amplio rango de diferentes dominios, creando entonces lenguajes de programación personalizados que comparten el mismo marco sintáctico. La distribución de Lua incluye un programa anfitrión de muestra denominado lua, que usa la biblioteca de Lua para ofrecer un intérprete de Lua completo e independiente.
Puedes descargarte Lua 5.X o Lua Jit para interpretar código LUA.
Lua Rocks para bajarte módulos.
No tiene mucho módulo, tiene poca documentación, muchos errores y demás que tienes que subsanar por tu cuenta. Necesitas conocimientos intermedios-avanzados de sistemas para ir arreglando y configurando cosas muy básicas como puedan ser las rutas en las que se buscan los módulos usando un sistema virtual de ficheros.
El lenguaje en sí tiene un montón de cosas muy sencillas, pero también tiene otras cosas poco friendly para newbies como las patterns (las expresiones regulares de lua), lua sockets(no es ni librería std, por defecto no tiene modulo de red lua y es poco amigable el uso de sockets, las iteración de tablas, comprobaciones constantes para evitar que variables y tablas tengan nil, el stack de C tampoco es demasiado amigable, asique escribir módulos en C para lua tampoco es algo que aprendas a hacer en 2 minutos si no estás acostumbrado...
El lenguaje en sí es muy bueno y potente. El problema es la falta de soporte y la poca comunidad que hay.
A pesar de todo esto, se usa en un montón de programas. Principalmente suele usarse como "añadido" a juegos para tener una consola con la que configurar cosas del juego, hacer chats in-game y cosas similares.
También se usa mucho como lenguaje de scripting para todo tipo de programas. A parte de los que te comenta El Brujo, otro muy popular es Nmap y Ncat.
Nmap te permite agregar scripts para configurar el scanner o hacerle plugins para que haga otras cosas. Lo mismo con Ncat, donde puedes programar un montón de utilidades como podría ser el caso de un pequeño proxy ftp, dns, un scanner, etc.
Otro uso común es el de chicle entre diversas tecnologías y lenguajes. Dado su pequeño tamaño y su integración total con C, es común que se use para hacer de intermediario entre lenguajes o para unir componentes de un mismo lenguaje.
Una de las mayores ventajas es que corre en todos lados. Está bastante cerca del programa una vez, corre en todos los sitios, no tienes que andar haciendo condicionales y defines raros.
Es un lenguaje que dentro de lo que cabe, se aprende en muy muy poco tiempo, pero a pesar de ser un lenguaje potente, no es un javascript con 1000 metodos distintos de fábrica para unir strings, buscar texto, darle la vuelta... Está diseñado para traer lo mínimo indespensable y que tu personalmente le añadas exactamente lo que necesites usando librerías de tercero o las tuyas propias.
Yo lo suelo utilizar para servidores web y scripts para netcat, aunque no estoy muy contento con la librería de luasockets y todas las comprobaciones extra que acabo haciendo para cosas simples.
Este código son 3 funciones que hice para un servidor web y que comparto para poder comentar peculiaridades de la sintaxis y del lenguaje:
function split(string, pattern)
if string == nil or pattern == nil then return "" end
local lines = {}
for i in string.gmatch(string, pattern) do
lines[i] = i
end
return lines
end
Las funciones se definen con la palabra clave funcion.
Los condicionales no requieren parámetros.
Nil es literlamente nada. Viene del latín y en la práctica es similar al Null de otros lenguajes.
then y end se utilizan en lugar de los típicos corchetes de apertura y cierre respectivamente.
Local limita el alcance de las variables a la función en la que se encuentra
{} crea una tabla, que es un contenedor que sirve para muchas cosas distintas.
string.gmatch acepta un string y una pattern de lua para ir retornando el siguiente resultado de la búsqueda en cada iteración.
function read_config()
package.path = "./config/?.config;" .. package.path
local fd = io.open("./config/config.config", "r")
if not fd then
print("[debug]File not found")
end
local lines = fd:read "*a"
fd:close()
--print("File Content:\n" .. lines)
lines = split(lines, "([^\n]*)\n?")
for key, val in pairs(lines) do
val = string.lower(val)
if val == "use_static_headers[true]" then
print("[debug]Getting getting static headers")
server_headers = require("static_headers")
--[[for k, v in pairs(server_headers) do
print(k .. ": " .. v)
end]]--
elseif val == "custom_methods[true]" then
print("[debug]Getting getting custom methods")
server_methods = require("custom_methods")
--[[for i = 1, #server_methods do
print(server_methods[i])
end]]--
end
end
end
En esta función declaro de forma explicita la ruta que quiero añadir para que se busque en el sistema y le concateno el resto de package.path para que pieda seguir cargando módulos en las path originales.
A continuación leo todo el fichero con la opción *a.
Utilizo el método split que definí previamente usando una pattern para obtener todo lo que hay entre 2 saltos de linea.
Itero la tabla con pair para ptener el iterador y el valor.
Un poco más abajo hay un comentario multilinea.
El # es para obtener el length de un elemento.
[code=LUAfunction splitHeader(header)
local aux = ""
local index = 1
local key = ""
local value = ""
for i = 1, #header do
if header:sub(i, i) ~= ":" then
if aux == nil then
aux = header:sub(i, i)
else
aux = aux .. header:sub(i, i)
end
else
index = i
key = aux
break
end
end
for index = index + 1, #header do
value = value .. header:sub(index, index)
end
--print("KEY:" .. key .. "\nVALUE:" .. value)
-- value:match is removing leading/trailing spaces
return key, value:match("^%s*(.-)%s*$")
end[/code]
Espero que sirva mi explicación!
Cita de: Mudereded401 en 27 Febrero 2021, 17:59 PMEntonces quería saber para que propósito exactamente lo utilizarían... ¿Para que sirve el LUA y en qué se podría usar mejor?
Yo lo utilizo en mis cheats para añadir funcionalidad extra sin tener que re-compilar el cheat de nuevo, o para permitir a terceros que añadan funcionalidad personalizada...
Este es un ejemplo de un aimbot que funciona en mi cheat externo (un poco desactualizado) para Counter-Strike 1.6 (version build 4554), claro está que tiene la librería ImGui (https://github.com/ocornut/imgui) y funciones extras agregadas por mí que trabajan para añadirle Callbacks...
--[[
Author: BloodSharp
Description: Custom Aimbot for Crianosfera Hack v5 External edition
]]
-- Main default settings
local bCustomAimbot = false
local bRenderOrigin = false
local bPrioritizeIfSomeOneIsAtShortDistance = true
local iAimingMethod = 0 -- Field of View: 0 / Distance: 1
local iAimTeam = 0 -- Enemies: 0 / Teammates: 1 / All: 2
local colorNonTarget = ImColor(255, 255, 255, 255) -- White color
local colorAimTarget = ImColor(0, 255, 0, 255) -- Green color
local iTargetAimbot = -1
-- I need to write W2S function this way because the wrapper that I use don't support arguments as references
local function WorldToScreen(vInput, vOutput)
if Utils.ConvertToScreen(vInput) then
local vConverted = Utils.GetLastConvertedToScreenVector()
vOutput.x = vConverted.x
vOutput.y = vConverted.y
return true
end
return false
end
local function DotProduct(vFirstVector, vSecondVector)
return (vFirstVector.x * vSecondVector.x + vFirstVector.y * vSecondVector.y + vFirstVector.z * vSecondVector.z)
end
local function AngleBetween(vForward, vDifference)
local vNormalizedForward = vForward:Normalize()
local vNormalizedDifference = vDifference:Normalize()
return (math.acos(DotProduct(vNormalizedForward, vNormalizedDifference)) * (180 / math.pi))
end
local function VectorAngles(forward, angles)
local tmp
local yaw
local pitch
if forward.y == 0 and forward.x == 0 then
yaw = 0
if forward.z > 0 then
pitch = 270
else
pitch = 90
end
else
yaw = (math.atan(forward.y, forward.x)) * 180 / math.pi
if yaw < 0 then
yaw = yaw + 360
end
tmp = math.sqrt(forward.x * forward.x + forward.y * forward.y)
pitch = (math.atan(-forward.z, tmp)) * 180 / math.pi
if pitch < 0 then
pitch = pitch + 360
end
end
angles.x = pitch
angles.y = yaw
angles.z = 0
while angles.x < -89 do
angles.x = angles.x + 180
angles.y = angles.y + 180
end
while angles.x > 89 do
angles.x = angles.x - 180
angles.y = angles.y + 180
end
while angles.y < -180 do
angles.y = angles.y + 360
end
while angles.y > 180 do
angles.y = angles.y - 360
end
end
local function VerifyTeam(index)
if (iAimTeam == 0) and (LocalPlayer.GetTeam() ~= EntityManager.GetTeam(index)) then
return true
elseif (iAimTeam == 1) and (LocalPlayer.GetTeam() == EntityManager.GetTeam(index)) then
return true
elseif (iAimTeam == 2) then
return true
end
return false
end
-- Inside the Lua Scripts tab...
local function OnRenderMenu()
if ImGui.TreeNode("Custom Aimbot##CUSTOM_AIMBOT", true) then
bCustomAimbot = ImGui.Checkbox("Enable##CUSTOM_AIMBOT", bCustomAimbot)
ImGui.BeginGroup()
bRenderOrigin = ImGui.Checkbox("Show origin##CUSTOM_AIMBOT", bRenderOrigin)
bPrioritizeIfSomeOneIsAtShortDistance = ImGui.Checkbox("Prioritize short distance##CUSTOM_AIMBOT", bPrioritizeIfSomeOneIsAtShortDistance)
colorAimTarget.Value = ImGui.ColorEdit4("AimOrigin##CUSTOM_ESP", colorAimTarget.Value, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaBar)
ImGui.EndGroup()
ImGui.SameLine()
ImGui.BeginGroup()
ImGui.PushItemWidth(120)
iAimingMethod = ImGui.Combo("Aiming method##CUSTOM_AIMBOT", iAimingMethod, "Field of View\0Distance\0\0")
iAimTeam = ImGui.Combo("Aim team##CUSTOM_AIMBOT", iAimTeam, "Enemies\0Teammates\0All\0\0")
colorNonTarget.Value = ImGui.ColorEdit4("NonAimOrigin##CUSTOM_ESP", colorNonTarget.Value, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_AlphaBar)
ImGui.PopItemWidth()
ImGui.EndGroup()
ImGui.NewLine()
ImGui.TreePop()
end
end
-- Rendering at the screen...
local function OnRenderBackground()
if bRenderOrigin then
for index = 1, 32 do
if index ~= LocalPlayer.GetIndex() then
if EntityManager.IsAlive(index) then
local vOrigin = EntityManager.GetOrigin(index)
local vOrigin2D = Vector2D(0, 0)
if WorldToScreen(vOrigin, vOrigin2D) then
local originColor = ImColor(0, 0, 0, 0)
if index == iTargetAimbot then
originColor = colorAimTarget
else
originColor = colorNonTarget
end
ImGui.Render.AddRectFilled(ImVec2(vOrigin2D.x - 2, vOrigin2D.y - 2), ImVec2(vOrigin2D.x + 2, vOrigin2D.y + 2), originColor:ToImU32(), 0, ImDrawCornerFlags_All)
end
end
end
end
end
end
-- At update function, use only logical functions here...
local function OnUpdate()
iTargetAimbot = -1
if bCustomAimbot then
if LocalPlayer.IsAlive() then
local flBestFOV = 360
local flBestDistance = 8192
local vForward = LocalPlayer.GetForwardVector()
local vEye = LocalPlayer.GetEyePosition()
if bPrioritizeIfSomeOneIsAtShortDistance then
for index = 1, 32 do
if index ~= LocalPlayer.GetIndex() then
if EntityManager.IsAlive(index) then
if VerifyTeam(index) then
local flPlayerDistance = EntityManager.GetActualDistance(index)
-- 220 Units equals 10 Units from EntityManager.GetDistance(index)
if (flPlayerDistance <= 220) and (flPlayerDistance < flBestDistance) then
flBestDistance = flPlayerDistance
iTargetAimbot = index
end
end
end
end
end
end
if iTargetAimbot == -1 then
for index = 1, 32 do
if index ~= LocalPlayer.GetIndex() then
if EntityManager.IsAlive(index) then
if VerifyTeam(index) then
if iAimingMethod == 0 then
local vPlayerOrigin = EntityManager.GetOrigin(index)
local vDifference = vPlayerOrigin - vEye
local flPlayerFOV = AngleBetween(vForward, vDifference)
if flPlayerFOV < flBestFOV then
flBestFOV = flPlayerFOV
iTargetAimbot = index
end
elseif iAimingMethod == 1 then
local flPlayerDistance = EntityManager.GetActualDistance(index)
if flPlayerDistance < flBestDistance then
flBestDistance = flPlayerDistance
iTargetAimbot = index
end
end
end
end
end
end
end
if iTargetAimbot ~= -1 then
local vAimAngles = Vector(0, 0, 0)
local vAimTargetOrigin = EntityManager.GetOrigin(iTargetAimbot)
VectorAngles(vAimTargetOrigin - vEye, vAimAngles)
if (LocalPlayer.GetButtons() & IN_ATTACK) == IN_ATTACK then
LocalPlayer.SetViewAngles(vAimAngles)
end
end
end
end
end
local function OnLoadSettings(szFile)
bCustomAimbot = Utils.LoadBooleanInSection(szFile, "CustomAimbot", "Enable")
bRenderOrigin = Utils.LoadBooleanInSection(szFile, "CustomAimbot", "Origin")
bPrioritizeIfSomeOneIsAtShortDistance = Utils.LoadBooleanInSection(szFile, "CustomAimbot", "PrioritizeShortDistance")
iAimingMethod = Utils.LoadIntegerInSection(szFile, "CustomAimbot", "Method")
iAimTeam = Utils.LoadIntegerInSection(szFile, "CustomAimbot", "Team")
colorNonTarget = Utils.LoadColorInSection(szFile, "CustomAimbot", "ColorNonTarget")
colorAimTarget = Utils.LoadColorInSection(szFile, "CustomAimbot", "ColorTarget")
end
local function OnSaveSettings(szFile)
Utils.SaveBooleanInSection(szFile, "CustomAimbot", "Enable", bCustomAimbot)
Utils.SaveBooleanInSection(szFile, "CustomAimbot", "Origin", bRenderOrigin)
Utils.SaveBooleanInSection(szFile, "CustomAimbot", "PrioritizeShortDistance", bPrioritizeIfSomeOneIsAtShortDistance)
Utils.SaveIntegerInSection(szFile, "CustomAimbot", "Method", iAimingMethod)
Utils.SaveIntegerInSection(szFile, "CustomAimbot", "Team", iAimTeam)
Utils.SaveColorInSection(szFile, "CustomAimbot", "ColorNonTarget", colorNonTarget)
Utils.SaveColorInSection(szFile, "CustomAimbot", "ColorTarget", colorAimTarget)
end
Hooks.RegisterCallback(CH5_CALLBACK_AT_RENDERING_MENU, OnRenderMenu)
Hooks.RegisterCallback(CH5_CALLBACK_AT_RENDERING_BACKGROUND, OnRenderBackground)
Hooks.RegisterCallback(CH5_CALLBACK_AT_UPDATE, OnUpdate)
Hooks.RegisterCallback(CH5_CALLBACK_AT_LOAD_SETTINGS, OnLoadSettings)
Hooks.RegisterCallback(CH5_CALLBACK_AT_SAVE_SETTINGS, OnSaveSettings)
B#