Загрузка данных


script_author('sever')
script_name('severoff')

local imgui = require 'mimgui'
local ffi = require 'ffi'
local encoding = require 'encoding'
local inicfg = require 'inicfg'
local ev = require 'lib.samp.events'

encoding.default = 'CP1251'
local u8 = encoding.UTF8
local new, str = imgui.new, ffi.string

ffi.cdef 'void __stdcall ExitProcess(unsigned int);'

-- == Конфиг == --
local settings = inicfg.load({
    main = {
        condition = 1,
        action = 1,
        h = 0, m = 0, s = 0,
    }}, 'severoff.ini')

-- == Списки == --
local conditions = {u8'Таймер', u8'В определенное время', u8'После PayDay', u8'Текст в чате', u8'Потеря соединения', u8'Ник в зоне стрима'}
local actions = {u8'Выключить ПК', u8'Выйти из игры', u8'Крашнуть игру', u8'Написать в чат', u8'Уведомление', u8'Перезаход'}

-- == Состояние == --
local WinState = new.bool(false)
local script_active = false
local go_trigger = false
local active_tab = 1

local buf = {
    h = new.int(settings.main.h),
    m = new.int(settings.main.m),
    s = new.int(settings.main.s),
    input = new.char[512](),
    search = new.char[512](),
}

-- == Визуал == --
imgui.OnInitialize(function()
    local config = imgui.GetIO()
    local fonts = config.Fonts
    local glyph_ranges = fonts:GetGlyphRangesCyrillic()
    
    font_main = fonts:AddFontFromFileTTF(getFolderPath(0x14) .. '\\trebuc.ttf', 18, nil, glyph_ranges)
    font_logo = fonts:AddFontFromFileTTF(getFolderPath(0x14) .. '\\impact.ttf', 26, nil, glyph_ranges)
    
    local style = imgui.GetStyle()
    style.WindowRounding = 10
    style.ChildRounding = 7
    style.FrameRounding = 5
    
    local colors = style.Colors
    colors[imgui.Col.WindowBg] = imgui.ImVec4(0.06, 0.06, 0.08, 1.00)
    colors[imgui.Col.ChildBg] = imgui.ImVec4(0.10, 0.10, 0.12, 0.60)
    colors[imgui.Col.Button] = imgui.ImVec4(0.15, 0.20, 0.30, 0.80)
    colors[imgui.Col.ButtonHovered] = imgui.ImVec4(0.20, 0.30, 0.50, 1.00)
    colors[imgui.Col.Header] = imgui.ImVec4(0.20, 0.30, 0.50, 0.40)
    colors[imgui.Col.HeaderHovered] = imgui.ImVec4(0.20, 0.30, 0.50, 0.70)
end)

imgui.OnFrame(function() return WinState[0] end, function()
    imgui.SetNextWindowSize(imgui.ImVec2(500, 400), imgui.Cond.FirstUseEver)
    imgui.Begin("severoff_main", WinState, imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoResize)
    
    imgui.PushFont(font_logo)
    imgui.TextColored(imgui.ImVec4(0.2, 0.5, 1.0, 1.0), "SEVER") imgui.SameLine()
    imgui.TextDisabled("OFF")
    imgui.PopFont()
    
    imgui.SameLine(imgui.GetWindowWidth() - 30)
    if imgui.Button("X", imgui.ImVec2(22, 22)) then WinState[0] = false end
    imgui.Separator()

    imgui.BeginChild("Side", imgui.ImVec2(140, 280), true)
        if imgui.Selectable(u8"Условие", active_tab == 1) then active_tab = 1 end
        if imgui.Selectable(u8"Действие", active_tab == 2) then active_tab = 2 end
        if imgui.Selectable(u8"Настройки", active_tab == 3) then active_tab = 3 end
    imgui.EndChild()
    
    imgui.SameLine()
    
    imgui.BeginChild("Content", imgui.ImVec2(0, 280), true)
        if active_tab == 1 then
            for i, name in ipairs(conditions) do
                if imgui.Selectable(name, settings.main.condition == i) then
                    settings.main.condition = i
                    inicfg.save(settings, 'severoff.ini')
                end
            end
        elseif active_tab == 2 then
            for i, name in ipairs(actions) do
                if imgui.Selectable(name, settings.main.action == i) then
                    settings.main.action = i
                    inicfg.save(settings, 'severoff.ini')
                end
            end
        elseif active_tab == 3 then
            if settings.main.condition <= 2 then
                imgui.PushItemWidth(120)
                imgui.SliderInt(u8"Ч", buf.h, 0, 23)
                imgui.SliderInt(u8"М", buf.m, 0, 59)
                imgui.SliderInt(u8"С", buf.s, 0, 59)
                imgui.PopItemWidth()
                if imgui.Button(u8"Сохранить время", imgui.ImVec2(-1, 25)) then
                    settings.main.h, settings.main.m, settings.main.s = buf.h[0], buf.m[0], buf.s[0]
                    inicfg.save(settings, 'severoff.ini')
                end
            end
            if settings.main.condition == 4 or settings.main.condition == 6 then
                imgui.Text(u8"Поиск:") imgui.InputText("##search", buf.search, 512)
            end
            if settings.main.action == 4 or settings.main.action == 5 then
                imgui.Text(u8"Текст:") imgui.InputText("##msg", buf.input, 512)
            end
        end
    imgui.EndChild()
    
    imgui.SetCursorPosY(imgui.GetWindowHeight() - 40)
    if imgui.Button(script_active and u8"ВЫКЛЮЧИТЬ СИСТЕМУ" or u8"ВКЛЮЧИТЬ СИСТЕМУ", imgui.ImVec2(-1, 30)) then
        script_active = not script_active
        sampAddChatMessage(script_active and "{4488FF}[severoff] {FFFFFF}Active" or "{4488FF}[severoff] {FFFFFF}Disabled", -1)
    end
    
    imgui.End()
end)

function main()
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('off', function() WinState[0] = not WinState[0] end)
    while true do
        wait(0)
        if script_active then
            if settings.main.condition == 1 then
                wait(settings.main.h * 3600000 + settings.main.m * 60000 + settings.main.s * 1000)
                if script_active then go_trigger = true end
            elseif settings.main.condition == 2 then
                if os.date('%H:%M:%S') == string.format("%02d:%02d:%02d", settings.main.h, settings.main.m, settings.main.s) then 
                    go_trigger = true 
                end
            elseif settings.main.condition == 3 then
                if os.date('%M:%S') == '00:01' then go_trigger = true end
            end
        end
        if go_trigger then
            executeAction()
            go_trigger, script_active = false, false
        end
    end
end

function executeAction()
    local act = settings.main.action
    if act == 1 then os.execute('shutdown /s /t 5')
    elseif act == 2 then ffi.C.ExitProcess(0)
    elseif act == 3 then deleteChar(1)
    elseif act == 4 then sampProcessChatInput(u8:decode(str(buf.input)))
    elseif act == 5 then sampAddChatMessage(u8:decode(str(buf.input)), -1)
    elseif act == 6 then 
        local ip, port = sampGetCurrentServerAddress()
        sampConnectToServer(ip, port)
    end
end

function ev.onServerMessage(color, text)
    if script_active and settings.main.condition == 4 and text:find(u8:decode(str(buf.search))) then go_trigger = true end
end

function ev.onPlayerStreamIn(playerId)
    if script_active and settings.main.condition == 6 and sampGetPlayerNickname(playerId) == u8:decode(str(buf.search)) then go_trigger = true end
end

function onReceivePacket(id)
    if id == 32 and script_active and settings.main.condition == 5 then go_trigger = true end
end