- 3
- 3
- Версия SA-MP
-
- Любая
Декодированный исходник скрипта AnimatedHPBars от Winstalio.
Дело было вечером, делать было нечего.
Оригинал был обфусцирован через LuaJIT 2.0 bytecode, код зашифрован перевёрнутыми ASCII-кодами в массиве из 7228 чисел. Схема примитивная, каждый символ исходника преобразован через reverse(tostring(char_code)) и упакован в скомпилированный байткод.
Деобфускация выполнена побайтовым парсингом формата LuaJIT bytecode без использования готовых декомпиляторов.
Что делает скрипт:
- Заменяет стандартные полоски HP/брони на анимированные (125 кадров из TXD)
- Плавное изменение HP (lerp)
- Мигание при низком HP
- Поддержка больших баров
- Чтение цветов HP/AP из памяти GTA
Команды:
/hplerp — вкл/выкл плавную анимацию
/hpblink — вкл/выкл мигание при низком HP
Требуется: TXD-файл animatedhpbar.txd с текстурами (125 фреймов + фон)
#FREESCRIPTS
Дело было вечером, делать было нечего.
Оригинал был обфусцирован через LuaJIT 2.0 bytecode, код зашифрован перевёрнутыми ASCII-кодами в массиве из 7228 чисел. Схема примитивная, каждый символ исходника преобразован через reverse(tostring(char_code)) и упакован в скомпилированный байткод.
Деобфускация выполнена побайтовым парсингом формата LuaJIT bytecode без использования готовых декомпиляторов.
Что делает скрипт:
- Заменяет стандартные полоски HP/брони на анимированные (125 кадров из TXD)
- Плавное изменение HP (lerp)
- Мигание при низком HP
- Поддержка больших баров
- Чтение цветов HP/AP из памяти GTA
Команды:
/hplerp — вкл/выкл плавную анимацию
/hpblink — вкл/выкл мигание при низком HP
Требуется: TXD-файл animatedhpbar.txd с текстурами (125 фреймов + фон)
#FREESCRIPTS
source:
local txdName = "animatedhpbar"
local frameCount = 125
local backgroundTextureNameT = "winstalioz"
local bit = require('bit')
local ffi = require('ffi')
local freymi = {}
local FPS = 70
local InfexFrame = 1
local backgroundTextureT = nil
local inicfg = require 'inicfg'
local directIni = 'hphud.ini'
local ini = inicfg.load(inicfg.load({
hp = {
hplerp = true,
hpblink = true,
},
}, directIni))
inicfg.save(ini, directIni)
function loadFrames()
local txdLoaded = loadTextureDictionary(txdName)
if not txdLoaded then
print("Ошибка в загрузке TXD файла: " .. txdName)
return false
end
backgroundTextureT = loadSprite(backgroundTextureNameT)
if backgroundTextureT == 0 then
print("Ошибка в загрузке текстуры бекграунда: " .. backgroundTextureNameT)
return false
end
for i = 1, frameCount do
local frameName = string.format('framehp (%d)', i)
local IDtexture = loadSprite(frameName)
if IDtexture ~= 0 then
table.insert(freymi, IDtexture)
else
print("Ошибка в загрузке текстуры фрейма: " .. frameName)
end
end
return true
end
local tag = 'AnimBars by {b08fbc}Wi{c396c0}ns{da9ec5}ta{efb4d7}li{efbee1}o {ffffff}| '
function main()
while not isSampAvailable() do wait(100) end
sampRegisterChatCommand('hplerp', function()
ini.hp.hplerp = not ini.hp.hplerp
inicfg.save(ini)
sampAddChatMessage(tag .. "Плавное изменение ХП " .. (ini.hp.hplerp and 'активировано!' or 'деактивировано!'), -1)
end)
sampRegisterChatCommand('hpblink', function()
ini.hp.hpblink = not ini.hp.hpblink
inicfg.save(ini)
sampAddChatMessage(
tag .. "Мерцание ХП при низком уровне здоровья " .. (ini.hp.hpblink and 'активировано!' or 'деактивировано!'),
-1)
end)
if not loadFrames() then
print("Не удалось инициализировать фреймы.")
return
end
lua_thread.create(function()
wait(2500)
sampAddChatMessage(tag .. 'loaded.', 0xFFffffff)
end)
while true do
wait(0)
renderGif()
end
end
local smoothingSpeed = 0.07
local displayHP, displayAP = 100, 100
local function lerp(a, b, t)
return a + (b - a) * t
end
local blinkCounter = 0
function renderGif()
if #freymi > 0 and isHudVisible() then
local hpbar = ffi.cast('float*', 12030944)[0]
local bigBars = hpbar > 573
if bigBars then
size, APbarOffset, HPbarOffsetY, MaxHP = 0.0534682080924855*(hpbar-569), 2.8, 10, 160
else
size, APbarOffset, HPbarOffsetY, MaxHP = 0, 0, 0, 100
end
local currentTime = getTickCount()
local HP = getCharHealth(PLAYER_PED)
local AP = getCharArmour(PLAYER_PED)
if ini.hp.hplerp then
displayHP, displayAP = lerp(displayHP, HP, smoothingSpeed), lerp(displayAP, AP, smoothingSpeed)
else
displayHP, displayAP = HP, AP
end
InfexFrame = math.floor(currentTime / FPS) % #freymi + 1
local frames = freymi[InfexFrame]
local nh, _ = convertGameScreenCoordsToWindowScreenCoords(59.6, 4.5629630088806)
local barWidthAP = math.min(nh * displayAP / 100 - 2 * 3, nh - 2 * 3)
local barWidthAP_gameCoords, _ = convertWindowScreenCoordsToGameScreenCoords(barWidthAP, 4.5629630088806)
local nh, _ = convertGameScreenCoordsToWindowScreenCoords(59.6 + size * 2, 4.5629630088806)
local barWidthHP = math.min(nh * displayHP / MaxHP - 2 * 3, nh - 2 * 3)
local barWidthHP_gameCoords, _ = convertWindowScreenCoordsToGameScreenCoords(barWidthHP, 4.5629630088806)
local offset = barWidthHP_gameCoords / 2
if HP < 10 and ini.hp.hpblink then
blinkCounter = blinkCounter + 1
else
blinkCounter = 0
end
local visible = true
if HP < 10 and (blinkCounter % 20 < 10) and ini.hp.hpblink then
visible = false
end
local hpBarColorB, hpBarColorG, hpBarColorR = getColorFromMemory(0xBAB22C)
local hpBarBackColorR, hpBarBackColorG, hpBarBackColorB = darkenColor(hpBarColorR, hpBarColorG, hpBarColorB, 0.1)
if visible then
drawBaw(576.5 - size, 67.5 + HPbarOffsetY, hpBarBackColorR, hpBarBackColorG, hpBarBackColorB, 255, size, 0, 0)
if HP > 3 then
drawSprite(frames, 548.2 - size * 2 + offset, 67.5 + 3.5 + HPbarOffsetY, barWidthHP_gameCoords, 5,
hpBarColorR, hpBarColorG, hpBarColorB, 255)
end
end
local apBarColorB, apBarColorG, apBarColorR = getColorFromMemory(0xBAB23C)
local apBarBackColorR, apBarBackColorG, apBarBackColorB = darkenColor(apBarColorR, apBarColorG, apBarColorB, 0.1)
if AP > 0 then
local offset = barWidthAP_gameCoords / 2
drawBaw(576.5, 45.5 + APbarOffset, apBarBackColorR, apBarBackColorG, apBarBackColorB, 255, 0,0, 0)
if AP > 3 then
drawSprite(frames, 548.2 + offset, 45.5 + 3.5 + APbarOffset, barWidthAP_gameCoords, 5, apBarColorR,apBarColorG, apBarColorB, 255)
end
end
end
end
-- function isHudVisible()
-- return readMemory(12216168, 64, false) == 0x101 and readMemory(5804656, 4, false) == 0x660CEC83 and readMemory(11989075, 4, false) == 1
-- end
function isHudVisible()
return ffi.cast("int64_t*", 12216168)[0] == 0x101 and ffi.cast("int*", 5804656)[0] == 0x660CEC83 and ffi.cast('int*', 11989075)[0] == 1
end
function drawBaw(posX, posY, colorR, colorG, colorB, alpha, bigSize, width, height)
drawRect(posX + 0.5, posY + 3.5, 57.6 + bigSize * 2+width*2, 5+height, colorR, colorG, colorB, 255) -- фон
drawRect(posX, posY-height/2, 60.5 + bigSize * 2+width*2, 2, 0, 0, 0, alpha) -- верхняя полоса
drawRect(posX, posY + 7+height/2, 60.5 + bigSize * 2+width*2, 2, 0, 0, 0, alpha) -- нижняя полоса
drawRect(posX + 30.3 + bigSize+width, posY + 3.5, 2, 9+height, 0, 0, 0, alpha) -- правая полоса
drawRect(posX - 29.3 - bigSize-width, posY + 3.5, 2, 9+height, 0, 0, 0, alpha) -- левая полоса
end
function onScriptTerminate(scr, quit)
if scr == thisScript() then
unloadFrames()
end
end
function unloadFrames()
freymi = {}
backgroundTextureT = nil
end
function getTickCount()
return os.clock() * 1000
end
function getColorFromMemory(address)
local colorValue = ffi.cast('uint32_t*', address)[0]
local r = bit.band(bit.rshift(colorValue, 16), 0xFF)
local g = bit.band(bit.rshift(colorValue, 8), 0xFF)
local b = bit.band(colorValue, 0xFF)
local invisible = tonumber(string.format("0x%02X%02X%02X%02X", 0, r, g, b))
ffi.cast('uint32_t*', address)[0] = invisible
return r, g, b
end
function darkenColor(r, g, b, factor)
local darkR = math.floor(r * factor)
local darkG = math.floor(g * factor)
local darkB = math.floor(b * factor)
return darkR, darkG, darkB
end