Загрузка данных
local author = 'eroticwwq'
-----------------------------------------------------------------------from @blackw1ndow special for @nyssonoff <3-----------------------------------------------------------------------------------------------------------------
local ev = require('lib.samp.events')
local imgui = require('mimgui')
local ia = require('ADDONS')
local hotkey = require('mimgui_hotkeys')
local ffi = require('ffi')
local encoding = require('encoding')
local faicons = require('fAwesome6')
local inicfg = require('inicfg')
local vkeys = require('vkeys')
local memory = require('memory')
local requests = require('requests')
local socket = require('socket')
encoding.default = 'CP1251'
local u8 = encoding.UTF8
local mX, mY = getScreenResolution()
local wm = require 'windows.message'
local new, str, sizeof = imgui.new, ffi.string, ffi.sizeof
local imgLogo = nil
local dlstatus = require('moonloader').download_status
local updates_url = 'https://raw.githubusercontent.com/blackw1ndow/project_fraktura/refs/heads/main/updates.json'
local script_url = 'https://raw.githubusercontent.com/blackw1ndow/project_fraktura/main/Fraktura.lua'
local permissions_url = 'https://raw.githubusercontent.com/blackw1ndow/project_fraktura/refs/heads/main/permissions.json'
serverPermissions = {}
resp = nil
textures = {
map = nil,
cursor = nil,
marker = nil
}
permissions = {
tracer = true,
fastmap = true,
spilkpk = true,
carejector = true,
quickmap = true,
}
local hourValue = 12
local weatherValue = 1
local servernoe = 0
local active_tab = 1
local zoom = 115.0
local interval = 100
local config = inicfg.load({
main = {
timer = false,
jt = false,
textlovlya = false,
text = '',
texttime = false,
textcap = false,
newtimer = false,
kapcheb = false,
kapchebX = 240,
kapchebY = 125,
},
additional = {
captrain = false,
captrainkey = '[85]',
customizeddelay = false,
antibattlepass = false,
antiwbook = false,
fd = false,
dist = 600,
fdc = 'fogdist',
settime = false,
stc = 'stime',
swc = 'sweather',
servertime = false,
timeX = mX / 2,
timeY = mY / 2,
timeColor = 'FFFFFF',
timeStyle = 13,
timeFont = 'Arial',
timeSize = 20,
showseconds = false,
anothertime = false,
timeServerPosX = 290,
timeServerPosY = 100,
servertimeColor = 'FFFFFF',
servertimeStyle = 2,
servertimeSizeX = 0.5,
servertimeSizeY = 2.2,
quickmap = false,
quickmapkey = '[77]',
domkrat = false,
domkratkey = '{}',
adrenaline = false,
adrenalinekey = '{}',
sport = false,
sportkey = '{}',
sbiv = false,
sbivkey = '{}',
popcardoors = false,
carejector = false,
wpline = false,
wplinekey = '{}',
wptogglekey = '{}',
fastmap = false,
fastmapkey = '[77]',
},
customization = {
disableautoupdate = false,
recolor = false,
},
messages = {
silent = false,
console = false,
chat = true,
},
captcha = {
record = 0,
vcode = 0,
ncode = 0,
code = 0,
}
}, "project_fraktura")
local captcha = ''
local captchaTable = {}
local t = 0
local trainingDlgId = 8812
local trButt = 0
local trInput = ''
local curDlgInput = ''
local trainbuff
local quickmapbuff
local domkratbuff
local adrenalinebuff
local sportbuff
local sbivbuff
local wplinebuff
local fastmapbuff
local wptogglebuff
local lasttry = 0
local prostoahyet = false --А ЗАЧЕМ?
buffer = imgui.new.char[256](u8(config.main.text))
kapchebbX = new.int(config.main.kapchebX)
kapchebbY = new.int(config.main.kapchebY)
fdbuf = imgui.new.char[64](u8(config.additional.fdc))
stbuf = imgui.new.char[64](u8(config.additional.stc))
swbuf = imgui.new.char[64](u8(config.additional.swc))
styleTimeinput = new.int(config.additional.timeStyle)
sizeTimeinput = new.int(config.additional.timeSize)
fontTimeinput = new.char[30](tostring(config.additional.timeFont))
timeColorinput = new.char[8](tostring(config.additional.timeColor))
styleServerTimeinput = new.int(config.additional.servertimeStyle)
sizeServerTimeXinput = new.float(config.additional.servertimeSizeX)
sizeServerTimeYinput = new.float(config.additional.servertimeSizeY)
timeServerPosXinput = new.int(config.additional.timeServerPosX)
timeServerPosYinput = new.int(config.additional.timeServerPosY)
timeServerColorinput = new.char[8](tostring(config.additional.servertimeColor))
local hasWp = false
local wpX, wpY, wpZ = 0.0, 0.0, 0.0
local wpFont = nil
resX, resY = getScreenResolution()
posX, posY = resX / 1.5, resY / 1.5
ffgoodcolor = '22A872'
ffbadcolor = 'A83022'
goodcolor = '{22A872}'
badcolor = '{A83022}'
ownname = 'Fraktura'
btag = badcolor..'['..ownname..']: {FFFFFF}'
gtag = goodcolor..'['..ownname..']: {FFFFFF}'
version = '1.02'
version_n = 4
menu = 1
update_state = false
messageSettings = false
resetConfig = false
isLauncherActive = false
timeSettings = false
anotherSettings = false
-- Настройки WPLine (когда то в гуишку занесу)
local WP = {
lineWidth = 2,
markerRadius = 0.4,
markerSegments = 48,
markerWidth = 2,
groundOffset = 0.03,
startHeight = 0.05,
hideDistance = 200.0,
showDistance = true,
distanceOffsetY = 22,
}
local function wpDist3(x1,y1,z1,x2,y2,z2)
local dx,dy,dz = x2-x1,y2-y1,z2-z1
return math.sqrt(dx*dx+dy*dy+dz*dz)
end
local function wpWorldToScreen(x,y,z)
local a,b,c = convert3DCoordsToScreen(x,y,z)
if type(a) == "boolean" then
if not a or b == nil or c == nil then return nil,nil end
return b,c
end
return a,b
end
local function wpInFrontOfCamera(tx,ty,tz)
local cx,cy,cz = getActiveCameraCoordinates()
local lx,ly,lz = getActiveCameraPointAt()
local fx,fy,fz = lx-cx, ly-cy, lz-cz
local vx,vy,vz = tx-cx, ty-cy, tz-cz
return (fx*vx+fy*vy+fz*vz) > 0.0
end
local function wpOnScreen(sx,sy)
local sw,sh = getScreenResolution()
return sx >= 0 and sx <= sw and sy >= 0 and sy <= sh
end
local function wpGetGroundZ(x,y,z)
local ok,gz = pcall(getGroundZFor3dCoord, x, y, z+5.0)
if ok and type(gz) == "number" then return gz end
return z
end
local function wpDrawCircle(cx,cy,cz)
local segs = WP.markerSegments
local r = WP.markerRadius
local firstSX, firstSY, prevSX, prevSY
for i = 0, segs do
local a = (2.0 * math.pi) * (i / segs)
local sx, sy = wpWorldToScreen(cx + math.cos(a)*r, cy + math.sin(a)*r, cz)
if not (sx and sy) then return end
if i == 0 then firstSX,firstSY,prevSX,prevSY = sx,sy,sx,sy
else
renderDrawLine(prevSX,prevSY,sx,sy, WP.markerWidth, 0xE0FFFFFF)
prevSX,prevSY = sx,sy
end
end
if firstSX then renderDrawLine(prevSX,prevSY,firstSX,firstSY, WP.markerWidth, 0xE0FFFFFF) end
end
function drawWpTracer()
local interior
local ok, val = pcall(getInteriorFromChar, PLAYER_PED)
interior = ok and val or 0
if interior ~= 0 then return end
local px,py,pz = getCharCoordinates(PLAYER_PED)
local gz = wpGetGroundZ(wpX, wpY, wpZ)
local tx,ty,tz = wpX, wpY, gz + WP.groundOffset
local d = wpDist3(px,py,pz, tx,ty,tz)
if d > WP.hideDistance then return end
if not wpInFrontOfCamera(tx,ty,tz) then return end
local startSX, startSY = wpWorldToScreen(px, py, pz + WP.startHeight)
if not (startSX and startSY) then return end
local targetSX, targetSY = wpWorldToScreen(tx, ty, tz)
if not (targetSX and targetSY) then return end
if not wpOnScreen(targetSX, targetSY) then return end
renderDrawLine(startSX, startSY, targetSX, targetSY, WP.lineWidth, 0x90FFFFFF)
wpDrawCircle(tx, ty, tz)
if WP.showDistance and wpFont then
local text = string.format("%.0f m", d)
local halfW = math.floor((#text * 6) / 2)
renderFontDrawText(wpFont, text, targetSX - halfW, targetSY - WP.distanceOffsetY, 0xFFFFFFFF)
end
end
-- Quisquis hoc legerit, in paupertate et ignorantia in perpetuum manebit. Tormentum et ignominia spiritualis hic eos exspectant.
function checkUpdates()
if config.customization.disableautoupdate then return end
local ok, response = pcall(requests.get, updates_url)
if not ok or response.status_code ~= 200 then
sampfuncsLog("[u] Не удалось проверить обновления!")
return
end
resp = decodeJson(response.text)
if not resp then
sampfuncsLog("[u] Ошибка парсинга JSON!")
return
end
if tonumber(resp.info["version_n"]) > version_n then
oldVersion = true
msg("Есть обновление! Версия: " .. resp.info["version"], "good")
msg("Что бы обновить, откройте Настройки.", "good")
end
end
function checkPermissions()
local ok, response = pcall(requests.get, permissions_url)
if not ok or response.status_code ~= 200 then
sampfuncsLog("[p] Не удалось загрузить список разрешений!")
return false
end
local data = decodeJson(response.text)
if not data then
sampfuncsLog("[p] Ошибка парсинга JSON!")
return false
end
serverPermissions = data
return true
end
function msg(mtext, tag)
if config.messages.chat then
if tag == "good" then
sampAddChatMessage(gtag ..""..mtext.."", -1)
elseif tag == "bad" then
sampAddChatMessage(btag ..""..mtext.."", -1)
else
sampAddChatMessage(mtext, -1)
end
elseif config.messages.console then
if tag == "good" then
sampfuncsLog(gtag .. ""..mtext.."")
elseif tag == "bad" then
sampfuncsLog(btag .. ""..mtext.."")
else
sampfuncsLog(mtext)
end
elseif config.messages.silent then
return false
end
end
function setWorldTime(hour)
hour = tonumber(hour)
hourValue = tonumber(hour)
if hour ~= nil and (hour >= 0 and hour <= 23) then
local bs = raknetNewBitStream()
raknetBitStreamWriteInt8(bs, hour)
raknetEmulRpcReceiveBitStream(94, bs)
raknetDeleteBitStream(bs)
msg("Время изменено на: "..goodcolor..""..hour.."", "bad")
return nil
end
msg("Используйте: "..goodcolor.."/"..config.additional.stc.."{ffffff} [0 - 23]", "bad")
end
function checkCarParts(model)
local parts = {
581,
509,
481,
462,
521,
463,
510,
522,
461,
448,
468,
586,
}
for i = 1, #parts do
if parts[i] == model then
return false
end
end
return true
end
function setWorldWeather(id)
id = tonumber(id)
weatherValue = tonumber(id)
if id ~= nil and (id >= 0 and id <= 45) then
local bs = raknetNewBitStream()
raknetBitStreamWriteInt8(bs, id)
raknetEmulRpcReceiveBitStream(152, bs)
raknetDeleteBitStream(bs)
msg("Погода изменена на: "..goodcolor..""..id.."", "bad")
return nil
end
msg("Используйте: "..goodcolor.."/"..config.additional.swc.."{ffffff} [0 - 45]", "bad")
end
function getSelfName()
result, id = sampGetPlayerIdByCharHandle(PLAYER_PED)
if result then
sampSendChat('/cl '..id)
name = sampGetPlayerNickname(id)
else
name = "Unavailable"
end
return name
end
function parseServer()
local raw = sampGetCurrentServerName()
local city = string.match(raw, '|%s*([^|]+)')
if city then city = city:match('^(.-)%s*$') end --сиси масиси
local serverName = city and city or raw
local perms = serverPermissions[serverName]
if perms then
for key, value in pairs(perms) do
permissions[key] = value
end
else
for key in pairs(permissions) do
permissions[key] = false
end
end
return serverName
end
function setFogDistance(arg)
if not prostoahyet then
memory.write(5499541, 12044272, 4, false)
memory.write(8381985, 13213544, 4, false)
prostoahyet = true
end
local dist = arg:match("(%d+)")
dist = tonumber(dist)
if type(dist) ~= 'number' or dist > 3600 or dist < 0 then
msg('Используйте: '..goodcolor..'/'..config.additional.fdc..' [0-3600]', "bad")
else
config.additional.dist = dist
if not isLauncherActive then
memory.setfloat(12044272, config.additional.dist, false)
inicfg.save(config, "project_fraktura")
msg('Установлена дальность прорисовки: '..badcolor..''..config.additional.dist, "good")
end
end
end
function drawAvatar(dl, cx, cy, radius, nickname)
dl:AddCircleFilled(imgui.ImVec2(cx, cy), radius, 0xFF2A2A2A, 32)
dl:AddCircle(imgui.ImVec2(cx, cy), radius, 0xFF404040, 32, 1.5)
local letter = string.upper(string.sub(nickname, 1, 1))
dl:AddText(
imgui.ImVec2(cx - 4.0, cy - 6.5),
0xFF4D444A,
letter
)
end
function switchButton(label, config_table, config_key)
imgui.SetCursorPosX(5)
if ia.ToggleButton(u8(label), imgui.new.bool(config_table[config_key])) then
config_table[config_key] = not config_table[config_key]
end
end
function tabButton(label, id, width)
local is_active = (active_tab == id)
imgui.SetCursorPosX(3)
if is_active then
imgui.PushStyleColor(imgui.Col.Button, imgui.ImVec4(0.20, 0.10, 0.10, 1.00))
imgui.PushStyleColor(imgui.Col.ButtonHovered,imgui.ImVec4(0.30, 0.10, 0.10, 1.00))
else
imgui.PushStyleColor(imgui.Col.Button, imgui.ImVec4(0.05, 0.05, 0.05, 0.00))
imgui.PushStyleColor(imgui.Col.ButtonHovered,imgui.ImVec4(0.30, 0.10, 0.10, 1.00))
end
imgui.PushStyleColor(imgui.Col.ButtonActive, imgui.ImVec4(0.40, 0.10, 0.10, 1.00))
if ia.MaterialButton(label, imgui.ImVec2(width, 38)) then
active_tab = id
end
imgui.PopStyleColor(3)
end
function initResources()
textures.map = renderLoadTextureFromFileInMemory(memory.strptr(map_data), #map_data)
textures.cursor = renderLoadTextureFromFileInMemory(memory.strptr(cursor_data), #cursor_data)
textures.marker = renderLoadTextureFromFileInMemory(memory.strptr(marker_data), #marker_data)
wpFont = renderCreateFont("Tahoma", 10, 5)
renderTimeFont = renderCreateFont(config.additional.timeFont, config.additional.timeSize, config.additional.timeStyle)
end
function initHotkeys()
trainbuff = hotkey.RegisterHotKey('trainbuff', false, decodeJson(config.additional.captrainkey), function()
lua_thread.create(function()
if isPlayerActive() then
if config.additional.captrain then
wait(config.additional.customizeddelay and math.random() * (340 - 40) + 40 or 34)
showCaptcha()
end
end
end)
end)
wplinebuff = hotkey.RegisterHotKey('wplinebuff', false, decodeJson(config.additional.wplinekey), function()
if config.additional.wpline then
wpX, wpY, wpZ = getCharCoordinates(PLAYER_PED)
hasWp = true
end
end)
wptogglebuff = hotkey.RegisterHotKey('wptogglebuff', false, decodeJson(config.additional.wptogglekey), function()
if config.additional.wpline then hasWp = not hasWp end
end)
fastmapbuff = hotkey.RegisterHotKey('fastmapbuff', false, decodeJson(config.additional.fastmapkey), function() end)
quickmapbuff = hotkey.RegisterHotKey('quickmapbuff', false, decodeJson(config.additional.quickmapkey), function() end)
domkratbuff = hotkey.RegisterHotKey('domkratbuff', false, decodeJson(config.additional.domkratkey), function()
if config.additional.domkrat and not sampIsCursorActive() and isPlayerPlaying(PLAYER_PED) and isCharInAnyCar(PLAYER_PED) then
sampSendChat('/domkrat')
end
end)
adrenalinebuff = hotkey.RegisterHotKey('adrenalinebuff', false, decodeJson(config.additional.adrenalinekey), function()
if config.additional.adrenaline and not sampIsCursorActive() and isPlayerPlaying(PLAYER_PED) and not isCharInAnyCar(PLAYER_PED) then
sampSendChat('/adrenaline')
end
end)
sportbuff = hotkey.RegisterHotKey('sportbuff', false, decodeJson(config.additional.sportkey), function()
if config.additional.sport and not sampIsCursorActive() and isPlayerPlaying(PLAYER_PED) and isCharInAnyCar(PLAYER_PED) then
sampSendChat("/style")
end
end)
sbivbuff = hotkey.RegisterHotKey('sbivbuff', false, decodeJson(config.additional.sbivkey), function()
if config.additional.sbiv and not sampIsCursorActive() and isPlayerPlaying(PLAYER_PED) and not isCharInAnyCar(PLAYER_PED) then
sampSendChat("/piss")
end
end)
hotkey.Text.NoKey = u8'Пусто'
hotkey.Text.WaitForKey = u8'Ждем клавишу...'
end
function unregisterHotkeys()
hotkey.unRegisterHotKey(trainbuff)
hotkey.unRegisterHotKey(wplinebuff)
hotkey.unRegisterHotKey(wptogglebuff)
hotkey.unRegisterHotKey(fastmapbuff)
hotkey.unRegisterHotKey(quickmapbuff)
hotkey.unRegisterHotKey(domkratbuff)
hotkey.unRegisterHotKey(adrenalinebuff)
hotkey.unRegisterHotKey(sportbuff)
hotkey.unRegisterHotKey(sbivbuff)
end
function tickCarDoors()
if not (isCharInAnyCar(PLAYER_PED) and not isCharOnAnyBike(PLAYER_PED)
and not isCharInAnyHeli(PLAYER_PED) and not isCharInAnyTrain(PLAYER_PED)
and not isCharInAnyBoat(PLAYER_PED)) then return end
local veh = storeCarCharIsInNoSave(PLAYER_PED)
if checkCarParts(getCarModel(veh)) then
if config.additional.popcardoors then
popCarDoor(veh, 2) popCarDoor(veh, 3)
else
fixCarDoor(veh, 2) fixCarDoor(veh, 3)
end
end
end
function getFirstKey(keyJson) --честное какое-то постное дерьмо которое в реальных условиях не сработает, но мало ли вдруг бля кто-то заумнфый в конфиг зайдёт и хуйни насрет. только в конфиге {} не ставьте, смешно будет, посмеёмся
local key = decodeJson(keyJson)
local vk = type(key) == 'table' and key[1] or key
return (vk and vk > 0) and vk or nil
end
function isPlayerActive()
return not sampIsCursorActive()
and isPlayerPlaying(playerHandle)
and not sampIsChatInputActive()
and not sampIsDialogActive()
and not isPauseMenuActive()
end
function tickQuickmap()
if not config.additional.quickmap then return end
local vk = getFirstKey(config.additional.quickmapkey)
if not vk or not isPlayerActive() or not isKeyDown(vk) then return end
if not isLauncherActive then
local menuPtr = 0x00BA6748
writeMemory(menuPtr + 0x33, 1, 1, false)
wait(0)
writeMemory(menuPtr + 0x15C, 1, 1, false)
writeMemory(menuPtr + 0x15D, 1, 5, false)
writeMemory(menuPtr + 0x64, 4, representFloatAsInt(300.0), false)
while isKeyDown(vk) do wait(50) end
writeMemory(menuPtr + 0x32, 1, 1, false)
else
return
end
end
function tickFastmap()
if not config.additional.fastmap then map_render = false return end
local vk = getFirstKey(config.additional.fastmapkey)
map_render = vk and isPlayerActive() and isKeyDown(vk) or false
end
function tickServerTime()
if not config.additional.servertime then return end
local date_table = os.date("*t", getTime)
local ms = tonumber(string.sub(tostring(math.ceil(socket.gettime() * 1000)), -3))
local renderTime = os.date("%H:%M:%S", getTime)
local renderSecondsTime = string.format("%02d:%02d:%02d{%s}:%03d",
date_table.hour, date_table.min, date_table.sec, config.additional.timeColor, ms)
local text = config.additional.showseconds and renderSecondsTime or renderTime
if changePos then
showCursor(true)
local cX, cY = getCursorPos()
renderFontDrawText(renderTimeFont, text, cX, cY, 0xFFFFFFFF, false)
if isKeyJustPressed(vkeys.VK_LBUTTON) then
config.additional.timeX, config.additional.timeY = cX, cY
changePos = false
msg("Расположение времени сохранено", "good")
showCursor(false)
end
else
renderFontDrawText(renderTimeFont, text, config.additional.timeX, config.additional.timeY,
tonumber("0xFF" .. config.additional.timeColor), false)
end
end
function tickAnotherTime()
if not config.additional.anothertime then
if sampTextdrawIsExists(223) then sampTextdrawDelete(223) end
return
end
local date_table = os.date("*t", getTime)
local ms = tonumber(string.sub(tostring(math.ceil(socket.gettime() * 1000)), -3))
local text = config.additional.showseconds
and string.format("%02d:%02d:%02d:%03d", date_table.hour, date_table.min, date_table.sec, ms)
or os.date("%H:%M:%S", getTime)
sampTextdrawCreate(223, text, config.additional.timeServerPosX, config.additional.timeServerPosY)
sampTextdrawSetLetterSizeAndColor(223, config.additional.servertimeSizeX, config.additional.servertimeSizeY, "0xFF" .. config.additional.servertimeColor)
sampTextdrawSetOutlineColor(223, 0.5, 0xFF000000)
sampTextdrawSetAlign(223, 1)
sampTextdrawSetStyle(223, config.additional.servertimeStyle)
end
function tickCaptcha()
local result, button, _, input = sampHasDialogRespond(trainingDlgId)
if not result then return end
time2 = string.format("%.3f", os.clock() - captime)
button, input = trButt, trInput -- от слова жопа
if button == 1 then
if input == captcha .. '0' then
config.captcha.vcode = config.captcha.vcode + 1
if config.main.newtimer then
printStyledString('~g~' .. time2 .. ' sec!', 1000, 7)
else
msg(string.format('{ffffff}Верный код! [%.3f]', time2), "good")
end
if os.clock() - captime < config.captcha.record or config.captcha.record == 0 then
config.captcha.record = floorStep(os.clock() - captime, 0.001)
end
else
config.captcha.ncode = config.captcha.ncode + 1
if config.main.newtimer then
printStyledString('~r~' .. time2 .. ' sec!', 1000, 7)
else
msg(string.format('{ffffff}Неверный код! [%.3f] (' .. captcha .. '0|' .. input .. ')', time2), "bad")
end
end
end
trButt, trInput = 0, ''
removeTextdraws()
end
function show_arz_notify(type, title, text, time)
local function escape_js(s)
return s:gsub("\\", "\\\\"):gsub('"', '\\"')
end
local safe_type = escape_js(type)
local safe_title = escape_js(title)
local safe_text = escape_js(text)
local safe_time = tostring(time)
local str = ('window.executeEvent("event.notify.initialize", "[\\"%s\\", \\"%s\\", \\"%s\\", \\"%s\\"]");'):format(safe_type, safe_title, safe_text, safe_time)
visualCEF(str, true)
end
function visualCEF(str, is_encoded)
local bs = raknetNewBitStream()
raknetBitStreamWriteInt8(bs, 17)
raknetBitStreamWriteInt32(bs, 0)
raknetBitStreamWriteInt16(bs, #str)
raknetBitStreamWriteInt8(bs, is_encoded and 1 or 0)
if is_encoded then
raknetBitStreamEncodeString(bs, str)
else
raknetBitStreamWriteString(bs, str)
end
raknetEmulPacketReceiveBitStream(220, bs)
raknetDeleteBitStream(bs)
end
function imgui.Link(link, text)
text = text or link
local tSize = imgui.CalcTextSize(text)
local p = imgui.GetCursorScreenPos()
local DL = imgui.GetWindowDrawList()
local col = { 0xFFFF7700, 0xFFFF9900 }
if imgui.InvisibleButton("##" .. link, tSize) then os.execute("explorer " .. link) end
local color = imgui.IsItemHovered() and col[1] or col[2]
DL:AddText(p, color, text)
DL:AddLine(imgui.ImVec2(p.x, p.y + tSize.y), imgui.ImVec2(p.x + tSize.x, p.y + tSize.y), color)
end
function imgui.Theme()
imgui.SwitchContext()
local style = imgui.GetStyle()
local colors = style.Colors
--==[ STYLE ]==--
imgui.GetStyle().WindowPadding = imgui.ImVec2(5, 5)
imgui.GetStyle().FramePadding = imgui.ImVec2(5, 5)
imgui.GetStyle().ItemSpacing = imgui.ImVec2(5, 5)
imgui.GetStyle().ItemInnerSpacing = imgui.ImVec2(2, 2)
imgui.GetStyle().TouchExtraPadding = imgui.ImVec2(0, 0)
imgui.GetStyle().IndentSpacing = 0
imgui.GetStyle().ScrollbarSize = 10
imgui.GetStyle().GrabMinSize = 10
--==[ BORDER ]==--
imgui.GetStyle().WindowBorderSize = 1
imgui.GetStyle().ChildBorderSize = 1
imgui.GetStyle().PopupBorderSize = 1
imgui.GetStyle().FrameBorderSize = 1
imgui.GetStyle().TabBorderSize = 1
--==[ ROUNDING ]==--
imgui.GetStyle().WindowRounding = 5
imgui.GetStyle().ChildRounding = 0
imgui.GetStyle().FrameRounding = 5
imgui.GetStyle().PopupRounding = 5
imgui.GetStyle().ScrollbarRounding = 5
imgui.GetStyle().GrabRounding = 5
imgui.GetStyle().TabRounding = 5
--==[ ALIGN ]==--
imgui.GetStyle().WindowTitleAlign = imgui.ImVec2(0.5, 0.5)
imgui.GetStyle().ButtonTextAlign = imgui.ImVec2(0.5, 0.5)
imgui.GetStyle().SelectableTextAlign = imgui.ImVec2(0.5, 0.5)
--==[ COLORS ]==--
colors[imgui.Col.Text] = imgui.ImVec4(0.95, 0.96, 0.98, 1.00)
colors[imgui.Col.TextDisabled] = imgui.ImVec4(0.60, 0.60, 0.60, 1.00)
colors[imgui.Col.WindowBg] = imgui.ImVec4(0.15, 0.10, 0.10, 1.00)
colors[imgui.Col.ChildBg] = imgui.ImVec4(0.15, 0.10, 0.10, 1.00)
colors[imgui.Col.PopupBg] = imgui.ImVec4(0.15, 0.10, 0.10, 0.95)
colors[imgui.Col.Border] = imgui.ImVec4(0.50, 0.50, 0.50, 0.50)
colors[imgui.Col.BorderShadow] = imgui.ImVec4(0.00, 0.00, 0.00, 0.00)
colors[imgui.Col.FrameBg] = imgui.ImVec4(0.25, 0.10, 0.10, 1.00)
colors[imgui.Col.FrameBgHovered] = imgui.ImVec4(0.40, 0.10, 0.10, 1.00)
colors[imgui.Col.FrameBgActive] = imgui.ImVec4(0.60, 0.10, 0.10, 1.00)
colors[imgui.Col.TitleBg] = imgui.ImVec4(0.15, 0.10, 0.10, 1.00)
colors[imgui.Col.TitleBgActive] = imgui.ImVec4(0.25, 0.10, 0.10, 1.00)
colors[imgui.Col.TitleBgCollapsed] = imgui.ImVec4(0.15, 0.10, 0.10, 0.75)
colors[imgui.Col.ScrollbarBg] = imgui.ImVec4(0.15, 0.10, 0.10, 0.60)
colors[imgui.Col.ScrollbarGrab] = imgui.ImVec4(0.80, 0.20, 0.20, 0.80)
colors[imgui.Col.ScrollbarGrabHovered] = imgui.ImVec4(0.90, 0.30, 0.30, 0.80)
colors[imgui.Col.ScrollbarGrabActive] = imgui.ImVec4(0.95, 0.40, 0.40, 1.00)
colors[imgui.Col.Button] = imgui.ImVec4(0.20, 0.10, 0.10, 1.00)
colors[imgui.Col.ButtonHovered] = imgui.ImVec4(0.30, 0.10, 0.10, 1.00)
colors[imgui.Col.ButtonActive] = imgui.ImVec4(0.40, 0.10, 0.10, 1.00)
colors[imgui.Col.Header] = imgui.ImVec4(0.20, 0.10, 0.10, 1.00)
colors[imgui.Col.HeaderHovered] = imgui.ImVec4(0.40, 0.10, 0.10, 1.00)
colors[imgui.Col.HeaderActive] = imgui.ImVec4(0.60, 0.10, 0.10, 1.00)
colors[imgui.Col.Tab] = imgui.ImVec4(0.20, 0.10, 0.10, 1.00)
colors[imgui.Col.TabHovered] = imgui.ImVec4(0.40, 0.10, 0.10, 1.00)
colors[imgui.Col.TabActive] = imgui.ImVec4(0.60, 0.10, 0.10, 1.00)
colors[imgui.Col.PlotLines] = imgui.ImVec4(0.80, 0.20, 0.20, 1.00)
colors[imgui.Col.PlotLinesHovered] = imgui.ImVec4(0.90, 0.30, 0.30, 1.00)
colors[imgui.Col.PlotHistogram] = imgui.ImVec4(0.80, 0.20, 0.20, 1.00)
colors[imgui.Col.PlotHistogramHovered] = imgui.ImVec4(0.90, 0.30, 0.30, 1.00)
colors[imgui.Col.TextSelectedBg] = imgui.ImVec4(0.30, 0.60, 0.85, 0.35)
colors[imgui.Col.DragDropTarget] = imgui.ImVec4(0.85, 0.60, 0.40, 0.90)
colors[imgui.Col.NavHighlight] = imgui.ImVec4(0.80, 0.30, 0.30, 1.00)
colors[imgui.Col.NavWindowingHighlight] = imgui.ImVec4(0.90, 0.50, 0.50, 0.70)
colors[imgui.Col.NavWindowingDimBg] = imgui.ImVec4(0.20, 0.20, 0.25, 0.20)
colors[imgui.Col.CheckMark] = imgui.ImVec4(0.90, 0.10, 0.10, 1.00)
colors[imgui.Col.ModalWindowDimBg] = imgui.ImVec4(0.20, 0.20, 0.25, 0.35)
ffgoodcolor = '22A872'
ffbadcolor = 'A83022'
goodcolor = '{22A872}'
badcolor = '{A83022}'
tag = badcolor..'['..ownname..']: {FFFFFF}'
gtag = goodcolor..'['..ownname..']: {FFFFFF}'
end
local renderWindow = new.bool()
imgui.OnInitialize(function()
local glyph_ranges = imgui.GetIO().Fonts:GetGlyphRangesCyrillic()
imgui.GetIO().Fonts:Clear()
-- imgLogo = imgui.CreateTextureFromFileInMemory(imgui.new('const char*', logo_data), #logo_data)
local function mergeIcons(size)
local cfg = imgui.ImFontConfig()
cfg.MergeMode = true
cfg.PixelSnapH = true
imgui.GetIO().Fonts:AddFontFromMemoryCompressedBase85TTF(
faicons.get_font_data_base85('solid'), size, cfg, iconRanges)
end
iconRanges = imgui.new.ImWchar[3](faicons.min_range, faicons.max_range, 0)
imgui.GetIO().Fonts:AddFontFromMemoryCompressedBase85TTF(default_compressed_data_base85, 14.0, nil, glyph_ranges)
mergeIcons(14)
font_small = imgui.GetIO().Fonts:AddFontFromMemoryCompressedBase85TTF(default_compressed_data_base85, 12.0, nil, glyph_ranges)
mergeIcons(12)
font_title = imgui.GetIO().Fonts:AddFontFromMemoryCompressedBase85TTF(bold_compressed_data_base85, 19.0, nil, glyph_ranges)
mergeIcons(19)
imgui.GetIO().IniFilename = nil
imgui.Theme()
end)
local newFrame = imgui.OnFrame(
function() return renderWindow[0] end,
function(player)
imgui.SetNextWindowPos(imgui.ImVec2(posX, posY), imgui.Cond.FirstUseEver, imgui.ImVec2(1, 1))
imgui.SetNextWindowSize(imgui.ImVec2(520, 360), imgui.Cond.Always)
imgui.Begin('##main', renderWindow, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse)
local dl = imgui.GetWindowDrawList()
imgui.BeginChild('##sidebar', imgui.ImVec2(190, -1), false)
imgui.SetCursorPos(imgui.ImVec2(14, 14))
imgui.PushFont(font_title)
imgui.Text(ownname)
imgui.PopFont()
imgui.SetCursorPos(imgui.ImVec2(14, 32))
imgui.Text(u8('v' .. version))
imgui.SetCursorPosY(58)
imgui.Separator()
imgui.Dummy(imgui.ImVec2(0, 15))
tabButton(u8' Работа с капчей', 1, 180)
tabButton(u8' Визуальные скрипты', 2, 180)
tabButton(u8' Помощь в ловле', 3, 180)
tabButton(u8' Настройки', 4, 180)
imgui.SetCursorPosY(imgui.GetWindowHeight() - 56)
imgui.Separator()
imgui.SetCursorPosY(imgui.GetWindowHeight() - 40)
drawAvatar(dl, imgui.GetCursorScreenPos().x + 20, imgui.GetCursorScreenPos().y + 14, 14, nickname)
imgui.SetCursorPos(imgui.ImVec2(43, imgui.GetWindowHeight() - 42))
imgui.PushFont(font_title)
imgui.Text(u8(nickname))
imgui.PopFont()
imgui.SetCursorPos(imgui.ImVec2(43, imgui.GetWindowHeight() - 26))
imgui.PushFont(font_small)
imgui.Text(u8(server_city .. ' · ' .. date_str))
imgui.PopFont()
imgui.EndChild()
dl:AddLine(
imgui.ImVec2(imgui.GetWindowPos().x + 195, imgui.GetWindowPos().y + 24),
imgui.ImVec2(imgui.GetWindowPos().x + 195, imgui.GetWindowPos().y + imgui.GetWindowHeight() - 1),
0xFF4D444A, 1.0
)
dl:AddRectFilled(
imgui.ImVec2(imgui.GetWindowPos().x + 197, imgui.GetWindowPos().y - 2),
imgui.ImVec2(imgui.GetWindowPos().x + imgui.GetWindowWidth() + 1, imgui.GetWindowPos().y + imgui.GetWindowHeight() - 2),
0xFF191926
)
imgui.SameLine()
imgui.SetCursorPosX(200)
imgui.PushStyleColor(imgui.Col.ChildBg, imgui.ImVec4(0, 0, 0, 0))
imgui.BeginChild('##content', imgui.ImVec2(-1, -1), false)
imgui.Dummy(imgui.ImVec2(0, 5))
if active_tab == 1 then
SEP_FISRT_COLUMN = 200
imgui.Separator()
imgui.Dummy(imgui.ImVec2(0, 5))
switchButton('Таймер ввода капчи', config.main, 'timer')
if not isLauncherActive then switchButton('Таймер на экране', config.main, 'newtimer') end -- аРИЗОНА ГОВНО
switchButton('Время ввода в строке покупки', config.main, 'jt')
switchButton('Сообщение после покупки имущества', config.main, 'textlovlya')
if config.main.textlovlya then
SEP_FISRT_COLUMN = SEP_FISRT_COLUMN + 80
if imgui.InputText('##textbuffer', buffer, sizeof(buffer) - 1) then
config.main.text = u8:decode(str(buffer))
end
switchButton('Время в сообщении', config.main, 'texttime')
switchButton('Капча в сообщении', config.main, 'textcap')
end
imgui.Dummy(imgui.ImVec2(0, 1))
imgui.Separator()
imgui.Dummy(imgui.ImVec2(0, 3))
switchButton('Центрирование капчи', config.main, 'kapcheb')
if config.main.kapcheb then
SEP_FISRT_COLUMN = SEP_FISRT_COLUMN + 30
imgui.PushItemWidth(100)
imgui.SetCursorPosX(5)
if imgui.InputInt('##kapchebX', kapchebbX, 10, 0) then
config.main.kapchebX = tonumber(kapchebbX[0])
inicfg.save(config, "project_fraktura")
end
imgui.SameLine()
if imgui.InputInt('##kapchebY', kapchebbY, 10, 0) then
config.main.kapchebY = tonumber(kapchebbY[0])
inicfg.save(config, "project_fraktura")
end
imgui.PopItemWidth()
end
ia.Hint('##kapcheb', u8'При появлении капчи, она будет выставляться точно по центру', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
switchButton('Тренировка капчи', config.additional, 'captrain')
if config.additional.captrain then
SEP_FISRT_COLUMN = SEP_FISRT_COLUMN + 30
imgui.SameLine()
if trainbuff:ShowHotKey() then
config.additional.captrainkey = encodeJson(trainbuff:GetHotKey())
inicfg.save(config, "project_fraktura")
end
switchButton('Рандомная задержка', config.additional, 'customizeddelay')
ia.Hint('##customizeddelay', u8'Задержка после нажатия клавиши открытия капчи', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
end
imgui.SetCursorPosY(SEP_FISRT_COLUMN)
imgui.Separator()
elseif active_tab == 2 then
SEP_SECOND_COLUMN = 160
imgui.Separator()
imgui.Dummy(imgui.ImVec2(0, 5))
switchButton('Анти баттл-пас', config.additional, 'antibattlepass')
ia.Hint('##antibp', u8'Не открывает баттл-пас при нажатии на B', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
switchButton('Анти /wbook', config.additional, 'antiwbook')
ia.Hint('##antiwb', u8'Не открывает меню организации при нажатии на M, команда всё ещё работает', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
if not isLauncherActive then
SEP_SECOND_COLUMN = SEP_SECOND_COLUMN + 30
switchButton('Fogdist', config.additional, 'fd')
ia.Hint('##fogdist', u8'Смена прорисовки по команде в чат. На лаунчере не работает', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
if config.additional.fd then
if not isLauncherActive then
imgui.SameLine()
imgui.PushItemWidth(90)
if imgui.InputText('##fdcommand', fdbuf, sizeof(fdbuf) - 1) then
config.additional.fdc = u8:decode(str(fdbuf))
end
imgui.PopItemWidth()
ia.Hint('##fdcom', u8'Команда для смены прорисовки. Для её активации - введите команду, а затем выключите и включите переключатель', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
end
end
else
config.additional.fd = false
end
switchButton('Смена погоды и времени', config.additional, 'settime')
ia.Hint('##settime', u8'Смена времени и погоды', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
if config.additional.settime then
SEP_SECOND_COLUMN = SEP_SECOND_COLUMN + 30
imgui.PushItemWidth(75)
if imgui.InputText('##stcommand', stbuf, sizeof(stbuf) - 1) then
config.additional.stc = u8:decode(str(stbuf))
end
imgui.PopItemWidth()
ia.Hint('##stcom', u8'Команда для смены времени. Для её активации - введите команду, а затем выключите и включите переключатель', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
imgui.SameLine()
imgui.PushItemWidth(75)
if imgui.InputText('##swcommand', swbuf, sizeof(swbuf) - 1) then
config.additional.swc = u8:decode(str(swbuf))
end
imgui.PopItemWidth()
ia.Hint('##swcom', u8'Команда для смены погоды. Для её активации - введите команду, а затем выключите и включите переключатель', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
end
switchButton('CTime', config.additional, 'servertime')
ia.Hint('##ctime', u8'ЦТайм, или же время на экран', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
if config.additional.servertime then
imgui.SameLine()
if imgui.Button(faicons('gear')) then timeSettings = true end
end
switchButton('Server time', config.additional, 'anothertime')
ia.Hint('##servertime', u8'Время на экране, но в другом стиле', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
if config.additional.anothertime then
imgui.SameLine()
if imgui.Button(faicons('gears')) then anotherSettings = true end
end
imgui.SetCursorPosY(SEP_SECOND_COLUMN)
imgui.Separator()
elseif active_tab == 3 then
SEP_THIRD_COLUMN = 280
imgui.Separator()
imgui.Dummy(imgui.ImVec2(0, 5))
if permissions.spilkpk then
switchButton('Спиливание передний дверей', config.additional, 'popcardoors')
ia.Hint('##kpkgobombmyhouse', u8'При активации, у транспорта в который вы сядете спилятся двери', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
else
config.additional.popcardoors = false
end
if permissions.carejector then
switchButton('Авто-выкидывание людей из транспорта', config.additional, 'carejector')
ia.Hint('##autoejector', u8'При активации, будет выкидывать всех, кто сел в машину', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
else
config.additional.carejector = false
end
if not isLauncherActive then
if permissions.quickmap then
switchButton('Быстрое открытие карты', config.additional, 'quickmap')
ia.Hint('##quickmap', u8'При зажатии заданной клавиши, у вас откроется мапа', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
if config.additional.quickmap then
imgui.SameLine()
if quickmapbuff:ShowHotKey() then
config.additional.quickmapkey = encodeJson(quickmapbuff:GetHotKey())
inicfg.save(config, "project_fraktura")
end
end
else
config.additional.quickmap = false
end
end
if permissions.fastmap then
switchButton('Фаст-мап', config.additional, 'fastmap')
ia.Hint('##fastmap', u8'При активации, при зажатии назначенной клавиши будет рендерится карта', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
if config.additional.fastmap then
imgui.SameLine()
if fastmapbuff:ShowHotKey() then
config.additional.fastmapkey = encodeJson(fastmapbuff:GetHotKey())
inicfg.save(config, "project_fraktura")
end
end
else
config.additional.fastmap = false
end
if permissions.tracer then
switchButton('Трейсер до метки', config.additional, 'wpline')
ia.Hint('##wplinehaha', u8'Рисует трейсер при нажатии на первую клавишу. Вторая включает/выключает её отображение', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
if config.additional.wpline then
imgui.SameLine()
if wplinebuff:ShowHotKey() then
config.additional.wplinekey = encodeJson(wplinebuff:GetHotKey())
inicfg.save(config, "project_fraktura")
end
imgui.SameLine()
if wptogglebuff:ShowHotKey() then
config.additional.wptogglekey = encodeJson(wptogglebuff:GetHotKey())
inicfg.save(config, "project_fraktura")
end
end
else
config.additional.wpline = false
end
imgui.Dummy(imgui.ImVec2(0, 1))
imgui.SetCursorPosY(160)
imgui.Separator()
imgui.Dummy(imgui.ImVec2(0, 3))
switchButton('Хот-кей на домкрат', config.additional, 'domkrat')
if config.additional.domkrat then
imgui.SameLine()
if domkratbuff:ShowHotKey() then
config.additional.domkratkey = encodeJson(domkratbuff:GetHotKey())
inicfg.save(config, "project_fraktura")
end
end
switchButton('Хот-кей на адреналин', config.additional, 'adrenaline')
if config.additional.adrenaline then
imgui.SameLine()
if adrenalinebuff:ShowHotKey() then
config.additional.adrenalinekey = encodeJson(adrenalinebuff:GetHotKey())
inicfg.save(config, "project_fraktura")
end
end
switchButton('Хот-кей на спорт-режим', config.additional, 'sport')
if config.additional.sport then
imgui.SameLine()
if sportbuff:ShowHotKey() then
config.additional.sportkey = encodeJson(sportbuff:GetHotKey())
inicfg.save(config, "project_fraktura")
end
end
switchButton('Хот-кей на сбив анимации', config.additional, 'sbiv')
if config.additional.sbiv then
imgui.SameLine()
if sbivbuff:ShowHotKey() then
config.additional.sbivkey = encodeJson(sbivbuff:GetHotKey())
inicfg.save(config, "project_fraktura")
end
end
imgui.SetCursorPosY(SEP_THIRD_COLUMN)
imgui.Separator()
elseif active_tab == 4 then
SEP_LAST_COLUMN = 290
imgui.SetCursorPosX(5)
imgui.Link("https://www.youtube.com/@Nysson13", u8"Ссылка на мой ютуб-канал")
imgui.SameLine()
imgui.SetCursorPosX(240)
imgui.Link("https://t.me/blackw1ndow", u8"разработчик")
imgui.Dummy(imgui.ImVec2(0, 2))
imgui.Separator()
imgui.Dummy(imgui.ImVec2(0, 5))
switchButton('Выключить авто-обновления', config.customization, 'disableautoupdate')
switchButton('Перекраска сообщений о покупке имущества', config.customization, 'recolor')
imgui.Dummy(imgui.ImVec2(0, 1))
imgui.Separator()
imgui.Dummy(imgui.ImVec2(0, 3))
imgui.Text(u8'Информация по вводу капчи:')
imgui.Text(u8'Всего капч введено: '..config.captcha.vcode + config.captcha.ncode)
imgui.Text(u8'Верных кодов: '..config.captcha.vcode)
imgui.Text(u8'Неверных кодов: '..config.captcha.ncode)
imgui.Text(u8'Рекорд ввода капчи: '..config.captcha.record)
imgui.SetCursorPosY(SEP_LAST_COLUMN)
imgui.Separator()
imgui.SetCursorPosX(5)
if imgui.Button(faicons('power_off')) then thisScript():unload() end
ia.Hint('##offnitvar', u8'Выключить скрипт.')
if imgui.Button(faicons('trash'), imgui.SameLine()) then
if doesFileExist(thisScript().filename)then
os.remove(thisScript().filename)
end
if doesFileExist('moonloader\\config\\project_fraktura.ini') then
os.remove('moonloader\\config\\project_fraktura.ini')
end
thisScript():unload()
end
ia.Hint('##nenadadyadya', u8'Удалить скрипт.')
if imgui.Button(faicons('rotate'), imgui.SameLine()) then thisScript():reload() end
ia.Hint('rebut', u8'Перезагрузить скрипт.')
if imgui.Button(faicons('floppy_disk'), imgui.SameLine()) then msg("Настройки успешно сохранены", "good") inicfg.save(config, "project_fraktura") end
ia.Hint('##sohrnastr', u8'Сохранить настройки.')
if imgui.Button(faicons('file_contract'), imgui.SameLine()) then
if doesFileExist('moonloader\\config\\project_fraktura.ini') then
resetConfig = true
thisScript():reload()
end
update_state = true
msg("Настройки успешно сброшены", "good")
end
ia.Hint('stoknastr', u8'Вернуть скрипт к стандартным настройкам.')
if resp and tonumber(resp.info["version_n"]) > version_n then
if ia.MaterialButton(faicons('cloud'), imgui.SameLine()) then
update_state = true
msg("Обновляемся, подождите", "good")
end
ia.Hint('##updaaaaaaate', u8'Кнопка для обновления скрипта, если вы этого ещё не сделали.')
end
if ia.MaterialButton(faicons('comments')..'', imgui.SameLine(285)) then
messageSettings = true
end
ia.Hint('##messagesettings', u8'Кнопка для настройки сообщений', imgui.GetStyle().Colors[imgui.Col.TextDisabled])
end
imgui.EndChild()
imgui.PopStyleColor()
imgui.End()
if messageSettings then imgui.OpenPopup(u8'Настройки сообщений в чат или консоль')
if (imgui.BeginPopupModal(u8'Настройки сообщений в чат или консоль', _, imgui.WindowFlags.AlwaysAutoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse)) then
if imgui.Checkbox(u8'Включить все сообщения в чат', imgui.new.bool(config.messages.chat)) then config.messages.console = false config.messages.silent = false config.messages.chat = not config.messages.chat end
if imgui.Checkbox(u8'Вывод всех сообщения в консоль', imgui.new.bool(config.messages.console)) then config.messages.chat = false config.messages.silent = false config.messages.console = not config.messages.console end
if imgui.Checkbox(u8'Выключить любые сообщения от скрипта', imgui.new.bool(config.messages.silent)) then config.messages.chat = false config.messages.console = false config.messages.silent = not config.messages.silent end
imgui.Separator()
if ia.MaterialButton(u8'Закрыть') then
imgui.CloseCurrentPopup()
messageSettings = false
end
imgui.EndPopup()
end
end
if timeSettings then imgui.OpenPopup(u8'Настройки показа времени')
if (imgui.BeginPopupModal(u8'Настройки показа времени', _, imgui.WindowFlags.AlwaysAutoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse)) then
imgui.Text(u8'Шрифт')
imgui.PushItemWidth(170)
imgui.SameLine()
if imgui.InputText('##11', fontTimeinput, sizeof(fontTimeinput) - 1) then
config.additional.timeFont = u8:decode(str(fontTimeinput))
renderTimeFont = renderCreateFont(config.additional.timeFont, config.additional.timeSize, config.additional.timeStyle)
end
imgui.PopItemWidth()
imgui.Text(u8'Стиль')
imgui.PushItemWidth(90)
imgui.SameLine()
if imgui.InputInt('##12', styleTimeinput, 0, 0) then
config.additional.timeStyle = tonumber(styleTimeinput[0])
renderTimeFont = renderCreateFont(config.additional.timeFont, config.additional.timeSize, config.additional.timeStyle)
inicfg.save(config, "project_fraktura")
end
imgui.PopItemWidth()
imgui.Text(u8'Размер')
imgui.PushItemWidth(90)
imgui.SameLine()
if imgui.InputInt('##13', sizeTimeinput, 0, 0) then
config.additional.timeSize = tonumber(sizeTimeinput[0])
renderTimeFont = renderCreateFont(config.additional.timeFont, config.additional.timeSize, config.additional.timeStyle)
inicfg.save(config, "project_fraktura")
end
imgui.PopItemWidth()
imgui.Text(u8'Цвет')
imgui.PushItemWidth(90)
imgui.SameLine()
if imgui.InputText('##14', timeColorinput, sizeof(timeColorinput) - 1, 0) then
config.additional.timeColor = u8:decode(str(timeColorinput))
inicfg.save(config, "project_fraktura")
end
imgui.PopItemWidth()
if ia.ToggleButton(u8'Показывать миллисекунды', imgui.new.bool(config.additional.showseconds)) then
config.additional.showseconds = not config.additional.showseconds
end
if imgui.Button(u8'Изменить расположение') then
if styleTimeinput[0] < 0 then styleTimeinput[0] = 0 end
if sizeTimeinput[0] < 0 then sizeTimeinput[0] = 0 end
changePos = true
imgui.CloseCurrentPopup()
timeSettings = false
renderWindow[0] = false
msg("Измените расположение времени курсором мыши и нажмите ЛКМ", "bad")
end
if imgui.Button(u8'Закрыть') then
imgui.CloseCurrentPopup()
timeSettings = false
end
imgui.EndPopup()
end
end
if anotherSettings then imgui.OpenPopup(u8'Настройки показа серверного времени')
if (imgui.BeginPopupModal(u8'Настройки показа серверного времени', _, imgui.WindowFlags.AlwaysAutoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoCollapse)) then
if imgui.RadioButtonIntPtr(u8"Стиль 1", styleServerTimeinput, 1, imgui.SameLine()) then
config.additional.servertimeStyle = tonumber(styleServerTimeinput[0])
inicfg.save(config, "project_fraktura")
elseif
imgui.RadioButtonIntPtr(u8"Стиль 2", styleServerTimeinput, 2, imgui.SameLine()) then
config.additional.servertimeStyle = tonumber(styleServerTimeinput[0])
inicfg.save(config, "project_fraktura")
elseif
imgui.RadioButtonIntPtr(u8"Стиль 3", styleServerTimeinput, 3, imgui.SameLine()) then
config.additional.servertimeStyle = tonumber(styleServerTimeinput[0])
inicfg.save(config, "project_fraktura")
end
imgui.Text(u8'Размер X')
imgui.PushItemWidth(120)
imgui.SameLine()
if imgui.InputFloat('##16', sizeServerTimeXinput, 0.1, 0) then
config.additional.servertimeSizeX = tonumber(sizeServerTimeXinput[0])
inicfg.save(config, "project_fraktura")
end
imgui.Text(u8'Размер Y')
imgui.SameLine()
if imgui.InputFloat('##20', sizeServerTimeYinput, 0.1, 0) then
config.additional.servertimeSizeY = tonumber(sizeServerTimeYinput[0])
inicfg.save(config, "project_fraktura")
end
imgui.PopItemWidth()
imgui.Text(u8'Цвет')
imgui.PushItemWidth(90)
imgui.SameLine()
if imgui.InputText('##17', timeServerColorinput, sizeof(timeServerColorinput) - 1, 0) then
config.additional.servertimeColor = u8:decode(str(timeServerColorinput))
inicfg.save(config, "project_fraktura")
end
imgui.PopItemWidth()
if ia.ToggleButton(u8'Показывать миллисекунды', imgui.new.bool(config.additional.showseconds)) then
config.additional.showseconds = not config.additional.showseconds
end
imgui.PushItemWidth(120)
if imgui.InputInt('##18', timeServerPosXinput, 5, 0) then
config.additional.timeServerPosX = tonumber(timeServerPosXinput[0])
inicfg.save(config, "project_fraktura")
end
if imgui.InputInt('##19', timeServerPosYinput, 5, 0) then
config.additional.timeServerPosY = tonumber(timeServerPosYinput[0])
inicfg.save(config, "project_fraktura")
end
imgui.PopItemWidth()
if imgui.Button(u8'Закрыть') then
imgui.CloseCurrentPopup()
anotherSettings = false
end
imgui.EndPopup()
end
end
end
)
function main()
while not isSampAvailable() do wait(0) end
checkUpdates()
checkPermissions()
initResources()
initHotkeys()
sampRegisterChatCommand('fraktura', function()
nickname = getSelfName()
server_city = parseServer()
date_str = os.date('%a') .. ', ' .. os.date('%d') .. ' ' .. os.date('%B')
renderWindow[0] = not renderWindow[0]
end)
if thisScript().filename ~= 'Fraktura.lua' then
os.rename(getGameDirectory() .. "/moonloader/" .. thisScript().filename,
getGameDirectory() .. "/moonloader/Fraktura.lua")
end
msg('Загружен! Активация: ' .. badcolor .. 'F2 {ffffff}или ' .. badcolor ..'/fraktura', "bad")
addEventHandler('onWindowMessage', function(var_msg, wparam, lparam)
if var_msg == wm.WM_KEYDOWN or var_msg == wm.WM_SYSKEYDOWN then
if wparam == vkeys.VK_F2 then
nickname = getSelfName()
server_city = parseServer()
date_str = os.date('%a') .. ', ' .. os.date('%d') .. ' ' .. os.date('%B')
renderWindow[0] = not renderWindow[0]
end
end
if var_msg == 0x001C and wparam == 1 then
hotkey.ActiveKeys = {}
end
--if var_msg == 641 or var_msg == 642 or lparam == -1073741809 then hotkey.ActiveKeys = {} end -- один раз китайца выебали так его и назвали, Хуяо
if var_msg == 0x100 or var_msg == 0x101 then
if wparam == vkeys.VK_ESCAPE and renderWindow[0] and not isPauseMenuActive() then
consumeWindowMessage(true, false)
renderWindow[0] = false
end
if config.additional.antibattlepass and wparam == vkeys.VK_B then
consumeWindowMessage(true, false)
end
if config.additional.antiwbook and wparam == vkeys.VK_M then
consumeWindowMessage(true, false)
end
end
end)
while true do
wait(0)
getTime = os.time() + servernoe
if update_state then
downloadUrlToFile(script_url, thisScript().path, function(id, status, err)
if status == dlstatus.STATUS_ENDDOWNLOADDATA then
msg("Скрипт успешно обновлен!", "good")
thisScript():reload()
end
end)
break
end
tickCarDoors()
tickQuickmap()
tickFastmap()
tickServerTime()
tickAnotherTime()
tickCaptcha()
if config.additional.wpline and hasWp then drawWpTracer() end
if config.additional.fastmap then renderMap() end
end
end
function ev.onPassengerSync(player_id, passengersyncdata)
local nick = sampGetPlayerNickname(player_id)
if config.additional.carejector and ((os.clock() - lasttry) > (interval/1000)) then
if player_id ~= select(2,sampGetPlayerIdByCharHandle(PLAYER_HANDLE)) then
lasttry = os.clock()
sampSendChat(("/eject %s"):format(player_id))
end
end
end
function ev.onShowTextDraw(textdrawId, data)
if config.main.kapcheb then
if data.boxColor == -2139062144 and data.backgroundColor == -16777216 and data.letterColor == -6054539 then
kapchebX = data.position.x
kapchebY = data.position.y
for kapchebId = 2000, 2400 do
if sampTextdrawIsExists(kapchebId) then
posX, posY = sampTextdrawGetPos(kapchebId)
if posX < 450 and posY < 170 then
posX = posX - kapchebX + config.main.kapchebX
posY = posY - kapchebY + config.main.kapchebY
letSizeX, letSizeY, color1 = sampTextdrawGetLetterSizeAndColor(kapchebId)
box, color2, sizeX, sizeY = sampTextdrawGetBoxEnabledColorAndSize(kapchebId)
if tonumber(box) == tonumber(1) and tonumber(color1) == tonumber(4292993505) and tonumber(color2) == tonumber(4279903282) then
sizeX = sizeX - kapchebX + config.main.kapchebX + 1
sampTextdrawSetBoxColorAndSize(kapchebId, box, color2, sizeX, sizeY)
end
sampTextdrawSetPos(kapchebId, posX, posY)
end
end
end
data.position.x,data.position.y = config.main.kapchebX, config.main.kapchebY
return {textdrawId, data}
end
end
end
function ev.onShowDialog(id, style, title, b1, b2, text)
if title:find("Откуда вы о нас узнали") then
show_arz_notify('info','Информация','При регистрации на ник Nysson_Inmayhearti ты получишь 50КК на 6 уровне!', 5000)
end
if title:find("Введите ник пригласившего") then
show_arz_notify('info','Информация','За получением отписывать сюда: @prokachkamirage', 5000)
end
if title:find("Проверка на робота") then
did = id
start = os.clock()
end
if string.match(text, "Текущее время") then -- by valerii kalashnikov
chislo, mesyac, god = string.match(text, "Сегодняшняя дата: {2EA42E}(%d+):(%d+):(%d+)")
chas, minuti, sekundi = string.match(text, "Текущее время: {345690}(%d+):(%d+):(%d+)")
datetime = {year = god,month = mesyac,day = chislo,hour = chas,min = minuti,sec = sekundi}
servernoe = tostring(os.time(datetime)) - os.time()
end
end
function ev.onSendDialogResponse(id, but, lis, input)
if id == trainingDlgId then
trButt = but
trInput = input
end
curDlgInput = input
if id == did then
time = os.clock() - start
time1 = string.format("%.3f", time)
if config.main.timer and time ~= nil then
msg('You entered captcha: '.. goodcolor ..'['..input..']{FFFFFF}, time: '.. goodcolor ..'['..time1..']{FFFFFF}', "good")
end
if config.main.newtimer and time ~= nil then
printStyledString('~y~'..time1..' sec!', 3000, 7)
end
end
end
function ev.onSendCommand(str)
local cmd, args = str:match('^/(%S+)%s*(.*)')
if not cmd then return end
cmd = cmd:lower()
if config.additional.fd and not isLauncherActive then
if cmd == config.additional.fdc:lower() then
setFogDistance(args)
return false
end
end
if config.additional.settime then
if cmd == config.additional.stc:lower() then
setWorldTime(args)
return false
end
if cmd == config.additional.swc:lower() then
setWorldWeather(args)
return false
end
end
end
function ev.onSendClientJoin(Ver, mod, nick, response, authKey, clientver, unk)
if clientver == 'Arizona PC' then isLauncherActive = true end
end
function ev.onServerMessage(color, text)
if text:find('{90EE90}Поздравляем! Теперь этот транспорт принадлежит вам!') then
config.captcha.vcode = config.captcha.vcode + 1
if time < config.captcha.record or config.captcha.record == 0 then
config.captcha.record = floorStep(time, 0.001)
end
if config.main.textlovlya then
if config.main.texttime and config.main.textcap then sampSendChat(string.format('%s [%.3f] ['..curDlgInput..']', config.main.text, time))
elseif config.main.texttime then sampSendChat(string.format('%s [%.3f]', config.main.text, time))
elseif config.main.textcap then sampSendChat(string.format('%s ['..curDlgInput..']', config.main.text))
else sampSendChat((config.main.text)) end
end
if config.customization.recolor and config.main.jt and time ~= nil then
sampAddChatMessage(string.format(goodcolor ..'Поздравляем! Теперь этот транспорт принадлежит вам! [%.3f]', time), -1)
return false
elseif config.main.jt and time ~= nil then
sampAddChatMessage(string.format('{90EE90}Поздравляем! Теперь этот транспорт принадлежит вам! [%.3f]', time), -1)
return false
elseif config.customization.recolor then
sampAddChatMessage(goodcolor ..'Поздравляем! Теперь этот транспорт принадлежит вам!', -1)
return false
end
end
if string.find(text, 'PC LAUNCHER') then isLauncherActive = true return false end
if text:find("выкинул") then
if config.additional.carejector then
config.additional.carejector = false
end
end
if text:find('этот бизнес ваш!') and color == 1941201407 then
config.captcha.vcode = config.captcha.vcode + 1
if time < config.captcha.record or config.captcha.record == 0 then
config.captcha.record = floorStep(time, 0.001)
end
if config.main.textlovlya then
if config.main.texttime and config.main.textcap then sampSendChat(string.format('%s [%.3f] ['..curDlgInput..']', config.main.text, time))
elseif config.main.texttime then sampSendChat(string.format('%s [%.3f]', config.main.text, time))
elseif config.main.textcap then sampSendChat(string.format('%s ['..curDlgInput..']', config.main.text))
else sampSendChat((config.main.text)) end
end
if config.customization.recolor and config.main.jt and time ~= nil then
sampAddChatMessage(string.format(goodcolor ..'[Информация] {FFFFFF}Поздравляю! Теперь этот бизнес ваш! [%.3f]', time), -1)
return false
elseif config.main.jt and time ~= nil then
sampAddChatMessage(string.format('{73B461}[Информация] {FFFFFF}Поздравляю! Теперь этот бизнес ваш! [%.3f]', time), -1)
return false
elseif config.customization.recolor then
sampAddChatMessage(goodcolor ..'[Информация] {FFFFFF}Поздравляю! Теперь этот бизнес ваш!', -1)
return false
end
end
if text:find('этот дом ваш!') and color == 1941201407 then
config.captcha.vcode = config.captcha.vcode + 1
if time < config.captcha.record or config.captcha.record == 0 then
config.captcha.record = floorStep(time, 0.001)
end
if config.main.textlovlya then
if config.main.texttime and config.main.textcap then sampSendChat(string.format('%s [%.3f] ['..curDlgInput..']', config.main.text, time))
elseif config.main.texttime then sampSendChat(string.format('%s [%.3f]', config.main.text, time))
elseif config.main.textcap then sampSendChat(string.format('%s ['..curDlgInput..']', config.main.text))
else sampSendChat((config.main.text)) end
end
if config.customization.recolor and config.main.jt and time ~= nil then
sampAddChatMessage(string.format(goodcolor ..'[Информация] {FFFFFF}Поздравляю! Теперь этот дом ваш! [%.3f]', time), -1)
return false
elseif config.main.jt and time ~= nil then
sampAddChatMessage(string.format('{73B461}[Информация] {FFFFFF}Поздравляю! Теперь этот дом ваш! [%.3f]', time), -1)
return false
elseif config.customization.recolor then
sampAddChatMessage(goodcolor ..'[Информация] {FFFFFF}Поздравляю! Теперь этот дом ваш!', -1)
return false
end
end
if text:find('Ответ неверный!') and color == -10270721 then
config.captcha.ncode = config.captcha.ncode + 1
if config.customization.recolor and config.main.jt and time ~= nil then
sampAddChatMessage(string.format(badcolor ..'[Ошибка] {FFFFFF}Ответ неверный! [%.3f]', time), -1)
return false
elseif config.main.jt and time ~= nil then
sampAddChatMessage(string.format('{FF6347}[Ошибка] {FFFFFF}Ответ неверный! [%.3f]', time), -1)
return false
elseif config.customization.recolor then
sampAddChatMessage(badcolor ..'[Ошибка] {FFFFFF}Ответ неверный!', -1)
return false
end
end
if text:find('Неверный код!') and color == -10270721 then
config.captcha.ncode = config.captcha.ncode + 1
if config.customization.recolor and config.main.jt and time ~= nil then
sampAddChatMessage(string.format(badcolor ..'[Ошибка] {FFFFFF}Неверный код! [%.3f]', time), -1)
return false
elseif config.main.jt and time ~= nil then
sampAddChatMessage(string.format('{FF6347}[Ошибка] {FFFFFF}Неверный код! [%.3f]', time), -1)
return false
elseif config.customization.recolor then
sampAddChatMessage(badcolor ..'[Ошибка] {FFFFFF}Неверный код!', -1)
return false
end
end
if text:find('Этот дом уже куплен!') and color == -10270721 then
if config.customization.recolor and config.main.jt and time ~= nil then
sampAddChatMessage(string.format(badcolor ..'[Ошибка] {FFFFFF}Этот дом уже куплен! [%.3f]', time), -1)
return false
elseif config.main.jt and time ~= nil then
sampAddChatMessage(string.format('{FF6347}[Ошибка] {FFFFFF}Этот дом уже куплен! [%.3f]', time), -1)
return false
elseif config.customization.recolor then
sampAddChatMessage(badcolor ..'[Ошибка] {FFFFFF}Этот дом уже куплен!', -1)
return false
end
end
if text:find('Этот дом уже кем то куплен!') and color == -10270721 then
if config.customization.recolor and config.main.jt and time ~= nil then
sampAddChatMessage(string.format(badcolor ..'[Ошибка] {FFFFFF}Этот дом уже кем то куплен! [%.3f]', time), -1)
return false
elseif config.main.jt and time ~= nil then
sampAddChatMessage(string.format('{FF6347}[Ошибка] {FFFFFF}Этот дом уже кем то куплен! [%.3f]', time), -1)
return false
elseif config.customization.recolor then
sampAddChatMessage(badcolor ..'[Ошибка] {FFFFFF}Этот дом уже кем то куплен!', -1)
return false
end
end
if text:find('Этот бизнес уже кем то куплен') and (color == -10270721 or color == -1347440641) then
if config.customization.recolor and config.main.jt and time ~= nil then
sampAddChatMessage(string.format(badcolor ..'[Ошибка] {FFFFFF}Этот бизнес уже кем то куплен! [%.3f]', time), -1)
return false
elseif config.main.jt and time ~= nil then
sampAddChatMessage(string.format('{FF6347}[Ошибка] {FFFFFF}Этот бизнес уже кем то куплен! [%.3f]', time), -1)
return false
elseif config.customization.recolor then
sampAddChatMessage(badcolor ..'[Ошибка] {FFFFFF}Этот бизнес уже кем то куплен!', -1)
return false
end
end
if text:find('Не флуди!') and color == -10270721 then
if config.customization.recolor then
sampAddChatMessage(badcolor ..'[Ошибка] {FFFFFF}Не флуди!', -1)
return false
end
end
if text:find('Вы продали ваш бизнес') and color == 1941201407 then
if config.customization.recolor then
sampAddChatMessage(goodcolor ..'[Информация] {FFFFFF}Вы продали ваш бизнес!', -1)
return false
end
end
if text:find('Вы продали ваш дом') and color == 1941201407 then
if config.customization.recolor then
sampAddChatMessage(goodcolor ..'[Информация] {FFFFFF}Вы продали ваш дом!', -1)
return false
end
end
if text:find('Этот дом только недавно слетел, он будет доступен для покупки в течении 3 часов.') and color == -10270721 then
if config.customization.recolor then
sampAddChatMessage(badcolor ..'[Ошибка] {FFFFFF}Этот дом только недавно слетел, он будет доступен для покупки в течении 3 часов.', -1)
return false
end
end
if text:find('Этот бизнес только недавно слетел, он будет доступен для покупки в течении 3 часов.') and color == -10270721 then
if config.customization.recolor then
sampAddChatMessage(badcolor ..'[Ошибка] {FFFFFF}Этот дом только недавно слетел, он будет доступен для покупки в течении 3 часов.', -1)
return false
end
end
if text:find('Капча введена верно!') and color == 1941201407 then
if config.customization.recolor then
sampAddChatMessage(goodcolor ..'[Информация] {FFFFFF}Капча введена верно!', -1)
return false
end
end
end
function floorStep(num, step)
return num - num % step
end
function showCaptcha()
removeTextdraws()
math.randomseed(os.time() * os.clock() * os.clock() * math.random(1, 9999))
local r = math.random()^0.4
if math.random(0, 1) == 1 then r = 1 - r end
local scale = 0.93 + r * (1.06 - 0.94)
t = t + 1
sampTextdrawCreate(t, "LD_SPAC:white", 240, 116)
sampTextdrawSetLetterSizeAndColor(t, 0, 7.3 * scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF1A2432, 404, 0.000000)
t = t + 1
sampTextdrawCreate(t, "LD_SPAC:white", 242, 119)
sampTextdrawSetLetterSizeAndColor(t, 0, 6.5 * scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF759DA3, 400, 0.000000)
nextPos = math.random() * (31 - 30) - 30.5
math.randomseed(os.time() * os.clock())
for i = 1, 4 do
a = math.random(0, 9)
table.insert(captchaTable, a)
captcha = captcha..a
end
for i = 0, 4 do
nextPos = nextPos + math.random() * (31 - 30) + 29.5
t = t + 1
sampTextdrawCreate(t, "usebox", 259 + nextPos, 124)
sampTextdrawSetLetterSizeAndColor(t, 0, (math.random() * (5.3 - 5) + 5) * scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF1A2432, 30, math.random() * (26.5 - 25) + 25)
sampTextdrawSetAlign(t, 2)
if i < 4 then GenerateTextDraw(captchaTable[i + 1], 259 + nextPos, 124, 3 + i * 2, scale)
else GenerateTextDraw(0, 259 + nextPos, 124, 3 + i * 10, scale) end
end
captchaTable = {}
sampShowDialog(trainingDlgId, '{F89168}Тренировка капчи', '{FFFFFF}Введите {C6FB4A}5{FFFFFF} символов, которые\nпоявились у Вас {C6FB4A}на{FFFFFF} экране.', 'Принять', 'Отмена', 1)
captime = os.clock()
end
function removeTextdraws()
if t > 0 then
for i = 1, t do sampTextdrawDelete(i) end
t = 0
captcha = ''
captime = nil
end
end
function GenerateTextDraw(id, PosX, PosY, _, scale)
scale = scale or 1.0
if id == 0 then
t = t + 1
sampTextdrawCreate(t, "LD_SPAC:white", PosX - 5, PosY + 5)
sampTextdrawSetLetterSizeAndColor(t, 0, (math.random()*(4-3)+3)*scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF759DA3, PosX+8, 0.000000)
elseif id == 1 then
for i = 0, 1 do
t = t + 1
if i == 0 then offsetX=2; offsetBX=17 else offsetX=-3; offsetBX=-17 end
sampTextdrawCreate(t, "LD_SPAC:white", PosX-offsetX, PosY)
sampTextdrawSetLetterSizeAndColor(t, 0, 5.7*scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF759DA3, PosX-offsetBX, 0.000000)
end
elseif id == 2 then
for i = 0, 1 do
t = t + 1
if i == 0 then offsetX=-8; offsetY=8; offsetBX=16
else offsetX=8; offsetY=28; offsetBX=-15 end
sampTextdrawCreate(t, "LD_SPAC:white", PosX-offsetX, PosY+offsetY)
sampTextdrawSetLetterSizeAndColor(t, 0, 0.85*scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF759DA3, PosX-offsetBX, 0.000000)
end
elseif id == 3 then
for i = 0, 1 do
t = t + 1
if i == 0 then size=1.1; offsetY=6 else size=1.3; offsetY=25 end
sampTextdrawCreate(t, "LD_SPAC:white", PosX+10, PosY+offsetY)
sampTextdrawSetLetterSizeAndColor(t, 0, size*scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF759DA3, PosX-16.5, 0.000000)
end
elseif id == 4 then
for i = 0, 1 do
t = t + 1
if i == 0 then size=1.6; offsetX=-10; offsetY=0; offsetBX=7
else size=2.75; offsetX=-10; offsetY=25; offsetBX=16 end
sampTextdrawCreate(t, "LD_SPAC:white", PosX-offsetX, PosY+offsetY)
sampTextdrawSetLetterSizeAndColor(t, 0, size*scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF759DA3, PosX-offsetBX, 0.000000)
end
elseif id == 5 then
for i = 0, 1 do
t = t + 1
if i == 0 then size=0.8; offsetX=6; offsetY=7; offsetBX=-15
else size=1.2; offsetX=-10; offsetY=26; offsetBX=16 end
sampTextdrawCreate(t, "LD_SPAC:white", PosX-offsetX, PosY+offsetY)
sampTextdrawSetLetterSizeAndColor(t, 0, size*scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF759DA3, PosX-offsetBX, 0.000000)
end
elseif id == 6 then
for i = 0, 1 do
t = t + 1
if i == 0 then size=1; offsetX=7.5; offsetY=7; offsetBX=-15
else size=1.1; offsetX=-10; offsetY=math.random()*(29-27)+27; offsetBX=10 end
sampTextdrawCreate(t, "LD_SPAC:white", PosX-offsetX, PosY+offsetY)
sampTextdrawSetLetterSizeAndColor(t, 0, size*scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF759DA3, PosX-offsetBX, 0.000000)
end
elseif id == 7 then
t = t + 1
sampTextdrawCreate(t, "LD_SPAC:white", PosX-14, PosY+6)
sampTextdrawSetLetterSizeAndColor(t, 0, 5.1*scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF759DA3, PosX+7, 0.000000)
elseif id == 8 then
local sizefor8 = math.random()*(9-8)+8
for i = 0, 1 do
t = t + 1
if i == 0 then size=1.275; offsetY=8 else size=1.2; offsetY=28 end
sampTextdrawCreate(t, "LD_SPAC:white", PosX+sizefor8, PosY+offsetY)
sampTextdrawSetLetterSizeAndColor(t, 0, size*scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF759DA3, PosX-6, 0.000000)
end
elseif id == 9 then
for i = 0, 1 do
t = t + 1
if i == 0 then size=1.25; offsetY=7; offsetBX=7
else size=1.275; offsetY=26; offsetBX=16 end
sampTextdrawCreate(t, "LD_SPAC:white", PosX+7, PosY+offsetY)
sampTextdrawSetLetterSizeAndColor(t, 0, size*scale, 0x80808080)
sampTextdrawSetBoxColorAndSize(t, 1, 0xFF759DA3, PosX-offsetBX, 0.000000)
end
end
end
function onScriptTerminate(script, quitGame)
if script == thisScript() then
inicfg.save(config, "project_fraktura")
end
if resetConfig then
if doesFileExist('moonloader\\config\\project_fraktura.ini') then
os.remove('moonloader\\config\\project_fraktura.ini')
end
end
end
function onQuitGame()
inicfg.save(config, "project_fraktura")
end
function isPlayerInWorld(interior_id)
local ip, port = sampGetCurrentServerAddress()
local address = ("%s:%s"):format(ip, port)
if address == "80.66.82.147:7777" then -- Vice City
return (interior_id == 20)
end
return (interior_id == 0)
end
function join_argb(a, r, g, b) local argb = b argb = bit.bor(argb, bit.lshift(g, 8)) argb = bit.bor(argb, bit.lshift(r, 16)) argb = bit.bor(argb, bit.lshift(a, 24)) return argb end
function explode_argb(argb) local a = bit.band(bit.rshift(argb, 24), 0xFF) local r = bit.band(bit.rshift(argb, 16), 0xFF) local g = bit.band(bit.rshift(argb, 8), 0xFF) local b = bit.band(argb, 0xFF) return a, r, g, b end
function convertCoord(xx,yy)
local function limitToMap(x, y)
if x > 3000 then
x = 3000
elseif x < -3000 then
x = -3000
end
if y > 3000 then
y = 3000
elseif y < -3000 then
y = -3000
end
return x, y
end
local mapSize = {getMapSize()}
local multiplier = mapSize[3] / 6000
local bottom_y = mapSize[2] + mapSize[3]
local bottom_x = mapSize[1] + mapSize[3]
local wx, wy = limitToMap((xx), (yy))
local x = mapSize[1] + (wx + 3000) * multiplier
local y = mapSize[2] + mapSize[3] - (wy + 3000) * multiplier
return x,y
end
function getMapSize()
local sh, sw = getScreenResolution()
local map_size = math.floor(sw * 0.8)
sw = sw - (zoom*4.5)
map_size = map_size + zoom
local top_x = sh / 2 - map_size / 2
local top_y = sw * 0.1
return top_x,top_y,map_size
end
function SearchMarker(isRace)
local ret_posX = 0.0
local ret_posY = 0.0
local ret_posZ = 0.0
local isFind = false
for id = 0, 31 do
local MarkerStruct = 0
if isRace then MarkerStruct = 0xC7F168 + id * 56
else MarkerStruct = 0xC7DD88 + id * 160 end
local MarkerPosX = representIntAsFloat(readMemory(MarkerStruct + 0, 4, false))
local MarkerPosY = representIntAsFloat(readMemory(MarkerStruct + 4, 4, false))
local MarkerPosZ = representIntAsFloat(readMemory(MarkerStruct + 8, 4, false))
if MarkerPosX ~= 0.0 or MarkerPosY ~= 0.0 or MarkerPosZ ~= 0.0 then
ret_posX = MarkerPosX
ret_posY = MarkerPosY
ret_posZ = MarkerPosZ
isFind = true
end
end
return isFind, ret_posX, ret_posY, ret_posZ
end
function renderMap(mode)
if map_render then
if not sampIsDialogActive() and not sampIsScoreboardOpen() then
local mapSize = {getMapSize()}
local myPos = {getCharCoordinates(playerPed)}
renderDrawTexture(textures.map, mapSize[1], mapSize[2], mapSize[3], mapSize[3], 0, join_argb(155,255,255,255))
local my_x,my_y = convertCoord(myPos[1],myPos[2])
renderDrawTexture(textures.cursor, my_x-7.5,my_y-7.5, 15,15, (getCharHeading(PLAYER_PED)-getCharHeading(PLAYER_PED)-360-getCharHeading(PLAYER_PED)), join_argb(255,255,255,255))
local blip = {getTargetBlipCoordinates()}
if blip[1] then
local x,y = convertCoord(blip[2],blip[3])
renderDrawTexture(textures.marker, x-12.5,y-12.5, 25,25, 0, join_argb(155,255,255,255))
-- renderDrawBox(x-1, y-1, 12, 12, 0xFF000000)
-- renderDrawBox(x, y, 10, 10, join_argb(155,204,0,0))
end
local marker = {SearchMarker(true)}
if marker[1] then
local marker_x,marker_y = convertCoord(marker[2],marker[3])
renderDrawBox(marker_x-1, marker_y-1, 12, 12, 0xFF000000)
renderDrawBox(marker_x, marker_y, 10, 10, join_argb(155,250,60,60))
end
end
end
end