require 'moonloader'
local inicfg = require 'inicfg'
local vkeys = require 'vkeys'
local imgui = require 'imgui'
local encoding = require 'encoding'
local sampev = require "lib.samp.events"
encoding.default = 'CP1251'
local u8 = encoding.UTF8
local ScreenX, ScreenY = getScreenResolution()
local action
local timetopress = os.clock()
local saved = false
local autom = false
local cfg = inicfg.load({
{name = "обычный чат",maxcd = 60,maxmsg = 3,mutetime = 60,bool = false,reason = "Флуд[{msg} сообщ за {sec} сек]"},
{name = "/b",maxcd = 60,maxmsg = 3,mutetime = 60,bool = false,reason = "Флуд[{msg} сообщ за {sec} сек]"},
{name = "/s",maxcd = 60,maxmsg = 3,mutetime = 60,bool = false,reason = "Флуд[{msg} сообщ за {sec} сек]"},
{name = "/vr",maxcd = 60,maxmsg = 3,mutetime = 60,bool = false,reason = "Флуд[{msg} сообщ за {sec} сек]"},
set = {enable = false,onbutton=false,bind=nil,time=5},
},"floodcontrol")
local msgs = {chat = {},s = {},b = {},vr = {},}
local settingsToImgui = {}
local mainw = imgui.ImBool(false)
for k,v in pairs(cfg) do
if k ~= "set" then
settingsToImgui[k] = {bool = imgui.ImBool(v.bool),maxcd = imgui.ImInt(v.maxcd),maxmsg = imgui.ImInt(v.maxmsg),mutetime = imgui.ImInt(v.mutetime),reason = imgui.ImBuffer(u8(v.reason),100)}
else
settingsToImgui[k] = {enable = imgui.ImBool(v.enable),onbutton = imgui.ImBool(v.onbutton),time = imgui.ImInt(v.time)}
end
end
function main()
if not isSampfuncsLoaded() or not isSampLoaded() then return end
while not isSampAvailable() do
wait(0)
end
sampAddChatMessage("[Flood Controller] Скрипт успешно запущен. Настройки:{ff4d4d} /floodc",0xd1d1d1)
sampRegisterChatCommand("floodc",function ()
mainw.v = not mainw.v
end)
imgui.Style()
imgui.ShowCursor = true
while true do
wait(0)
if action and cfg.set.onbutton and cfg.set.bind then
if cfg.set.time+1-(math.ceil(os.clock()-timetopress)) > 0 then
printStyledString("~n~~n~~n~~n~~n~~n~~r~wait "..(cfg.set.time+1-(math.ceil(os.clock()-timetopress))).."~n~~w~mute to~n~~g~"..action.name,1,4)
if tostring(cfg.set.bind):match('(.+)%p(.+)') then
if not sampIsChatInputActive() then
sampSendChat("/mute "..action.id.." "..action.time.." "..action.reason,-1)
action = nil
end
elseif tostring(cfg.set.bind):match('(.+)') then
if not sampIsChatInputActive() then
sampSendChat("/mute "..action.id.." "..action.time.." "..action.reason,-1)
action = nil
end
end
else
action = nil
end
end
imgui.Process = mainw.v
end
wait(0)
end
function detectedFlood(name,id,msg,time,count,number)
sampAddChatMessage("[Flood Controller] Замечен флуд в {ff4d4d}"..cfg[number].name.."{d1d1d1}. Отправлено "..count.." сообщения, за {ff4d4d}"..time.."{d1d1d1} секунд из "..cfg[number].maxcd.." разрешенных!",0xd1d1d1)
sampAddChatMessage("[Flood Controller] Сообщение: {ff4d4d}"..msg.."{d1d1d1} | Отправитель: {ff4d4d}"..name.."["..id.."]",0xd1d1d1)
if cfg.set.onbutton and cfg.set.bind then
sampAddChatMessage("[Flood Controller] Нажмите {ff4d4d}"..cfg.set.bind.."{d1d1d1}, чтобы выдать мут игроку {ff4d4d}"..name.."{d1d1d1} на {ff4d4d}"..cfg[number].mutetime.."{d1d1d1} минут",0xd1d1d1)
timetopress = os.clock()
action = {name = name,id = id, time = cfg[number].mutetime,reason = ((cfg[number].reason):gsub("{msg}",count):gsub("{sec}",time))}
end
end
function sampev.onServerMessage(clr,text)
if text:find("{FFFFFF}Вы простояли в AFK {FF9900}") then
action = nil
end
if cfg.set.enable then
if clr == -1 and text:find(".+ говорит:{B7AFAF}") then
local n
for k,v in pairs(cfg) do
if v.name and v.name == "обычный чат" then
n = k
end
end
if cfg[n].bool then
local playername,playerid,msg = text:match("(.+)%[(%d+)%] говорит:{B7AFAF} (.+)")
if msgs.chat[playername] and msgs.chat[playername][1] then
if (#msgs.chat[playername]+1 >= cfg[n].maxmsg) then
while (#msgs.chat[playername] > cfg[n].maxmsg) do
table.remove(msgs.chat[playername],1)
end
if msgs.chat[playername][#msgs.chat[playername]].id == playerid and msgs.chat[playername][#msgs.chat[playername]].msg == msg then
msgs.chat[playername][#msgs.chat[playername]+1] = {id = playerid,msg = msg,time = os.clock()}
if msgs.chat[playername][#msgs.chat[playername]].time and math.ceil(msgs.chat[playername][#msgs.chat[playername]].time - msgs.chat[playername][1].time) < cfg[n].maxcd then
detectedFlood(playername,playerid,msg,math.ceil(msgs.chat[playername][#msgs.chat[playername]].time - msgs.chat[playername][1].time),#msgs.chat[playername],n)
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.chat[playername],1)
end
end
else
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.chat[playername],1)
end
end
else
if msgs.chat[playername][#msgs.chat[playername]].id == playerid and msgs.chat[playername][#msgs.chat[playername]].msg == msg then
msgs.chat[playername][#msgs.chat[playername]+1] = {id = playerid,msg = msg,time = os.clock()}
else
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.chat[playername],1)
end
end
end
else
msgs.chat[playername] = {}
msgs.chat[playername][#msgs.chat[playername]+1] = {id = playerid,msg = msg,time = os.clock()}
if cfg[n].maxmsg <= 1 then
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.chat[playername],1)
end
end
end
end
elseif clr == -1 and text:find("%(%(.+%: {B7AFAF}.+{FFFFFF} %)%)") then
local n
for k,v in pairs(cfg) do
if v.name and v.name == "/b" then
n = k
end
end
if cfg[n].bool then
local playername,playerid,msg = text:match("%(%((.+)%[(%d+)%]: {B7AFAF}(.+){FFFFFF} %)%)")
if msgs.b[playername] and msgs.b[playername][1] then
if (#msgs.b[playername]+1 >= cfg[n].maxmsg) then
while (#msgs.b[playername] > cfg[n].maxmsg) do
table.remove(msgs.b[playername],1)
end
if msgs.b[playername][#msgs.b[playername]].id == playerid and msgs.b[playername][#msgs.b[playername]].msg == msg then
msgs.b[playername][#msgs.b[playername]+1] = {id = playerid,msg = msg,time = os.clock()}
if msgs.b[playername][#msgs.b[playername]].time and math.ceil(msgs.b[playername][#msgs.b[playername]].time - msgs.b[playername][1].time) < cfg[n].maxcd then
detectedFlood(playername,playerid,msg,math.ceil(msgs.b[playername][#msgs.b[playername]].time - msgs.b[playername][1].time),#msgs.b[playername],n)
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.b[playername],1)
end
end
else
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.b[playername],1)
end
end
else
if msgs.b[playername][#msgs.b[playername]].id == playerid and msgs.b[playername][#msgs.b[playername]].msg == msg then
msgs.b[playername][#msgs.b[playername]+1] = {id = playerid,msg = msg,time = os.clock()}
else
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.b[playername],1)
end
end
end
else
msgs.b[playername] = {}
msgs.b[playername][#msgs.b[playername]+1] = {id = playerid,msg = msg,time = os.clock()}
if cfg[n].maxmsg <= 1 then
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.b[playername],1)
end
end
end
end
elseif clr == -253326081 and text:find(".+ кричит: .+!!") then
local n
for k,v in pairs(cfg) do
if v.name and v.name == "/s" then
n = k
end
end
if cfg[n].bool then
local playername,playerid,msg = text:match("(.+)%[(%d+)%] кричит: (.+)!!")
if msgs.s[playername] and msgs.s[playername][1] then
if (#msgs.s[playername]+1 >= cfg[n].maxmsg) then
while (#msgs.s[playername] > cfg[n].maxmsg) do
table.remove(msgs.s[playername],1)
end
if msgs.s[playername][#msgs.s[playername]].id == playerid and msgs.s[playername][#msgs.s[playername]].msg == msg then
msgs.s[playername][#msgs.s[playername]+1] = {id = playerid,msg = msg,time = os.clock()}
if msgs.s[playername][#msgs.s[playername]].time and math.ceil(msgs.s[playername][#msgs.s[playername]].time - msgs.s[playername][1].time) < cfg[n].maxcd then
detectedFlood(playername,playerid,msg,math.ceil(msgs.s[playername][#msgs.s[playername]].time - msgs.s[playername][1].time),#msgs.s[playername],n)
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.s[playername],1)
end
end
else
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.s[playername],1)
end
end
else
if msgs.s[playername][#msgs.s[playername]].id == playerid and msgs.s[playername][#msgs.s[playername]].msg == msg then
msgs.s[playername][#msgs.s[playername]+1] = {id = playerid,msg = msg,time = os.clock()}
else
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.s[playername],1)
end
end
end
else
msgs.s[playername] = {}
msgs.s[playername][#msgs.s[playername]+1] = {id = playerid,msg = msg,time = os.clock()}
if cfg[n].maxmsg <= 1 then
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.s[playername],1)
end
end
end
end
elseif clr == -1 and (text:find("{F345FC}%[PREMIUM%] {FFFFFF}") or text:find("{6495ED}%[VIP%] {FFFFFF}")) then
local n
for k,v in pairs(cfg) do
if v.name and v.name == "/vr" then
n = k
end
end
if cfg[n].bool then
local playername,playerid,msg = text:match("{.+}%[.+%] {.+}(.+)%[(%d+)%]: (.+)")
if msgs.vr[playername] and msgs.vr[playername][1] then
if (#msgs.vr[playername]+1 >= cfg[n].maxmsg) then
while (#msgs.vr[playername] > cfg[n].maxmsg) do
table.remove(msgs.vr[playername],1)
end
if msgs.vr[playername][#msgs.vr[playername]].id == playerid and msgs.vr[playername][#msgs.vr[playername]].msg == msg then
msgs.vr[playername][#msgs.vr[playername]+1] = {id = playerid,msg = msg,time = os.clock()}
if msgs.vr[playername][#msgs.vr[playername]].time and math.ceil(msgs.vr[playername][#msgs.vr[playername]].time - msgs.vr[playername][1].time) < cfg[n].maxcd then
detectedFlood(playername,playerid,msg,math.ceil(msgs.vr[playername][#msgs.vr[playername]].time - msgs.vr[playername][1].time),#msgs.vr[playername],n)
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.vr[playername],1)
end
end
else
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.vr[playername],1)
end
end
else
if msgs.vr[playername][#msgs.vr[playername]].id == playerid and msgs.vr[playername][#msgs.vr[playername]].msg == msg then
msgs.vr[playername][#msgs.vr[playername]+1] = {id = playerid,msg = msg,time = os.clock()}
else
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.vr[playername],1)
end
end
end
else
msgs.vr[playername] = {}
msgs.vr[playername][#msgs.vr[playername]+1] = {id = playerid,msg = msg,time = os.clock()}
if cfg[n].maxmsg <= 1 then
for i = 1,cfg[n].maxmsg,1 do
table.remove(msgs.vr[playername],1)
end
end
end
end
end
end
end
function imgui.OnDrawFrame()
if mainw.v then
imgui.SetNextWindowSize(imgui.ImVec2(565, 715), imgui.Cond.Appearing)
imgui.SetNextWindowPos(imgui.ImVec2(ScreenX / 2, ScreenY / 2),imgui.Cond.Appearing, imgui.ImVec2(0.5, 0.5))
imgui.Begin(u8"Flood Control", mainw, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoBringToFrontOnFocus + imgui.WindowFlags.NoCollapse)
imgui.Text(u8"Варнинги флуда: ")
imgui.SameLine(220)
if imgui.ToggleButton(u8("##warningbool"),settingsToImgui["set"].enable) then
cfg.set.enable = settingsToImgui["set"].enable.v
inicfg.save(cfg,"floodcontrol")
end
imgui.Text(u8"Выдача /mute по кнопке: ")
imgui.SameLine(220)
if imgui.ToggleButton(u8("##onbutton"),settingsToImgui["set"].onbutton) then
cfg.set.onbutton = settingsToImgui["set"].onbutton.v
inicfg.save(cfg,"floodcontrol")
end
imgui.Text(u8"Бинд выдачи /mute: ")
imgui.SameLine(220)
if setbinderkey then
setbinderkey,cfg.set.bind = imgui.GetKeys(setbinderkey,2)
else
if not saved then
inicfg.save(cfg,"floodcontrol")
saved = true
end
end
if imgui.Button(cfg.set.bind and u8(cfg.set.bind) or u8"None", imgui.ImVec2(100, 25)) then
if cfg.set.bind then
str = nil
cfg.set.bind = nil
setbinderkey = false
saved = false
else
saved = false
setbinderkey = true
end
end
imgui.Text(u8"Время ожидания нажатия бинда: ")
imgui.SameLine(220)
imgui.PushItemWidth(100)
if imgui.InputInt("##timetomute",settingsToImgui["set"].time) then
cfg.set.time = settingsToImgui["set"].time.v
inicfg.save(cfg,"floodcontrol")
end
imgui.Text(u8("track 1"))
imgui.SameLine()
if imgui.Button(u8('play')) then
track1 = loadAudioStream(getWorkingDirectory() .. "moonloader/resource/audioPlayer/track1.wav")
releaseAudioStream(track1)
end
imgui.PopItemWidth()
imgui.Separator()
for k,v in pairs(cfg) do
if k ~= "set" and (v.name == "обычный чат" or v.name == "/vr" or v.name == "/s" or v.name == "/b") then
imgui.Text(u8"Варнинг на "..u8(v.name)..": ")
imgui.SameLine(430)
if imgui.ToggleButton(u8(v.name),settingsToImgui[k].bool) then
msgs = {chat = {},s = {},b = {},vr = {},}
cfg[k].bool = settingsToImgui[k].bool.v
inicfg.save(cfg,"floodcontrol")
end
imgui.Text(u8"Кол-во секунд за которое нельзя отправить более чем "..(v.maxmsg-1)..u8" сообщения: ")
imgui.SameLine(430)
imgui.PushItemWidth(120)
if imgui.InputInt("##maxmsg"..k,settingsToImgui[k].maxcd) then
msgs = {chat = {},s = {},b = {},vr = {},}
cfg[k].maxcd = settingsToImgui[k].maxcd.v
inicfg.save(cfg,"floodcontrol")
end
imgui.Text(u8"Кол-во сообщений которое нельзя отправить в течении "..(v.maxcd)..u8" секунд: ")
imgui.SameLine(430)
if imgui.InputInt("##maxcd"..k,settingsToImgui[k].maxmsg) then
msgs = {chat = {},s = {},b = {},vr = {},}
cfg[k].maxmsg = settingsToImgui[k].maxmsg.v
inicfg.save(cfg,"floodcontrol")
end
imgui.Text(u8"Кол-во минут /mute за флуд: ")
imgui.SameLine(430)
if imgui.InputInt("##mutetime"..k,settingsToImgui[k].mutetime) then
msgs = {chat = {},s = {},b = {},vr = {},}
cfg[k].mutetime = settingsToImgui[k].mutetime.v
inicfg.save(cfg,"floodcontrol")
end
imgui.Text(u8"Своя причина для /mute: ")
imgui.SameLine(300)
imgui.TextColoredRGB("{808080}Теги: {808080}{msg} |")
imgui.Hint('Количество сообщений от игрока при флуде')
imgui.SameLine(378)
imgui.TextColoredRGB("{808080}{sec}")
imgui.Hint('Количество секунд, за которое отправлены сообщения')
imgui.SameLine(430)
if imgui.InputText("##mutereason"..k,settingsToImgui[k].reason) then
cfg[k].reason = u8:decode(settingsToImgui[k].reason.v)
inicfg.save(cfg,"floodcontrol")
end
imgui.PopItemWidth()
if k ~= #cfg then
imgui.Separator()
end
end
end
imgui.End()
end
end
function imgui.BeginTitleChild(str_id, size, color, offset,maked)
color = color or imgui.GetStyle().Colors[imgui.Col.Border]
offset = offset or 30
local DL = imgui.GetWindowDrawList()
local posS = imgui.GetCursorScreenPos()
local rounding = imgui.GetStyle().ChildWindowRounding
local title = str_id:gsub('##.+$', '')
local sizeT = imgui.CalcTextSize(title)
local padd = imgui.GetStyle().WindowPadding
local bgColor = imgui.ColorConvertFloat4ToU32(imgui.GetStyle().Colors[imgui.Col.WindowBg])
size.x = size.x == -1.0 and imgui.GetWindowWidth() or size.x
size.y = size.y == -1.0 and imgui.GetWindowHeight() or size.y
DL:AddRect(posS, imgui.ImVec2(posS.x + size.x, posS.y + size.y), imgui.ColorConvertFloat4ToU32(color), rounding, _, 1)
DL:AddLine(imgui.ImVec2(posS.x + offset - 3, posS.y), imgui.ImVec2(posS.x + offset + sizeT.x + 3, posS.y), bgColor, 3)
DL:AddLine(imgui.ImVec2(posS.x, posS.y + 35), imgui.ImVec2(posS.x + size.x, posS.y + 35), (maked == true and (0) or (imgui.ColorConvertFloat4ToU32(color))), 1)
DL:AddText(imgui.ImVec2(posS.x + offset, posS.y - (sizeT.y / 2)), imgui.ColorConvertFloat4ToU32(color), title)
end
function imgui.ToggleButton(str_id, bool)
local rBool = false
if LastActiveTime == nil then
LastActiveTime = {}
end
if LastActive == nil then
LastActive = {}
end
local function ImSaturate(f)
return f < 0.0 and 0.0 or (f > 1.0 and 1.0 or f)
end
local p = imgui.GetCursorScreenPos()
local draw_list = imgui.GetWindowDrawList()
local height = 20
local width = height * 1.55
local radius = height * 0.50
local ANIM_SPEED = 0.15
if imgui.InvisibleButton(str_id, imgui.ImVec2(width, height)) then
bool.v = not bool.v
rBool = true
LastActiveTime[tostring(str_id)] = os.clock()
LastActive[str_id] = true
end
local t = bool.v and 1.0 or 0.0
if LastActive[str_id] then
local time = os.clock() - LastActiveTime[tostring(str_id)]
if time <= ANIM_SPEED then
local t_anim = ImSaturate(time / ANIM_SPEED)
t = bool.v and t_anim or 1.0 - t_anim
else
LastActive[str_id] = false
end
end
local col_bg
if imgui.IsItemHovered() then
col_bg = imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.FrameBgHovered])
else
col_bg = imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.FrameBg])
end
draw_list:AddRectFilled(p, imgui.ImVec2(p.x + width, p.y + height), col_bg, height * 0.5)
draw_list:AddCircleFilled(imgui.ImVec2(p.x + radius + t * (width - radius * 2.0), p.y + radius), radius - 1.5, imgui.GetColorU32(bool.v and imgui.GetStyle().Colors[imgui.Col.ButtonActive] or imgui.GetStyle().Colors[imgui.Col.Button]))
return rBool
end
function imgui.Hint(text, delay, action)
if imgui.IsItemHovered() then
if hintanim == nil then hintanim = os.clock() + (delay and delay or 0.0) end
local alpha = (os.clock() - hintanim) * 5
if os.clock() >= hintanim then
imgui.PushStyleVar(imgui.StyleVar.WindowPadding, imgui.ImVec2(10, 10))
imgui.PushStyleVar(imgui.StyleVar.Alpha, (alpha <= 1.0 and alpha or 1.0))
imgui.PushStyleColor(imgui.Col.PopupBg, imgui.ImVec4(0.11, 0.11, 0.11, 0.80))
imgui.BeginTooltip()
imgui.PushTextWrapPos(450)
imgui.TextColoredRGB(('{FFFFFF}%s'):format(text),1)
if action ~= nil then imgui.Text(('\n %s'):format(action)) end
if not imgui.IsItemVisible() and imgui.GetStyle().Alpha == 1.0 then hintanim = nil end
imgui.PopTextWrapPos()
imgui.EndTooltip()
imgui.PopStyleColor()
imgui.PopStyleVar(2)
end
end
end
function imgui.TextColoredRGB(text,align)
local width = imgui.GetWindowWidth()
local style = imgui.GetStyle()
local colors = style.Colors
local ImVec4 = imgui.ImVec4
local explode_argb = function(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
local getcolor = function(color)
if color:sub(1, 6):upper() == 'SSSSSS' then
local r, g, b = colors[1].x, colors[1].y, colors[1].z
local a = tonumber(color:sub(7, 8), 16) or colors[1].w * 255
return ImVec4(r, g, b, a / 255)
end
local color = type(color) == 'string' and tonumber(color, 16) or color
if type(color) ~= 'number' then return end
local r, g, b, a = explode_argb(color)
return imgui.ImColor(r, g, b, a):GetVec4()
end
local render_text = function(text_)
for w in text_:gmatch('[^\r\n]+') do
local textsize = w:gsub('{.-}', '')
local text_width = imgui.CalcTextSize(u8(textsize))
if align == 1 then imgui.SetCursorPosX( width / 2 - text_width .x / 2 )
elseif align == 2 then imgui.SetCursorPosX(imgui.GetCursorPosX() + width - text_width.x - imgui.GetScrollX() - 2 * imgui.GetStyle().ItemSpacing.x - imgui.GetStyle().ScrollbarSize)
end
local text, colors_, m = {}, {}, 1
w = w:gsub('{(......)}', '{%1FF}')
while w:find('{........}') do
local n, k = w:find('{........}')
local color = getcolor(w:sub(n + 1, k - 1))
if color then
text[#text], text[#text + 1] = w:sub(m, n - 1), w:sub(k + 1, #w)
colors_[#colors_ + 1] = color
m = n
end
w = w:sub(1, n - 1) .. w:sub(k + 1, #w)
end
if text[0] then
for i = 0, #text do
imgui.TextColored(colors_[i] or colors[1], u8(text[i]))
imgui.SameLine(nil, 0)
end
imgui.NewLine()
else imgui.Text(u8(w)) end
end
end
render_text(text)
end
function imgui.GetKeys(bool,maxkeys)
if bool then
local function getDownKeys()
local curkeys = ''
local bool = false
for k, v in pairs(vkeys) do
if isKeyDown(v) and (v == VK_MENU or v == VK_CONTROL or v == VK_SHIFT or v == VK_LMENU or v == VK_RMENU or v == VK_RCONTROL or v == VK_LCONTROL or v == VK_LSHIFT or v == VK_RSHIFT) then
if v ~= VK_MENU and v ~= VK_CONTROL and v ~= VK_SHIFT then
curkeys = v
end
end
end
for k, v in pairs(vkeys) do
if isKeyDown(v) and (v ~= VK_MENU and v ~= VK_CONTROL and v ~= VK_SHIFT and v ~= VK_LMENU and v ~= VK_RMENU and v ~= VK_RCONTROL and v ~= VK_LCONTROL and v ~= VK_LSHIFT and v ~= VK_RSHIFT) then
if tostring(curkeys):len() == 0 then
curkeys = v
return curkeys, true
else
curkeys = curkeys .. ' ' .. v
end
bool = true
end
end
return curkeys, bool
end
local tKeys = string.split(getDownKeys(), ' ')
if #tKeys ~= 0 then
for i = 1, #tKeys do
if #tKeys == 1 then
str = vkeys.id_to_name(tonumber(tKeys[i]))
local v = getDownKeys()
if (v == VK_MENU or v == VK_CONTROL or v == VK_SHIFT or v == VK_LMENU or v == VK_RMENU or v == VK_RCONTROL or v == VK_LCONTROL or v == VK_LSHIFT or v == VK_RSHIFT) then
return true,str
else
return false,str
end
elseif #tKeys == maxkeys then
if str and not str:find(vkeys.id_to_name(tonumber(tKeys[i]))) then
str = str .. '+' .. vkeys.id_to_name(tonumber(tKeys[i]))
return false,str
end
else
return true,(math.ceil(os.clock()) % 2 == 0) and '______' or ''
end
end
else
return true,(math.ceil(os.clock()) % 2 == 0) and '______' or ''
end
end
end
function imgui.Style()
imgui.SwitchContext()
local style = imgui.GetStyle()
local colors = style.Colors
local clr = imgui.Col
local ImVec4 = imgui.ImVec4
local ImVec2 = imgui.ImVec2
style.WindowTitleAlign = ImVec2(0.5, 0.5)
style.WindowPadding = ImVec2(15, 15)
style.WindowRounding = 6.0
style.FramePadding = ImVec2(5, 5)
style.FrameRounding = 5.0
style.ItemSpacing = ImVec2(12, 4)
style.ItemInnerSpacing = ImVec2(8, 6)
style.IndentSpacing = 25.0
style.ScrollbarSize = 15
style.ScrollbarRounding = 9.0
style.GrabMinSize = 5.0
style.GrabRounding = 3.0
style.ChildWindowRounding = 5.0
colors[clr.Text] = ImVec4(0.95, 0.96, 0.98, 1.00)
colors[clr.TextDisabled] = ImVec4(0.29, 0.29, 0.29, 1.00)
colors[clr.WindowBg] = ImVec4(0.14, 0.14, 0.14, 1.00)
colors[clr.ChildWindowBg] = ImVec4(0.14, 0.14, 0.14, 1.00)
colors[clr.PopupBg] = ImVec4(0.14, 0.14, 0.14, 1.00)
colors[clr.Border] = ImVec4(1.00, 0.28, 0.28, 0.50)
colors[clr.BorderShadow] = ImVec4(1.00, 1.00, 1.00, 0.00)
colors[clr.FrameBg] = ImVec4(0.22, 0.22, 0.22, 1.00)
colors[clr.FrameBgHovered] = ImVec4(0.18, 0.18, 0.18, 1.00)
colors[clr.FrameBgActive] = ImVec4(0.09, 0.12, 0.14, 1.00)
colors[clr.TitleBg] = ImVec4(1.00, 0.30, 0.30, 1.00)
colors[clr.TitleBgActive] = ImVec4(1.00, 0.30, 0.30, 1.00)
colors[clr.TitleBgCollapsed] = ImVec4(1.00, 0.30, 0.30, 1.00)
colors[clr.MenuBarBg] = ImVec4(0.20, 0.20, 0.20, 1.00)
colors[clr.ScrollbarBg] = ImVec4(0.02, 0.02, 0.02, 0.39)
colors[clr.ScrollbarGrab] = ImVec4(0.36, 0.36, 0.36, 1.00)
colors[clr.ScrollbarGrabHovered] = ImVec4(0.18, 0.22, 0.25, 1.00)
colors[clr.ScrollbarGrabActive] = ImVec4(0.24, 0.24, 0.24, 1.00)
colors[clr.ComboBg] = ImVec4(0.24, 0.24, 0.24, 1.00)
colors[clr.CheckMark] = ImVec4(1.00, 0.28, 0.28, 1.00)
colors[clr.SliderGrab] = ImVec4(1.00, 0.28, 0.28, 1.00)
colors[clr.SliderGrabActive] = ImVec4(1.00, 0.28, 0.28, 1.00)
colors[clr.Button] = ImVec4(1.00, 0.30, 0.30, 1.00)
colors[clr.ButtonHovered] = ImVec4(1.00, 0.25, 0.25, 1.00)
colors[clr.ButtonActive] = ImVec4(1.00, 0.20, 0.20, 1.00)
colors[clr.Header] = ImVec4(1.00, 0.28, 0.28, 1.00)
colors[clr.HeaderHovered] = ImVec4(1.00, 0.39, 0.39, 1.00)
colors[clr.HeaderActive] = ImVec4(1.00, 0.21, 0.21, 1.00)
colors[clr.ResizeGrip] = ImVec4(1.00, 0.28, 0.28, 1.00)
colors[clr.ResizeGripHovered] = ImVec4(1.00, 0.39, 0.39, 1.00)
colors[clr.ResizeGripActive] = ImVec4(1.00, 0.19, 0.19, 1.00)
colors[clr.CloseButton] = ImVec4(1.00, 0.00, 0.00, 0.50)
colors[clr.CloseButtonHovered] = ImVec4(1.00, 0.00, 0.00, 0.60)
colors[clr.CloseButtonActive] = ImVec4(1.00, 0.00, 0.00, 0.70)
colors[clr.PlotLines] = ImVec4(0.61, 0.61, 0.61, 1.00)
colors[clr.PlotLinesHovered] = ImVec4(1.00, 0.43, 0.35, 1.00)
colors[clr.PlotHistogram] = ImVec4(1.00, 0.21, 0.21, 1.00)
colors[clr.PlotHistogramHovered] = ImVec4(1.00, 0.18, 0.18, 1.00)
colors[clr.TextSelectedBg] = ImVec4(1.00, 0.25, 0.25, 1.00)
colors[clr.ModalWindowDarkening] = ImVec4(0.00, 0.00, 0.00, 0.30)
end
function string.split(inputstr, sep)
if sep == nil then
sep = '%s'
end
local t={} ; i=1
for str in string.gmatch(inputstr, '([^'..sep..']+)') do
t[i] = str
i = i + 1
end
return t
end
function strToIdKeys(str)
tKeys = string.split(str, "+")
if #tKeys ~= 0 then
for i = 1, #tKeys do
if i == 1 then
str = vkeys.name_to_id(tKeys[i], false)
else
str = str .. " " .. vkeys.name_to_id(tKeys[i], false)
end
end
return tostring(str)
else
return "(("
end
end
function isKeysDown(keylist, pressed)
local tKeys = string.split(keylist, " ")
if pressed == nil then
pressed = false
end
if tKeys[1] == nil then
return false
end
local bool = false
local key = #tKeys < 2 and tonumber(tKeys[1]) or tonumber(tKeys[2])
local modified = tonumber(tKeys[1])
if #tKeys < 2 then
if not isKeyDown(VK_RMENU) and not isKeyDown(VK_LMENU) and not isKeyDown(VK_LSHIFT) and not isKeyDown(VK_RSHIFT) and not isKeyDown(VK_LCONTROL) and not isKeyDown(VK_RCONTROL) then
if wasKeyPressed(key) and not pressed then
bool = true
elseif isKeyDown(key) and pressed then
bool = true
end
end
else
if isKeyDown(modified) and not wasKeyReleased(modified) then
if wasKeyPressed(key) and not pressed then
bool = true
elseif isKeyDown(key) and pressed then
bool = true
end
end
end
if nextLockKey == keylist then
if pressed and not wasKeyReleased(key) then
bool = false
else
bool = false
nextLockKey = ""
end
end
return bool
end