Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Max K. 18.06.2017 mcskill.ru
- local component = require("component")
- local computer = require("computer")
- local term = require("term")
- local event = require("event")
- local gpu = component.gpu
- local serialization = require("serialization")
- local unicode = require("unicode")
- local chat = component.chat_box
- local debug = component.debug
- chat.setName("§6G§7")
- setFG = gpu.setForeground
- setBG = gpu.setBackground
- gpu.setResolution(160,28)
- local LIVE = true -- true если стоит в рабочем состоянии на сервере - меняет поведение isGlobal(),cmd(),say()
- local c = {
- chat_name = "§8[§eБета-тест§8] §bKelira v2.0§7:§f ",
- history_borderUp = 1,
- history_borderDown = 1,
- history_borderLeft = 1,
- history_borderRight = 1,
- history_rows = nil,
- history_highglight_color = 0xff0000,
- history_tabs_y = 1,
- screenWidth = nil,
- screenHeight = nil,
- frame_main_color = 0xff00ff,
- frame_tabs_name_color = 0xffffff,
- white = 0xffffff,
- color1 = "§3",
- color2 = "§d",
- server_reboot_period = 10800, -- нужно указать как часто сервер делает рестарты
- timeout_question = 60, -- кд на повторный ответ на тот же самый вопрос в чате
- command_help = "-help",
- command_help2 = "-help2",
- command_inf = "-inf",
- command_mods = "-mods",
- command_yes = "-yes",
- command_no = "-no",
- command_server = "-server",
- command_votestats = "-votestats",
- command_votestop = "-votestop",
- command_is_player_muted = "-ismuted",
- command_unmute = "-unmute",
- command_toggle_detect = "-toggledetect", -- стать невидимым для -mods
- command_memory_used = "-memory",
- command_retranslate = "==", -- говорить от имени бота
- server_command_personal_cooldown = 5, -- личный кулдаун на команду -server
- warn_decay = 3600, -- период в секундах, на который бот запоминает свои варны. повторное нарушение дает мут вместо варна
- double_warn_mute_duration = 1800, -- длительность мута в случае двойного варна за censoredWords
- vote_easy_yes_to_pass = 2, -- во сколько голосов должен быть перевес для того, чтоб isEasy голосование прошло
- duration_mute_caps = 600, -- длительность мута за капс
- duration_mute_symbol_flood = 180, -- длительность мута за флуд символами
- duration_mute_flood = 900, -- длительность мута за флуд, в т.ч. торговыми сообщениями
- ratio_flood_symbol = 0.8, -- процент символов в сообщении для получения мута
- ratio_caps_symbol = 0.85, -- процент капса в сообщении для получения мута (также используется в isUsernameBad())
- flood_timeout = 30, -- таймаут для одинаковых сообщений
- flood_normal_messages_trigger = 3, -- сколько одинаковых сообщений подряд для мута
- flood_identical_trade_messages_trigger = 2, -- сколько одинаковых торговых сообщений подряд для мута
- flood_any_trade_messages_trigger = 3, -- сколько любых торговых сообщений ЗА flood_any_trade_messages_period СЕКУНД для получения мута
- flood_any_trade_messages_period = 180, -- период, за который учитываются торговые сообщения игрока для получения мута
- }
- local masters = {
- Shyvana = {
- --undetectable = false, -- не видно в списке -mods (это значение меняется командой c.command_toggle_detect)
- infiniteVote = true, -- может голосовать бесконечно
- canAccessVoteStats = true, -- может юзать votestats (инфа о текущем голосовании)
- canSkipVoteStartCondition = true, -- может начать голосование, даже если startCondition для голосования не соблюдено
- canSkipVoteGlobalCooldown = true, -- может игнорировать глобальный кулдаун на голосование
- canSkipVotePersonalCooldown = true, -- может игнорировать личный кулдаун на голосование
- canSkipQuestionsCooldown = true, -- может игнорировать кулдаун на вопросы c.timeout_question
- canSkipServerCommandCooldown = true, -- может игнорировать кулдаун команды -server
- canCancelIssuedMutes = true, -- может отменять муты, выданные ботом
- canNOTGetIgnoredByBot = true, -- если true то не может быть проигнорирован ботом (для команд глобального чата) после получения мута от него
- canCurse = false, -- может ли материться в чат (если true, бот будет игнорировать мат)
- canIgnoreModeratorCheckForCW = false, -- может ли игнорировать проверку на модератора если сматерится/зафлудит/закапсит в чат. true - будет получать муты, false - реплику в чат
- canStopVotes = true, -- может отменять голосование
- canHideFromModsCommand = true, -- может использовать команду для скрытия себя из списка -mods
- canUseRetranslate = true, -- может говорить от имени бота
- },
- lLuffy = {
- undetectable = true,
- canAccessVoteStats = true,
- canCancelIssuedMutes = true,
- canStopVotes = true,
- canHideFromModsCommand = true,
- canUseRetranslate = true,
- },
- ogrezem = {
- infiniteVote = true, -- может голосовать бесконечно
- canAccessVoteStats = true, -- может юзать votestats (инфа о текущем голосовании)
- canSkipVoteStartCondition = true, -- может начать голосование, даже если startCondition для голосования не соблюдено
- canSkipVoteGlobalCooldown = true, -- может игнорировать глобальный кулдаун на голосование
- canSkipVotePersonalCooldown = true, -- может игнорировать личный кулдаун на голосование
- canSkipQuestionsCooldown = true, -- может игнорировать кулдаун на вопросы c.timeout_question
- canSkipServerCommandCooldown = true, -- может игнорировать кулдаун команды -server
- canCancelIssuedMutes = true, -- может отменять муты, выданные ботом
- canNOTGetIgnoredByBot = true, -- если true то не может быть проигнорирован ботом (для команд глобального чата) после получения мута от него
- canCurse = false, -- может ли материться в чат (если true, бот будет игнорировать мат)
- canIgnoreModeratorCheckForCW = false, -- может ли игнорировать проверку на модератора если сматерится/зафлудит/закапсит в чат. true - будет получать муты, false - реплику в чат
- canStopVotes = true, -- может отменять голосование
- canHideFromModsCommand = true, -- может использовать команду для скрытия себя из списка -mods
- canUseRetranslate = true, -- может говорить от имени бота
- },
- Tekyera = {
- infiniteVote = true, -- может голосовать бесконечно
- canAccessVoteStats = true, -- может юзать votestats (инфа о текущем голосовании)
- canSkipVoteStartCondition = true, -- может начать голосование, даже если startCondition для голосования не соблюдено
- canSkipVoteGlobalCooldown = true, -- может игнорировать глобальный кулдаун на голосование
- canSkipVotePersonalCooldown = true, -- может игнорировать личный кулдаун на голосование
- canSkipQuestionsCooldown = true, -- может игнорировать кулдаун на вопросы c.timeout_question
- canSkipServerCommandCooldown = true, -- может игнорировать кулдаун команды -server
- canCancelIssuedMutes = true, -- может отменять муты, выданные ботом
- canNOTGetIgnoredByBot = true, -- если true то не может быть проигнорирован ботом (для команд глобального чата) после получения мута от него
- canCurse = false, -- может ли материться в чат (если true, бот будет игнорировать мат)
- canIgnoreModeratorCheckForCW = false, -- может ли игнорировать проверку на модератора если сматерится/зафлудит/закапсит в чат. true - будет получать муты, false - реплику в чат
- canStopVotes = true, -- может отменять голосование
- canHideFromModsCommand = true, -- может использовать команду для скрытия себя из списка -mods
- canUseRetranslate = true, -- может говорить от имени бота
- },
- Martinez = {
- infiniteVote = true, -- может голосовать бесконечно
- canAccessVoteStats = true, -- может юзать votestats (инфа о текущем голосовании)
- canSkipVoteStartCondition = true, -- может начать голосование, даже если startCondition для голосования не соблюдено
- canSkipVoteGlobalCooldown = true, -- может игнорировать глобальный кулдаун на голосование
- canSkipVotePersonalCooldown = true, -- может игнорировать личный кулдаун на голосование
- canSkipQuestionsCooldown = true, -- может игнорировать кулдаун на вопросы c.timeout_question
- canSkipServerCommandCooldown = true, -- может игнорировать кулдаун команды -server
- canCancelIssuedMutes = true, -- может отменять муты, выданные ботом
- canNOTGetIgnoredByBot = true, -- если true то не может быть проигнорирован ботом (для команд глобального чата) после получения мута от него
- canCurse = false, -- может ли материться в чат (если true, бот будет игнорировать мат)
- canIgnoreModeratorCheckForCW = false, -- может ли игнорировать проверку на модератора если сматерится/зафлудит/закапсит в чат. true - будет получать муты, false - реплику в чат
- canStopVotes = true, -- может отменять голосование
- canHideFromModsCommand = true, -- может использовать команду для скрытия себя из списка -mods
- canUseRetranslate = true, -- может говорить от имени бота
- },
- }
- local historyTabs = {
- [1] = {name = "Commands/Questions", start = 2, width = 50, prefix = "[Q]", prefix2 = "%[Q%]", prefixColor = 0x00ff00}, -- 2 45
- [2] = {name = "Warned/Muted", start = 54, width = 106,prefix = "[M]", prefix2 = "%[M%]", prefixColor = 0xcd8700}, --49 91
- --[3] = {name = "Warned/Muted", start = 110, width = 50,prefix = "[M]", prefix2 = "%[M%]", prefixColor = 0xcd8700},
- }
- local censoredWords = {
- [1] = {list = {"пидор", "пидар", "ебать", "ёбаный", "ёбанный", "ёбырь", "ебырь", "ебнутый", "ёбнутый", "хуй ", "нихуя", "хуя ", "ебись", "ебать", "пидр", "пидор", "хуйня", "хуи ", "хуила", "нахуй", "похуй", "хуев", "хуёв", "хуес", "хуег", "отъебись", "отьебись", "отебись", "долбаеб", "долбаёб", "долбоеб", "долбоёб", "хуета", "хуита", "пизд", "ебан", "ёбан", "ебал", "наеб", "наёб", "ебу", "ебло", "уебок", "уёбо", "уебан", "уебки", "уёбки", "ахуеть", "ахуительно", "ахуенно", "охуенно", "охуительно", "заебись", "заебал", "ебет", "ебёт", "ебаца", "ебацца", "нехуя", "ебацо", "ибаца", "ибацца", "ипацца", "ебанат", "уебище", "уёбище", "выеб", "блядь", "блядин", "хуйня", "выбляд", "еблищ", "пиздяч", "впиздяч", "выблядова", "blyad", "blyat", "ebal", "cyka", "suka", "pidor", "pidar", "hui", "huesos", "ueban", "uebok", "xyi", "xui", "пидрила", "курва", "мразь", "залуп", "гандон"}, duration = 1800},
- [2] = {list = {}, duration = 1200},
- [3] = {list = {"бля", "сука", "чмо", "педик", "хули", "мудак", "мудила", "мудень", "мудозвон",}, duration = "warn"},
- }
- c.screenWidth, c.screenHeight = gpu.getResolution()
- c.history_rows = c.screenHeight - c.history_borderUp - c.history_borderDown
- local history = {}
- local messages = {}
- local mods = {
- { group = "Тех.Админ", prefixColor = "§4", nameColor = "§7", list = {"lLuffy",}},
- { group = "Дизайнер", prefixColor = "§9", nameColor = "§3", list = {"Dark_Time",}},
- { group = "Гл.модератор", prefixColor = "§9", nameColor = "§3", list = {"ogrezem", "Martinez"}},
- { group = "Ст.модератор", prefixColor = "§3", nameColor = "§b", list = {"qwe",}},
- { group = "Разработчик", prefixColor = "§d", nameColor = "§d", list = {"krovyaka",}},
- { group = "Строитель", prefixColor = "§d", nameColor = "§d", list = {"msDrakononenko","titan123023",}},
- { group = "Модератор", prefixColor = "§4", nameColor = "§6", list = {"ImRazen",}},
- { group = "Помощник", prefixColor = "§2", nameColor = "§a", list = {"DJ_SonyBlaze","Pahanchegg"}},
- { group = "Стажёр", prefixColor = "§a", nameColor = "§a", list = {"qwe",}},
- }
- local coloring = {
- ["&0"] = 1, ["&1"] = 1, ["&2"] = 1, ["&3"] = 1, ["&4"] = 1, ["&5"] = 1, ["&6"] = 1, ["&7"] = 1,
- ["&8"] = 1, ["&9"] = 1, ["&a"] = 1, ["&b"] = 1, ["&c"] = 1, ["&d"] = 1, ["&e"] = 1, ["&f"] = 1,
- }
- local ignoredCaps = {
- "ЭХПФ", "МФЭХ", "МФЭ", "НЛО", "МЭ"
- }
- loadfile("/home/Bot/_q")()
- loadfile("/home/Bot/_rules")()
- local mainWorld = 0 -- id главного мира, через component.debug.getWorld().getDimensionId() например
- local activeVote = false -- "=votesun"
- local activeVoteTimerId
- local hasUserVoted = {}
- local currentVoteResults = {
- yes = 0,
- no = 0,
- }
- local questionLastTriggered = {}
- local mutes = {} -- mutes["Shyvana"].29111 - содержит computer.uptime() момента, когда мут истечет
- local warns = {} -- warns["Shyvana"].29111 - содержит computer.uptime() момента, когда варн истечет
- local serverCommandCooldowns = {} -- serverCommandCooldowns["Shyvana"].29111 - содержит computer.uptime() момента, когда кд на команду -server истечет
- function isRaining()
- return debug.getWorld(mainWorld).isRaining()
- end
- function turnOffRain()
- debug.getWorld(mainWorld).setRaining(false)
- end
- function setMorning()
- debug.getWorld(mainWorld).setTime(0)
- end
- function none()
- return true
- end
- local votes = {
- ["-votesun"] = {
- lastActivatedByPlayer = {}, -- не трогать
- lastActivated = 0, -- не трогать
- StaticGlobalCooldown = 300, -- глобальный кулдаун для всех игроков на использование именно этого голосования
- StaticPersonalCooldown = 1200, -- личный кулдаун каждого игрока на использование именно этого голосования
- text = "отключение дождя", -- "игрок начал голосование за" ..
- duration = 25, -- время в секундах, которое дается на голосование
- isEasy = true, -- легко проголосовать "да" (не юзать в votemute). перевес определяется в c.vote_easy_yes_to_pass
- startCondition = isRaining, -- возможно начать голосование только если эта функция вернет true. ВСЕ ФУНКЦИИ ДОЛЖНЫ СТОЯТЬ ВЫШЕ ЭТОЙ ТАБЛИЦЫ. указать none если условие не нужно
- denyMsg = "в данный момент дождя нет", -- что получит пользователь в ответ если startCondition == false
- passFunction = turnOffRain, -- функция, которая вызовется если голосование пройдет
- passMessage = "дождь отключен", -- отчет в глобал чат если голосование пройдет
- failFunction = none, -- функция, которая вызовется, если голосование провалится
- failMessage = "дождь не отключен", -- отчет в глобал чат если голосование не пройдет
- },
- ["-voteday"] = {
- lastActivatedByPlayer = {},
- lastActivated = 0,
- StaticGlobalCooldown = 300,
- StaticPersonalCooldown = 1200,
- text = "смену времени суток на утро",
- duration = 25,
- isEasy = true,
- startCondition = none,
- denyMsg = " ",
- passFunction = setMorning,
- passMessage = "время суток сменено на утро",
- failFunction = none,
- failMessage = "время суток не изменено",
- },
- }
- function say(msg)
- if LIVE then
- chat.say(c.chat_name .. tostring(msg))
- else
- chat.say(c.chat_name .. tostring(msg),40)
- end
- end
- function sayLocal(msg)
- chat.say("local: " .. c.chat_name .. tostring(msg),40)
- end
- function cmdReal(command)
- component.opencb.execute(tostring(command))
- end
- function cmd(command)
- if LIVE then
- component.opencb.execute(tostring(command))
- else
- say("CMD: " .. command)
- end
- end
- function whisper(player,text)
- component.opencb.execute("m " .. player .. " " .. tostring(text))
- end
- function drawMainFrame()
- setFG(c.frame_main_color)
- gpu.set(1,1,string.rep("─",c.screenWidth)) -- ═
- gpu.set(1,c.screenHeight,string.rep("─",c.screenWidth)) -- ═
- gpu.set(1,1,string.rep("│",c.screenHeight),true) -- ║
- gpu.set(c.screenWidth,1,string.rep("│",c.screenHeight),true)
- gpu.set(1,1,"┌") --╔
- gpu.set(c.screenWidth,1,"┐")
- gpu.set(1,c.screenHeight,"└")
- gpu.set(c.screenWidth,c.screenHeight,"┘")
- for i = 1,#historyTabs do
- drawCenteredText(historyTabs[i].start,c.history_tabs_y,historyTabs[i].width,"┤ " .. historyTabs[i].name .. " ├")
- setFG(c.frame_tabs_name_color)
- drawCenteredText(historyTabs[i].start,c.history_tabs_y,historyTabs[i].width,historyTabs[i].name )
- setFG(c.frame_main_color)
- end
- for ii = 1,#historyTabs-1 do
- gpu.set(historyTabs[ii].start+historyTabs[ii].width+1,c.history_tabs_y,string.rep("│",c.history_rows+2),true)
- gpu.set(historyTabs[ii].start+historyTabs[ii].width+1,c.history_tabs_y,"┬")
- gpu.set(historyTabs[ii].start+historyTabs[ii].width+1,c.history_tabs_y+c.history_rows+1,"┴")
- end
- setFG(c.white)
- end
- function historyInitialize()
- for i = 1,#historyTabs do
- history[i] = {}
- for ii = 1,c.history_rows do
- history[i][ii] = {text = "", highlight = nil}
- end
- end
- end
- function drawCenteredText(x,y,width,text)
- gpu.set(x+math.floor(width/2)-math.floor(unicode.len(text)/2),y,text)
- end
- function log(index,text,highlightedText)
- local text = historyTabs[index].prefix .. text
- local extra = unicode.len(text) - historyTabs[index].width
- if extra <= 0 then
- table.insert(history[index],{text = text .. string.rep(" ",-extra), highlight = highlightedText})
- table.remove(history[index],1)
- else
- local text1
- local text2
- if highlightedText then
- local a,b = string.find(text,highlightedText)
- if a then
- if a <= historyTabs[index].width and b > historyTabs[index].width then
- text1 = unicode.sub(text,0,a-1)
- text2 = unicode.sub(text,a,a+historyTabs[index].width)
- else
- text1 = unicode.sub(text,0,historyTabs[index].width)
- text2 = unicode.sub(text,historyTabs[index].width+1,historyTabs[index].width*2)
- end
- else
- text1 = unicode.sub(text,0,historyTabs[index].width)
- text2 = unicode.sub(text,historyTabs[index].width+1,historyTabs[index].width*2)
- end
- else
- text1 = unicode.sub(text,0,historyTabs[index].width)
- text2 = unicode.sub(text,historyTabs[index].width+1,historyTabs[index].width*2)
- end
- table.insert(history[index],{text = text1 .. string.rep(" ",historyTabs[index].width-unicode.len(text1)), highlight = highlightedText})
- table.insert(history[index],{text = text2 .. string.rep(" ",historyTabs[index].width-unicode.len(text2)), highlight = highlightedText})
- table.remove(history[index],1)
- table.remove(history[index],2)
- end
- historyDraw()
- end
- function historyDraw()
- for column = 1,#historyTabs do
- for row = c.history_rows,1,-1 do
- drawStringWithHighlight(historyTabs[column].start,c.history_borderUp+row,history[column][row].text,history[column][row].highlight,column)
- end
- end
- end
- function drawStringWithHighlight(x,y,string,highlight,index)
- if index and string.find(string,historyTabs[index].prefix2) == 1 then
- gpu.set(x,y,string.sub(historyTabs[index].prefix,1,1))
- setFG(historyTabs[index].prefixColor)
- gpu.set(x+1,y,string.sub(historyTabs[index].prefix,2,2))
- setFG(c.white)
- gpu.set(x+2,y,string.sub(historyTabs[index].prefix,3,3))
- local newstring = string.sub(string,string.len(historyTabs[index].prefix)+1)
- drawStringWithHighlight(x+string.len(historyTabs[index].prefix),y,newstring,highlight)
- else
- if highlight ~= nil then
- local a,b = string.find(unicode.lower(string),highlight)
- if a == nil then
- gpu.set(x,y,string)
- elseif a > 1 then
- local newstring0 = string.sub(string,0,a-1)
- gpu.set(x,y,newstring0)
- local newstring = string.sub(string,a)
- drawStringWithHighlight(x+unicode.len(newstring0),y,newstring,highlight)
- elseif a == 1 then
- setFG(c.history_highglight_color)
- local newstring0 = string.sub(string,0,b)
- gpu.set(x,y,newstring0)
- setFG(0xffffff)
- local newstring = string.sub(string,b+1)
- drawStringWithHighlight(x+unicode.len(newstring0),y,newstring,highlight)
- end
- else
- gpu.set(x,y,string)
- end
- end
- end
- function isModerator(name)
- for _,group in ipairs(mods) do
- for _,nick in ipairs(group.list) do
- if nick == name then
- return true
- end
- end
- end
- return false
- end
- function isPlayerMuted(name)
- local currentTime = computer.uptime()
- if mutes[name] and (mutes[name] > currentTime) then
- return true, math.floor(mutes[name] - currentTime)
- else
- return false
- end
- end
- function isPlayerWarned(name) -- имеет ли активный варн
- local currentTime = computer.uptime()
- if warns[name] and (warns[name] > currentTime) then
- return true, math.floor(warns[name] - currentTime)
- else
- return false
- end
- end
- function canPlayerUseServerCommand(name)
- local currentTime = computer.uptime()
- if serverCommandCooldowns[name] and (serverCommandCooldowns[name] > currentTime) then
- return false, math.floor(serverCommandCooldowns[name] - currentTime)
- else
- return true
- end
- end
- function tempMute(name,duration,reason)
- mutes[name] = computer.uptime() + duration
- cmd("tempmute " .. name .. " " .. duration .. " sec " .. reason)
- end
- function isGlobal(msg)
- if LIVE == true then
- if string.find(msg,"!") == 1 then
- return true
- else
- return false
- end
- else
- if string.find(msg,"%.") == 1 or string.find(msg,"!") == 1 then
- return true
- else
- return false
- end
- end
- end
- function isOnline(player)
- if debug.getPlayer(player).getGameType() == nil then
- return false
- else
- return true
- end
- end
- function deColor(string)
- local text = string
- for k,_ in pairs(coloring) do
- text = string.gsub(text,k,"")
- end
- return text
- end
- function processMods(msg0,player)
- local msg = unicode.lower(msg0)
- if msg == c.command_mods then
- local strings = {}
- log(1,player .. ": " .. msg0)
- local t = debug.getPlayers()
- for index,this in ipairs(mods) do
- for _,name in ipairs(this.list) do
- if isOnline(name) then
- if (not masters[name]) or (not masters[name].undetectable) then
- table.insert(strings,"m " .. player .. " §aonline §8> [" .. this.prefixColor .. this.group .. "§8] " .. this.nameColor .. name)
- end
- end
- end
- end
- for k,v in ipairs(strings) do
- cmdReal(v)
- end
- end
- end
- function processQuestions(msg0,name)
- local msg = unicode.lower(msg0)
- local currentTime = computer.uptime()
- function checkWordBlock(wordblock)
- for _,word in ipairs(wordblock) do
- if string.find(msg,word) then
- return true
- end
- end
- return false
- end
- function canTriggerQuestion(ind)
- if questionLastTriggered[ind] then
- if (questionLastTriggered[ind] + c.timeout_question) > currentTime then
- return false
- else
- return true
- end
- else
- return true
- end
- end
- for ind,question in ipairs(Q) do
- local shouldAnswer = true
- for _,wordblock in ipairs(question) do
- if checkWordBlock(wordblock) == false then
- shouldAnswer = false
- break
- end
- end
- if shouldAnswer then
- if canTriggerQuestion(ind) or (masters[name] and masters[name].canSkipQuestionsCooldown) then
- say(Q[ind].response)
- questionLastTriggered[ind] = currentTime
- log(1,name .. ": " .. msg0)
- return true
- end
- end
- end
- end
- function processCensoredWords(msg0,name)
- local msg = unicode.lower(msg0)
- if not (masters[name] and masters[name].canCurse) then
- for _,wordSet in ipairs(censoredWords) do
- for _,word in pairs(wordSet.list) do
- if string.find(msg,word) then
- if not string.find(msg,"%S" .. word) then
- if isModerator(name) == false or (masters[name] and masters[name].canIgnoreModeratorCheckForCW) then
- if wordSet.duration == "warn" then
- if not isPlayerWarned(name) then
- cmd("warn " .. name .. " autowarn 3.1 (ругательства)")
- warns[name] = computer.uptime() + c.warn_decay
- log(2,"(3.1) warn " .. name .. ": " .. msg0,word)
- else
- tempMute(name,c.double_warn_mute_duration,"automute 3.1 (ругательства)+")
- log(2,"(3.1) " .. name .. ": " .. msg0,word)
- warns[name] = nil
- end
- return true
- else
- tempMute(name,wordSet.duration,"automute 3.1 (ругательства)")
- log(2,"(3.1) " .. name .. ": " .. msg0,word)
- return true
- end
- else
- say(c.color1 .. name .. ", ты же модератор, не ругайся")
- return true
- end
- end
- end
- end
- end
- end
- end
- function processInf(msg0,name)
- local msg = unicode.lower(msg0)
- if msg == c.command_inf then
- whisper(name,c.color1 .. "необходимо указать пункт правил, например, " .. c.color2 .. c.command_inf .. " 3.1")
- else
- if string.find(msg,c.command_inf .. " ") == 1 then
- local rule = rules[string.sub(msg,string.len(c.command_inf)+2)] or rules[string.gsub(string.sub(msg,string.len(c.command_inf)+2),",",".")]
- if rule then
- whisper(name,c.color2 .. string.gsub(string.sub(msg,string.len(c.command_inf)+2),",",".") .. ": " .. c.color1 .. rule.text)
- if rule.punishment then
- whisper(name,string.gsub(rule.punishment,"Наказание:",c.color2 .. "Наказание:" .. c.color1))
- end
- log(1,name .. ": " .. msg0)
- else
- whisper(name,c.color1 .. "пункт правил указан неверно")
- end
- end
- end
- end
- function processCaps(msg,name)
- local newmsg
- function isUsernameBad(username)
- local username = string.gsub(username,"%d","")
- local username = string.gsub(username,"%p","")
- local total = unicode.len(username)
- if total > 5 then
- local bad = 0
- for i = 1,total do
- local char = unicode.sub(username,i,i)
- if char ~= unicode.lower(char) then
- bad = bad + 1
- end
- end
- if bad/total > c.ratio_caps_symbol then
- return true
- else
- return false
- end
- else
- return false
- end
- end
- function getBadUsernames()
- local t = debug.getPlayers()
- local res = {}
- for _,player in ipairs(t) do
- if isUsernameBad(player) then
- table.insert(res,player)
- end
- end
- return res
- end
- for _,word in ipairs(ignoredCaps) do
- newmsg = string.gsub(msg,word,"")
- end
- local newmsg = string.gsub(newmsg,"%d","")
- local newmsg = string.gsub(newmsg,"%p","")
- local newmsg = string.gsub(newmsg," ","")
- if unicode.len(newmsg) > 7 then
- local total = unicode.len(newmsg)
- local bad = 0
- for i = 1,total do
- local char = unicode.sub(newmsg,i,i)
- if char ~= unicode.lower(char) then
- bad = bad + 1
- end
- end
- if bad/total > c.ratio_caps_symbol then
- for k,player in ipairs(getBadUsernames()) do
- if string.find(msg,player) then
- return true
- end
- end
- if isModerator(name) == false or (masters[name] and masters[name].canIgnoreModeratorCheckForCW) then
- tempMute(name,c.duration_mute_caps,"automute 3.1 (капс)")
- log(2,"3.1(caps)" .. name .. ": " .. msg)
- else
- say(c.color1 .. name .. ", ты же модератор, не капси")
- end
- end
- end
- end
- function processSymbolFlood(msg,name)
- local len1 = unicode.len(msg)
- if len1 >= 8 then
- local _,len2 = string.gsub(msg,"%p","")
- if (len2/len1) > c.ratio_flood_symbol then
- if isModerator(name) == false or (masters[name] and masters[name].canIgnoreModeratorCheckForCW) then
- tempMute(name,c.duration_mute_symbol_flood,"automute 3.1 (флуд символами)")
- log(2,"3.1 (symbol flood)" .. name .. ": " .. msg)
- else
- say(c.color1 .. name .. ", ты же модератор, не флуди")
- end
- end
- end
- end
- function processFlood(msg0,name)
- local msg = unicode.lower(msg0)
- local function isTradeMsg(msg)
- local len = unicode.len(msg)
- local tradeFilter = {"купл","продам",}
- local tradeFilter2 = {"warp"}
- for _,word in ipairs(tradeFilter) do
- if string.find(msg,word) and len > 12 then
- return true
- end
- end
- for _,word in ipairs(tradeFilter2) do
- if string.find(msg,word) and len > 30 then
- return true
- end
- end
- return false
- end
- local isTrade = isTradeMsg(msg)
- local currentTime = computer.uptime()
- if not messages[name] then
- messages[name] = {}
- end
- if not messages[name].previous then
- messages[name].anyTradeTimers = {}
- for i = 1,c.flood_any_trade_messages_trigger do
- messages[name].anyTradeTimers[i] = 0
- end
- end
- if not messages[name].previous or messages[name].previous ~= msg or messages[name].time <= currentTime - c.flood_timeout then
- messages[name].previous = msg
- messages[name].time = currentTime
- messages[name].subsequents = 1
- else
- messages[name].subsequents = messages[name].subsequents + 1
- end
- if isTrade then
- table.insert(messages[name].anyTradeTimers,currentTime)
- table.remove(messages[name].anyTradeTimers,1)
- end
- if isTrade and messages[name].subsequents >= c.flood_identical_trade_messages_trigger then
- if isModerator(name) == false or (masters[name] and masters[name].canIgnoreModeratorCheckForCW) then
- tempMute(name,c.duration_mute_flood,"automute 3.6 (частая реклама)")
- messages[name].previous = nil
- log(2,"(3.6: x" .. c.flood_identical_trade_messages_trigger .." in a row)" .. name .. ": " .. msg0,word)
- else
- say(c.color1 .. name .. ", ты же модератор, не флуди")
- end
- elseif messages[name].subsequents >= c.flood_normal_messages_trigger then
- if isModerator(name) == false or (masters[name] and masters[name].canIgnoreModeratorCheckForCW) then
- tempMute(name,c.duration_mute_flood,"automute 3.1 (флуд)")
- messages[name].previous = nil
- log(2,"(3.1: x" .. c.flood_normal_messages_trigger ..")" .. name .. ": " .. msg0,word)
- else
- say(c.color1 .. name .. ", ты же модератор, не флуди")
- end
- elseif currentTime - messages[name].anyTradeTimers[1] <= c.flood_any_trade_messages_period then
- if isModerator(name) == false or (masters[name] and masters[name].canIgnoreModeratorCheckForCW) then
- tempMute(name,c.duration_mute_flood,"automute 3.6 (частая реклама+)")
- messages[name].previous = nil
- log(2,"(3.6+: x" .. c.flood_any_trade_messages_trigger .." in " .. c.flood_any_trade_messages_period .. "s)" .. name .. ": " .. msg0,word)
- else
- say(c.color1 .. name .. ", ты же модератор, не флуди")
- end
- end
- end
- function getVoteCurrentGlobalCooldown(command)
- if votes[command] then
- local cd = (votes[command].lastActivated + votes[command].StaticGlobalCooldown) - computer.uptime()
- if cd <= 0 then
- return 0
- elseif cd > 0 then
- return cd
- end
- else
- error("#1")
- end
- end
- function getCurrentVoteTimer()
- if activeVote then
- local time = (votes[activeVote].lastActivated + votes[activeVote].duration) - computer.uptime()
- if time > 0 then
- return time
- else
- return 0
- end
- else
- return "NIL"
- end
- end
- function getVoteCurrentPersonalCooldown(command,name)
- if votes[command] then
- local last = votes[command].lastActivatedByPlayer[name] or 0
- local cd = (last + votes[command].StaticPersonalCooldown) - computer.uptime()
- if cd <= 0 then
- return 0
- elseif cd > 0 then
- return cd
- end
- else
- error("#2")
- end
- end
- function pushEndvoteSignal()
- event.push("endvote",1) -- 1 значит что голосование закончилось само по себе и выдаст результат
- end
- function processVoteStart(msg0,name)
- local msg = unicode.lower(msg0)
- if votes[msg] then
- currentTime = computer.uptime()
- if not activeVote then
- if votes[msg].startCondition() == true or (masters[name] and masters[name].canSkipVoteStartCondition) then
- if getVoteCurrentGlobalCooldown(msg) == 0 or (masters[name] and masters[name].canSkipVoteGlobalCooldown) then
- if getVoteCurrentPersonalCooldown(msg,name) == 0 or (masters[name] and masters[name].canSkipVotePersonalCooldown) then
- log(1,name .. ": " .. msg0)
- activeVote = msg
- votes[msg].lastActivated = currentTime
- votes[msg].lastActivatedByPlayer[name] = currentTime
- activeVoteTimerId = event.timer(votes[msg].duration,pushEndvoteSignal,1)
- say(c.color1 .. "Игрок ".. c.color2 .. name .. c.color1 .. " начал голосование за " .. votes[msg].text)
- say(c.color1 .. "Введите " .. c.color2 .. c.command_yes .. c.color1 .. " или " .. c.color2 .. c.command_no .. c.color1 .. " в локальный чат. Голосование длится " .. c.color2 .. votes[msg].duration .. c.color1 .. " секунд")
- else
- local answer = c.color1 .. "твой личный кулдаун на это голосование еще не истек. Осталось " .. c.color2 .. math.floor(getVoteCurrentPersonalCooldown(msg,name)) .. c.color1 .. " секунд"
- whisper(name,answer)
- end
- else
- local answer = c.color1 .. "глобальный кулдаун на это голосование еще не истек. Осталось " .. c.color2 .. math.floor(getVoteCurrentGlobalCooldown(msg)) .. c.color1 .. " секунд"
- whisper(name,answer)
- end
- else
- local answer = c.color1 .. votes[msg].denyMsg
- whisper(name,answer)
- end
- else
- local answer = c.color1 .. "идет другое голосование"
- whisper(name,answer)
- end
- end
- end
- function processActiveVote(msg0,name)
- local msg = unicode.lower(msg0)
- if msg == c.command_yes or msg == c.command_no then
- if activeVote then
- if not hasUserVoted[name] or (masters[name] and masters[name].infiniteVote) then
- if msg == c.command_yes then
- currentVoteResults.yes = currentVoteResults.yes+1
- whisper(name,c.color1 .. "ты проголосовал §2\"за\"")
- elseif msg == c.command_no then
- currentVoteResults.no = currentVoteResults.no+1
- whisper(name,c.color1 .. "ты проголосовал §4\"против\"")
- end
- hasUserVoted[name] = true
- end
- else
- whisper(name,c.color1 .. "нет активных голосований")
- end
- end
- end
- function processServerCommand(msg,name)
- local msg = unicode.lower(msg)
- if msg == c.command_server then
- local can,leftt = canPlayerUseServerCommand(name)
- if can or (masters[name] and masters[name].canSkipServerCommandCooldown) then
- log(1,name .. ": " .. msg)
- local _,report = component.opencb.execute("mem")
- if report then
- local hour = string.match(report,"(%d+)%Dчас") or 0
- local min = string.match(report,"(%d+)%Dмину") or 0
- local sec = string.match(report,"(%d+)%Dсеку") or 0
- local tps = string.match(report,"TPS%D*(.-)\n") or "NIL"
- local left = c.server_reboot_period-(hour*3600+min*60+sec)
- local hoursleft = math.floor(left/3600)
- local minleft = math.floor((left-hoursleft*3600)/60)
- local secleft = math.floor(left-hoursleft*3600-minleft*60)
- local answer = c.color1 .. "До рестарта: "
- if hoursleft ~= 0 then
- answer = answer .. c.color2 .. hoursleft .. c.color1 .. " час(а) "
- end
- local answer = answer .. c.color2 .. minleft .. c.color1 .. " минут " .. c.color2 .. secleft .. c.color1 .. " секунд"
- whisper(name,c.color1 .. "TPS: " .. c.color2 .. tps)
- whisper(name,answer)
- serverCommandCooldowns[name] = computer.uptime() + c.server_command_personal_cooldown
- end
- else
- whisper(name,c.color1 .. "Времени до повторного использования этой команды: " .. c.color2 .. leftt .. c.color1 .. " секунд(ы)")
- end
- end
- end
- function processMasterCommand(msg,name)
- -- msg = unicode.lower(msg) мешает isplayermuted
- if masters[name] then
- local answer = ""
- if msg == c.command_votestats then
- if masters[name].canAccessVoteStats then
- if activeVote then
- answer = c.color1 .. "Активное голосование: " .. c.color2 .. activeVote .. c.color1 .. ": §2" .. currentVoteResults.yes .. c.color1 .. "/§4" .. currentVoteResults.no .. c.color1 .. ". До окончания: " .. c.color2 .. math.floor(getCurrentVoteTimer()) .. c.color1 .. " секунд"
- else
- answer = c.color1 .. "нет активных голосований"
- end
- else
- answer = c.color1 .. "у тебя нет доступа к этой команде"
- end
- elseif string.find(msg,c.command_is_player_muted) == 1 then
- local username = string.sub(msg,string.len(c.command_is_player_muted)+2)
- local a,b = isPlayerMuted(username)
- if a then
- answer = c.color2 .. tostring(a) .. c.color1 .. " : " .. c.color2 .. b .. c.color1 .. " секунд осталось"
- else
- answer = c.color2 .. tostring(a)
- end
- elseif string.find(msg,c.command_unmute) == 1 then
- if masters[name].canCancelIssuedMutes then
- local username = string.sub(msg,string.len(c.command_unmute)+2)
- unmute(username,name)
- else
- whisper(name,"у тебя нет доступа к " .. c.command_unmute)
- end
- elseif msg == c.command_votestop and masters[name].canStopVotes then
- event.push("endvote",2,name)
- elseif msg == c.command_toggle_detect then
- if masters[name].undetectable then
- whisper(name,c.color1 .. "теперь тебя видно в " .. c.color2 .. c.command_mods)
- masters[name].undetectable = nil
- else
- whisper(name,c.color1 .. "теперь тебя не видно в " .. c.color2 .. c.command_mods)
- masters[name].undetectable = true
- end
- elseif msg == c.command_memory_used then
- answer = c.color1 .. "Использование памяти: " .. c.color2 .. math.floor((computer.totalMemory()-computer.freeMemory())/1024) .. c.color1 .. "/" .. c.color2 .. math.floor(computer.totalMemory()/1024) .. " kB"
- elseif string.find(msg,c.command_retranslate) == 1 then
- if masters[name].canUseRetranslate then
- local speech = string.sub(msg,unicode.len(c.command_retranslate)+1)
- say(c.color1 .. speech)
- end
- end
- if answer ~= "" then
- whisper(name,answer)
- end
- end
- end
- function endCurrentVote(arg,name) --arg 1 или 2, 1 чтоб закончить голосование само по себе (таймером), 2 для принудительного закрытия без результатов
- if arg == 1 then
- say(c.color1 .. "Голосование окончено: §2\"за\"" .. c.color1 .. ": " .. c.color2 .. currentVoteResults.yes .. c.color1 .. ", §4\"против\"" .. c.color1 .. ": " .. c.color2 .. currentVoteResults.no)
- if votes[activeVote].isEasy then
- if currentVoteResults.yes - currentVoteResults.no >= c.vote_easy_yes_to_pass then
- votes[activeVote].passFunction()
- say(c.color1 .. votes[activeVote].passMessage)
- else
- votes[activeVote].failFunction()
- say(c.color1 .. votes[activeVote].failMessage)
- end
- end
- activeVote = nil
- currentVoteResults = {yes = 0, no = 0}
- hasUserVoted = {}
- elseif arg == 2 then
- if activeVote then
- event.cancel(activeVoteTimerId)
- say(c.color1 .. "Голосование остановлено игроком " .. c.color2 .. name)
- activeVote = nil
- currentVoteResults = {yes = 0, no = 0}
- hasUserVoted = {}
- else
- whisper(name,c.color1 .. "нет активных голосований")
- end
- end
- end
- function unmute(player,name) -- player - тот, кто в муте, name - заказчик
- local a,b = isPlayerMuted(player)
- if a then
- cmd("unmute " .. player)
- mutes[player] = nil
- whisper(name,"мут снят с " .. player .. " (оставалось " .. b .. " секунд)")
- say(c.color2 .. name .. c.color1 .. " отменил мут игрока " .. c.color2 .. player)
- else
- whisper(name,c.color1 .. "игрок " .. c.color2 .. player .. c.color1 .. " не имеет актуальных мутов от бота или неправильно указано имя (чувствительно к регистру)")
- end
- end
- function processHelp(msg,name)
- msg = unicode.lower(msg)
- if msg == c.command_help then
- local answer
- function addCommand(command,description)
- answer = answer .. c.color2 .. command .. " " .. c.color1 .. "- " .. description .. "\n"
- end
- answer = c.color2 .. "Доступные команды: \n"
- addCommand(c.command_inf,"информация по определенному пункту правил (напр. " .. c.color2 .. c.command_inf .. " 3.1" .. c.color1 .. ")")
- addCommand(c.command_mods,"список модераторов онлайн")
- addCommand(c.command_server,"узнать время до рестарта сервера и ТПС")
- addCommand("-votesun","начать голосование за отключение дождя")
- addCommand("-voteday","начать голосование за установку времени на утро")
- addCommand(c.command_yes .. " / " .. c.command_no,"отдать голос в текущем голосовании")
- whisper(name,answer)
- end
- end
- function processHelp2(msg,name)
- msg = unicode.lower(msg)
- if msg == c.command_help2 then
- local answer
- function addCommand(command,description)
- answer = answer .. c.color2 .. command .. " " .. c.color1 .. "- " .. description .. "\n"
- end
- answer = c.color2 .. "Доступные команды для администраторов бота: \n (работают только при наличии соответствующих прав в конфиге)\n"
- addCommand(c.command_votestats,"получить инфу о текущем голосовании")
- addCommand(c.command_votestop,"отменить текущее голосование")
- addCommand(c.command_is_player_muted,"проверить наличие текущих мутов от бота указанному игроку (неоходимо соблюдать регистр)")
- addCommand(c.command_unmute,"отменить выданный ботом мут (если отменить вручную, бот продолжит игнорировать игрока на время бывшего мута)")
- addCommand(c.command_toggle_detect,"стать невидимым для команды " .. c.color2 .. c.command_mods)
- addCommand(c.command_memory_used,"инфа по оперативной памяти бота")
- whisper(name,answer)
- end
- end
- function getEvent()
- local evt,arg1,name,msg = event.pullMultiple("chat_message","endvote")
- if evt == "chat_message" then
- msg = deColor(msg)
- if isGlobal(msg) then
- if not isPlayerMuted(name) or (masters[name] and masters[name].canNOTGetIgnoredByBot) then
- msg = string.sub(msg,2)
- processCaps(msg,name)
- processQuestions(msg,name)
- processCensoredWords(msg,name)
- processSymbolFlood(msg,name)
- processFlood(msg,name)
- --log(3,name .. ": " .. msg,"test")
- else
- --log(3,"(muted)" .. name .. ": " .. msg,"test")
- end
- else -- is local
- processHelp(msg,name)
- processHelp2(msg,name)
- processActiveVote(msg,name)
- processVoteStart(msg,name)
- processInf(msg,name)
- processMods(msg,name)
- processServerCommand(msg,name)
- processMasterCommand(msg,name)
- end
- elseif evt == "endvote" then
- endCurrentVote(arg1,name)
- end
- end
- term.clear()
- drawMainFrame()
- historyInitialize()
- while true do
- getEvent()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement