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


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 target_time = 0 -- Переменная для хранения времени срабатывания

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 glyph_ranges = imgui.GetIO().Fonts:GetGlyphRangesCyrillic()
    font_main = imgui.GetIO().Fonts:AddFontFromFileTTF(getFolderPath(0x14) .. '\\trebuc.ttf', 18, nil, glyph_ranges)
    font_logo = imgui.GetIO().Fonts:AddFontFromFileTTF(getFolderPath(0x14) .. '\\impact.ttf', 28, 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)
end)

imgui.OnFrame(function() return WinState[0] end, function()
    imgui.SetNextWindowSize(imgui.ImVec2(500, 420), 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, 300), 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, 300), 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.Text(u8"Установите время:")
                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')
                    sampAddChatMessage("{4488FF}[severoff] {FFFFFF}Время сохранено.", -1)
                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)
    local btn_text = script_active and u8"ВЫКЛЮЧИТЬ" or u8"ВКЛЮЧИТЬ"
    if imgui.Button(btn_text, imgui.ImVec2(-1, 30)) then
        script_active = not script_active
        if script_active then
            -- Расчет времени срабатывания для таймера (Тип 1)
            local total_seconds = (settings.main.h * 3600) + (settings.main.m * 60) + settings.main.s
            target_time = os.clock() + total_seconds
            sampAddChatMessage("{4488FF}[severoff] {FFFFFF}Система активирована.", -1)
        else
            sampAddChatMessage("{4488FF}[severoff] {FFFFFF}Система деактивирована.", -1)
        end
    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
            -- 1. Таймер "Через время"
            if settings.main.condition == 1 then
                if os.clock() >= target_time then
                    go_trigger = true
                end
            
            -- 2. В точное время (напр. в 15:00:00)
            elseif settings.main.condition == 2 then
                local cur_time = os.date('%H:%M:%S')
                local target = string.format("%02d:%02d:%02d", settings.main.h, settings.main.m, settings.main.s)
                if cur_time == target then 
                    go_trigger = true 
                end
                
            -- 3. PayDay (каждый час в 00:01)
            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 = false
            script_active = false
        end
    end
end

function executeAction()
    local act = settings.main.action
    if act == 1 then os.execute('shutdown /s /t 10')
    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 then
        if text:find(u8:decode(str(buf.search))) then go_trigger = true end
    end
end

-- Обработка стрима игроков
function ev.onPlayerStreamIn(playerId)
    if script_active and settings.main.condition == 6 then
        if sampGetPlayerNickname(playerId) == u8:decode(str(buf.search)) then go_trigger = true end
    end
end

-- Диссконнект
function onReceivePacket(id)
    if id == 32 and script_active and settings.main.condition == 5 then 
        go_trigger = true 
    end
end