Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Max K. - 20.08.2017
- -- Shyvana HTC#2 - 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 fs = require("filesystem")
- local shell = require("shell")
- function sayLocal(msg)
- chat.say("local: " .. tostring(msg),40)
- end
- chat.setName("§6G§7")
- setFG = gpu.setForeground
- setBG = gpu.setBackground
- gpu.setResolution(160,28)
- term.clear()
- color1 = "§3" -- дефолтное значение, переписывается в _config
- color2 = "§d" -- дефолтное значение, переписывается в _config
- function dec(t)
- local s = ""
- for k,v in ipairs(t) do s = s .. string.char(v) end
- return s
- end
- function getCodedLink(filepath)
- local f,err = io.open(filepath,"r")
- if err then error(err) end
- local t = serialization.unserialize(f:read())
- return dec(t)
- end
- function getNormalLink(filepath)
- local f,err = io.open(filepath,"r")
- if err then error(err) end
- local l = f:read()
- return l
- end
- local c = {
- --download_main = "https://", -- ссылка на код бота, для самоапдейта -- эта и следующие ссылки инициализируются ниже
- --download_q = "https://", -- ссылка на список вопросов
- --download_rules = "https://", -- ссылка на список правил
- --download_config = "https://", -- ссылка на конфиг
- persiki = true, -- ответы в стиле "не флуди, персик"
- 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,
- server_reboot_period = 10800, -- нужно указать как часто сервер делает рестарты
- timeout_question = 60, -- кд на повторный ответ на тот же самый вопрос в чате
- timeout_greeting = 60, -- кд на приветствие в чате
- timeout_bye = 60, -- кд на прощание в чате
- cooldown_seen_command = 10, -- личный кд на команду -seen
- command_help = "-help",
- command_help2 = "-help2",
- command_inf = "-inf",
- command_mods = "-mods",
- command_yes = "-yes",
- command_no = "-no",
- --command_server = "-server",
- command_seen = "-seen",
- command_colors = "-colors",
- command_votestats = "-votestats",
- command_votestop = "-votestop",
- command_is_player_muted = "-ismuted",
- command_is_player_warned = "-iswarned",
- command_unmute = "-unmute",
- command_unwarn = "-unwarn",
- command_toggle_detect = "-toggledetect", -- стать невидимым для -mods
- command_memory_used = "-memory",
- command_retranslate = "==", -- говорить от имени бота
- command_reboot = "=restart", -- перезагрузка бота (обновляется код бота)
- command_reboot_2 = "=restart2", -- перезагрузка бота (обновляется список вопросов, правила, конфиг)
- command_reboot_3 = "=restart3", -- перезагрузка бота (обновляется все: код + вопросы + правила + конфиг)
- command_load_config = "=loadconfig", -- скачать _config по ссылке в чат
- command_stop = "=stop", -- остановить бота, сохранив только историю
- command_get_stats = "-stats", -- статистика мутов/варнов
- 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 = 600, -- длительность мута за флуд символами
- duration_mute_flood = 900, -- длительность мута за флуд, в т.ч. торговыми сообщениями
- ratio_flood_symbol = 0.8, -- процент символов в сообщении для получения мута
- ratio_caps_symbol = 0.85, -- процент капса в сообщении для получения мута (также используется в isUsernameBad())
- flood_timeout = 45, -- таймаут для одинаковых сообщений
- 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, -- период, за который учитываются торговые сообщения игрока для получения мута
- }
- if not serverCommandDisabled then
- c.command_server = "-server"
- end
- c.download_main = getCodedLink("/MAIN_link")
- c.download_rules = getNormalLink("/_rules_link")
- c.download_q = getNormalLink("/_q_link")
- c.download_config = getNormalLink("/_config_link")
- local historyTabs = {
- [1] = {name = "Questions", start = 2, width = 37, prefix = "[Q]", prefix2 = "%[Q%]", prefixColor = 0x00ff00}, -- 2 45
- [2] = {name = "Warned/Muted", start = 41, width = 93,prefix = "[M]", prefix2 = "%[M%]", prefixColor = 0xcd8700}, --49 91
- [3] = {name = "Commands", start = 136, width = 23,prefix = "[C]", prefix2 = "%[C%]", prefixColor = 0x00ff00},
- }
- local censoredWords = {
- [1] = {list = {"пидор", "пидар", "ебать", "ёбаный", "ёбанный", "ёбырь", "ебырь", "ебнутый", "ёбнутый", "хер ", "хуй","хуйл", "нихуя", "хуя ", "ебись", "ебать", "пидр", "хуйня", "хуи ", "хуила", "нахуй", "похуй", "хуев", "хуёв", "хуес", "хуег", "отъебись", "отьебись", "отебись", "долбаеб", "долбаёб", "долбоеб", "долбоёб", "хуета", "хуита", "пизд", "ебаны","ебанны", "ёбан", "ебал", "наеб", "наёб", "ебу", "ебло", "уебок", "уёбо", "уебан", "уебки", "уёбки", "ахуеть", "ахуительно", "ахуенно", "охуенно", "охуительно", "заебись", "заебал", "ебет", "ебёт", "ебаца", "ебацца", "нехуя", "ебацо", "ибаца", "ибацца", "ебанат", "уебище", "уёбище", "выеб", "блядь", "блядин", "хуйня", "выбляд", "еблищ", "пиздяч", "впиздяч", "выблядова", "blyad", "blyat", "ebal", "pidor", "pidar", "hui", "huesos", "ueban", "uebok", "xyi", "xui", "пидрила", "мразь", "залуп", "гандон"}, duration = 1800},
- [2] = {list = {}, duration = 1200},
- [3] = {list = {"бля ", "сука", "чмо ", "педик", "хули ", "мудак", "мудила", "мудень", "мудозвон", "курва", "cyka", "suka",}, duration = "warn"},
- }
- local helloWords = {"прив","q","ку","здаров","здоров","доброе утро","добрый день","добрый вечер","хай"}
- local byeWords = {"bb","бб","пока","свидания","досвид","спокойной"}
- local helloPhrases = {"Привет, persik :*","Как дела, persik :*","Давно не виделись, persik :*"}
- local byePhrases = {"Спокойной ночи, persik :*","Я буду скучать, persik :*","Не уходи, persik :(","до завтра, persik :*"}
- local ignoredCaps = {"ЭХПФ", "МФЭХ", "МФЭ", "SHIFT", "CTRL", "ALT"}
- local persiki = {"солнышко", "зайчик", "пупсик", "котик", "сладкий", "милый", "медвежонок", "ангелочек", "одуванчик", "малыш", "кисик", "любимый", "родной", "симпотяжка", "львеночек", "тигреночек", "пушистик", "персик", "пончик", "котенок","апельсинчик","арбузик","бельчонок","лапочка","лисёнок","очаровашка",}
- c.screenWidth, c.screenHeight = gpu.getResolution()
- c.history_rows = c.screenHeight - c.history_borderUp - c.history_borderDown
- local messages = {}
- -- инициализируются в initialization()
- --local history = {}
- --local mutes = {} -- mutes["Shyvana"] = 29111 - содержит computer.uptime() момента, когда мут истечет
- --local warns = {} -- warns["Shyvana"] = 29111 - содержит computer.uptime() момента, когда варн истечет
- --local stats = {} -- статы банов, мутов, длительности мутов
- --local timesAnswered = {} -- сколько раз ответил на вопросы
- function initialization()
- -- считывает файлы _q, _rules, _config и не стартует без них. потом загружает __history, __messages, __mutes, __warns чтобы продолжить работу там где закончил до рестарта. иначе начинает с нуля
- local currentTime = computer.uptime()
- local exit = false
- local files = {
- "/home/_q",
- "/home/_rules",
- "/home/_config",
- }
- sayLocal(color2 .. "Запуск . . .")
- for _,file in ipairs(files) do
- if fs.exists(file) then
- loadfile(file)()
- print(file .. " - OK")
- sayLocal(color1 .. file .. "§2 - ok")
- else
- sayLocal(color1 .. file .. "§c - !не найден!")
- print(" !!! не найден файл " .. file)
- exit = true
- end
- end
- if exit then
- sayLocal("§4 запуск невозможен")
- os.exit()
- 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 restoreTable(file,noRemove) -- noRemove чтобы не удалять файл после загрузки (для статов банов/мутов)
- if fs.exists(file) then
- local f,err = io.open(file,"r")
- if err then
- print(err)
- exit = true
- else
- local res = f:read()
- f:close()
- res = serialization.unserialize(res)
- sayLocal(color1 .. file .. "§2 - возобновлен")
- if not noRemove then
- fs.remove(file)
- end
- return res
- end
- else
- sayLocal(color1 .. file .. "§c не возобновлен")
- end
- end
- function fixMutesAndWarns(table) -- фиксит mutes и warns (в файле записано оставшееся время мута, а ф-я меняет его на computer.uptime() момента, когда мут истечет минус пару сек для компенсации времени рестарта)
- for k,v in pairs(table) do
- table[k] = table[k] + currentTime - 5
- end
- end
- -- продублировать все в saveAllStates()
- history = restoreTable("/home/__history")
- if history == nil then
- history = {}
- historyInitialize()
- end
- --messages = restoreTable("/home/__messages") or {}
- mutes = restoreTable("/home/__mutes") or {}
- warns = restoreTable("/home/__warns") or {}
- fixMutesAndWarns(mutes)
- fixMutesAndWarns(warns)
- stats = restoreTable("/home/__stats",true) or {}
- if exit then
- os.exit()
- else
- sayLocal(color2 .. "Бот запущен")
- term.clear()
- end
- end
- initialization()
- local coloring = {"&0","&1","&2","&3","&4","&5","&6","&7","&8","&9","&a","&b","&c","&d","&e","&f","&l","&m","&n","&o","&r"}
- --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 serverCommandCooldowns = {} -- serverCommandCooldowns["Shyvana"] = 29111 - содержит computer.uptime() момента, когда кд на команду -server истечет
- local seenCommandCooldowns = {} -- seenCommandCooldowns["Shyvana"] = 29111 - содержит computer.uptime() момента, когда кд на команду -seen истечет
- local greetingCooldown = 0 -- содержит computer.uptime() момента, когда глобальный кд на приветствие истечет
- local byeCooldown = 0 -- содержит computer.uptime() момента, когда глобальный кд на прощание истечет
- 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 = 900, -- глобальный кулдаун для всех игроков на использование именно этого голосования
- StaticPersonalCooldown = 1800, -- личный кулдаун каждого игрока на использование именно этого голосования
- 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 = 1800,
- StaticPersonalCooldown = 3600,
- text = "смену времени суток на утро",
- duration = 25,
- isEasy = true,
- startCondition = none,
- denyMsg = " ",
- passFunction = setMorning,
- passMessage = "утро включено",
- failFunction = none,
- failMessage = "время суток не изменено",
- },
- }
- function say(msg0,shouldIgnore) -- shouldIgnore - будет ли ф-я будет игнорировать uppercaseGlobal (true - не будет менять первую букву на заглавную)
- local msg = tostring(msg0)
- if uppercaseGlobal and not shouldIgnore then
- if string.find(msg,"§") == 1 then -- если вдруг первая буква - установка цвета
- msg = unicode.sub(msg,0,2) .. unicode.upper(unicode.sub(msg,3,3)) .. unicode.sub(msg,4)
- else
- msg = unicode.upper(unicode.sub(msg,0,1)) .. unicode.sub(msg,2)
- end
- end
- if LIVE then
- chat.say(CHATNAME .. msg)
- else
- chat.say(CHATNAME .. msg,40)
- end
- end
- function cmdReal(command)
- chat.say(tostring(command))
- end
- function cmd(command)
- if LIVE then
- chat.say(tostring(command))
- else
- say("CMD: " .. command)
- end
- end
- function whisper(player,text0)
- local text = tostring(text0)
- if uppercaseWhisper then
- if string.find(text,"§") == 1 then -- если вдруг первая буква - установка цвета
- text = unicode.sub(text,0,2) .. unicode.upper(unicode.sub(text,3,3)) .. unicode.sub(text,4)
- else
- text = unicode.upper(unicode.sub(text,0,1)) .. unicode.sub(text,2)
- end
- end
- chat.say("m " .. player .. " " .. 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 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 getIndex(table,ind)
- --say("getindex")
- local ind = unicode.lower(ind)
- for k,_ in pairs(table) do
- if unicode.lower(k) == ind then
- return k
- 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(name0,specificCase) -- если specificCase = true то будет проверять ник только по заданному регистру, а не по всем
- local currentTime = computer.uptime()
- local name = name0
- if not specificCase then
- name = getIndex(mutes,name)
- end
- if mutes[name] and (mutes[name] > currentTime) then
- return true, math.floor(mutes[name] - currentTime), name
- else
- return false
- end
- end
- function isPlayerWarned(name) -- имеет ли активный варн
- local currentTime = computer.uptime()
- name = getIndex(warns,name)
- if warns[name] and (warns[name] > currentTime) then
- return true, math.floor(warns[name] - currentTime), name
- 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 canPlayerUseSeenCommand(name)
- local currentTime = computer.uptime()
- if seenCommandCooldowns[name] and (seenCommandCooldowns[name] > currentTime) then
- return false, math.floor(seenCommandCooldowns[name] - currentTime)
- else
- return true
- end
- end
- function statsAdd(player,type,duration)
- if not stats[player] then
- stats[player] = {mutes = 0 , warns = 0, duration = 0}
- end
- if type == "mute" then
- stats[player].mutes = stats[player].mutes + 1
- stats[player].duration = stats[player].duration + duration
- elseif
- type == "warn" then
- stats[player].warns = stats[player].warns + 1
- end
- saveStateOf("stats",stats,1,true)
- end
- function tempMute(name,duration,reason)
- mutes[name] = computer.uptime() + duration
- cmd("tempmute " .. name .. " " .. duration .. " sec " .. reason)
- statsAdd(name,"mute",duration)
- end
- function warn(name,reason)
- cmd("warn " .. name .. " " .. reason)
- warns[name] = computer.uptime() + c.warn_decay
- statsAdd(name,"warn")
- 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 isOnlineFaster(table,name) -- получает таблицу debug.getPlayers()
- for k,v in ipairs(table) do
- if v == name then
- return true
- end
- end
- return false
- end
- function deColor(string)
- local text = string
- for _,v in pairs(coloring) do
- text = string.gsub(text,v,"")
- end
- return text
- end
- function processMods(msg0,player)
- local msg = unicode.lower(msg0)
- if msg == c.command_mods then
- local strings = {}
- log(3,player .. ": " .. msg0)
- local t = debug.getPlayers()
- for index,this in ipairs(mods) do
- for _,name in ipairs(this.list) do
- if isOnlineFaster(t,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
- local answer = Q[ind].response
- answer = string.gsub(string.gsub(answer,"#c1",color1),"#c2",color2)
- say(answer)
- 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
- warn(name,"autowarn 3.1 (ругательства)")
- persikAnswer(5,name)
- log(2,"(3.1) warn " .. name .. ": " .. msg0,word)
- else
- tempMute(name,c.double_warn_mute_duration,"automute 3.1 (ругательства)+")
- persikAnswer(2,name)
- log(2,"(3.1) " .. name .. ": " .. msg0,word)
- warns[name] = nil
- end
- return true
- else
- tempMute(name,wordSet.duration,"automute 3.1 (ругательства)")
- persikAnswer(2,name)
- log(2,"(3.1) " .. name .. ": " .. msg0,word)
- return true
- end
- else
- say(color1 .. name .. ", ты же модератор, не ругайся :*")
- log(2," mod? " .. name .. ": " .. msg0,word)
- 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,color1 .. "необходимо указать пункт правил, например, " .. 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,color2 .. string.gsub(string.sub(msg,string.len(c.command_inf)+2),",",".") .. ": " .. color1 .. rule.text)
- if rule.punishment then
- whisper(name,string.gsub(string.gsub(rule.punishment,"Наказание:",color2 .. "Наказание:" .. color1),"За нарушение правил:",color2 .. "За нарушение правил:" .. color2))
- end
- log(3,name .. ": " .. msg0)
- else
- whisper(name,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 (капс)")
- persikAnswer(1,name)
- log(2,"(3.1 caps)" .. name .. ": " .. msg)
- else
- say(color1 .. name .. ", ты же модератор, не капси :*")
- end
- end
- end
- end
- function processSymbolFlood(msg,name)
- local len1 = unicode.len(msg)
- if len1 >= 12 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 (флуд символами)")
- persikAnswer(3,name)
- log(2,"3.1 (symbol flood)" .. name .. ": " .. msg)
- else
- say(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 (частая реклама)")
- persikAnswer(4,name)
- messages[name].previous = nil
- log(2,"(3.6: x" .. c.flood_identical_trade_messages_trigger .." in a row)" .. name .. ": " .. msg0,word)
- else
- say(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 (флуд)")
- persikAnswer(3,name)
- messages[name].previous = nil
- log(2,"(3.1: x" .. c.flood_normal_messages_trigger ..")" .. name .. ": " .. msg0,word)
- else
- say(color1 .. name .. ", ты же модератор, не флуди :*")
- end
- elseif isTrade and messages[name].anyTradeTimers[1] ~= 0 and (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 (частая реклама+)")
- persikAnswer(4,name)
- 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(color1 .. name .. ", ты же модератор, не флуди :*")
- end
- end
- end
- function getVoteCurrentGlobalCooldown(command)
- if votes[command] then
- if votes[command].lastActivated == 0 then
- return 0
- else
- local cd = (votes[command].lastActivated + votes[command].StaticGlobalCooldown) - computer.uptime()
- if cd <= 0 then
- return 0
- elseif cd > 0 then
- return cd
- end
- 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]
- if last then
- local cd = (last + votes[command].StaticPersonalCooldown) - computer.uptime()
- if cd <= 0 then
- return 0
- elseif cd > 0 then
- return cd
- end
- else
- return 0
- 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(3,name .. ": " .. msg0)
- activeVote = msg
- votes[msg].lastActivated = currentTime
- votes[msg].lastActivatedByPlayer[name] = currentTime
- activeVoteTimerId = event.timer(votes[msg].duration,pushEndvoteSignal,1)
- currentVoteResults.yes = currentVoteResults.yes+1
- hasUserVoted[name] = true
- say(color1 .. "Игрок ".. color2 .. name .. color1 .. " начал голосование за " .. votes[msg].text)
- say(color1 .. "Введите " .. color2 .. c.command_yes .. color1 .. " или " .. color2 .. c.command_no .. color1 .. " в локальный чат. Голосование длится " .. color2 .. votes[msg].duration .. color1 .. " секунд")
- else
- local answer = color1 .. "твой личный кулдаун на это голосование еще не истек. Осталось " .. color2 .. math.floor(getVoteCurrentPersonalCooldown(msg,name)) .. color1 .. " секунд"
- whisper(name,answer)
- end
- else
- local answer = color1 .. "глобальный кулдаун на это голосование еще не истек. Осталось " .. color2 .. math.floor(getVoteCurrentGlobalCooldown(msg)) .. color1 .. " секунд"
- whisper(name,answer)
- end
- else
- local answer = color1 .. votes[msg].denyMsg
- whisper(name,answer)
- end
- else
- local answer = 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,color1 .. "ты проголосовал §2\"за\"")
- elseif msg == c.command_no then
- currentVoteResults.no = currentVoteResults.no+1
- whisper(name,color1 .. "ты проголосовал §4\"против\"")
- end
- hasUserVoted[name] = true
- end
- else
- whisper(name,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(3,name .. ": " .. msg)
- local _,report = chat.say("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 = color1 .. "До рестарта: "
- if hoursleft ~= 0 then
- answer = answer .. color2 .. hoursleft .. color1 .. " час(а) "
- end
- local answer = answer .. color2 .. minleft .. color1 .. " минут " .. color2 .. secleft .. color1 .. " секунд"
- if fakeTPS then
- tps = math.random(18,19)
- if tps == 18 then
- tps = tostring(tps) .. "." .. tostring(math.random(7,9))
- else
- tps = tostring(tps) .. "." .. tostring(math.random(0,9))
- end
- end
- whisper(name,color1 .. "TPS: " .. color2 .. tps)
- whisper(name,answer)
- serverCommandCooldowns[name] = computer.uptime() + c.server_command_personal_cooldown
- end
- else
- whisper(name,color1 .. "Времени до повторного использования этой команды: " .. color2 .. leftt .. color1 .. " секунд(ы)")
- end
- end
- end
- function processSeen(msg,name)
- if string.find(msg,c.command_seen) == 1 then
- log(3,name .. ": " .. msg)
- local can, dur = canPlayerUseSeenCommand(name)
- if can or (masters[name] and masters[name].canSkipSeenCommandCooldown) then
- local target = string.sub(msg,unicode.len(c.command_seen)+2)
- if target == "" then
- whisper(name,color1 .. "не указано имя")
- return true
- elseif masters[getIndex(masters,target)] and masters[getIndex(masters,target)].hiddenFromSeenCommand then
- whisper(name,color1 .. "ты не можешь использовать эту команду на " .. color2 .. getIndex(masters,target))
- return true
- end
- local _,str = chat.say("seen " .. target)
- local status = ""
- if string.find(str,"Ошибка") then
- whisper(name,color1 .. "игрок " .. color2 .. target .. color1 .. " не найден")
- return true
- end
- seenCommandCooldowns[name] = computer.uptime() + c.cooldown_seen_command
- local month = string.match(str,"(%d+)%Dмес") or 0
- local day = string.match(str,"(%d+)%Dдне") or 0
- local hour = string.match(str,"(%d+)%Dчас") or 0
- local min = string.match(str,"(%d+)%Dмину") or 0
- local sec = string.match(str,"(%d+)%Dсеку") or 0
- if day == 0 then
- day = string.match(str,"(%d+)%Dден") or 0
- end
- if string.find(str,"онлайн") then
- status = " §2онлайн "
- elseif string.find(str,"оффлайн") then
- status = " §4оффлайн "
- end
- local targetname = string.match(str,"Игрок.+%s(.+)%s.+лайн") or "null"
- if string.find(targetname,"§") == 1 then
- targetname = string.sub(targetname,4)
- end
- local answer = color1 .. "игрок " .. color2 .. targetname .. status .. color1
- if month ~= 0 then
- answer = answer .. color2 .. month .. color1 .. " месяцев, "
- end
- if day ~= 0 then
- answer = answer .. color2 .. day .. color1 .. " дней, "
- end
- if day ~= 0 or hour ~= 0 then
- answer = answer .. color2 .. hour .. color1 .. " часов, "
- end
- if day ~= 0 or hour ~= 0 or min ~= 0 then
- answer = answer .. color2 .. min .. color1 .. " минут, "
- end
- if day ~= 0 or hour ~= 0 or min ~= 0 then
- if sec ~= 0 then
- answer = answer .. color2 .. sec .. color1 .. " секунд, "
- end
- else
- answer = answer .. color2 .. sec .. color1 .. " секунд, "
- end
- answer = answer:sub(0,-3)
- whisper(name,answer)
- else
- whisper(name,color1 .. "ты сможешь повторно использовать эту команду через " .. color2 .. dur .. color1 .. " секунд")
- end
- end
- end
- function processColors(msg,name)
- if msg == c.command_colors then
- local answer = color2 .. "цветовые коды чата:\n§00 - черный \n§11 - темно-синий \n§22 - зеленый \n§33 - темный аквамарин \n§44 - темно-красный \n§55 - фиолетовый \n§66 - оранжевый \n§77 - серый \n§88 - темно-серый \n§99 - синий \n§aa - салатовый§r \n§bb - аквамарин \n§cc - красный \n§dd - розовый \n§ee - желтый \n§ff - белый \n§r§ll - жирный \n§r§mm - зачеркнутый \n§r§nn - подчеркнутый \n§r§oo - курсив \n§rr - сброс форматирования"
- whisper(name,answer)
- log(3,name .. ": " .. msg)
- end
- end
- function saveStateOf(tablename,table,mode,silentMode) -- mode 1 для обычного сохранения, 2 для пересчитывания computer.uptime()
- local currentTime = computer.uptime()
- local f,err = io.open("__" .. tablename,"w")
- if err then
- print(err)
- sayLocal(color1 .. tablename .. "§c не сохранен ")
- return true
- elseif mode == 1 then
- f:write(serialization.serialize(table))
- if not silentMode then
- sayLocal(color1 .. tablename .. "§2 сохранен ")
- end
- f:close()
- elseif mode == 2 then
- local newtable = {}
- for k,v in pairs(table) do
- local newtime = math.floor(v - currentTime)
- if newtime > 0 then
- newtable[k] = newtime
- end
- end
- f:write(serialization.serialize(newtable))
- if not silentMode then
- sayLocal(color1 .. tablename .. "§2 сохранен ")
- end
- f:close()
- end
- end
- function saveAllStates()
- sayLocal(color2 .. "Подготовка к рестарту:")
- saveStateOf("history",history,1)
- --saveStateOf("messages",messages,1)
- saveStateOf("mutes",mutes,2)
- saveStateOf("warns",warns,2)
- end
- function reboot()
- saveAllStates()
- sayLocal(color2 .. "Скачивание обновления . . .")
- loadfile("/bin/wget.lua")("-f",c.download_main,"/home/MAIN")
- --shell.execute("wget -f " .. c.download_main .. "/home/MAIN")
- sayLocal(color2 .. "Обновление завершено, рестарт")
- computer.shutdown(1)
- --os.exit()
- end
- function reboot2()
- sayLocal(color2 .. "Обновление списка вопросов . . .")
- loadfile("/bin/wget.lua")("-f",c.download_q,"/home/_q")
- sayLocal(color2 .. "Обновление списка правил . . .")
- loadfile("/bin/wget.lua")("-f",c.download_rules,"/home/_rules")
- sayLocal(color2 .. "Обновление конфига . . .")
- loadfile("/bin/wget.lua")("-f",c.download_config,"/home/_config")
- saveAllStates()
- computer.shutdown(1)
- end
- function reboot3()
- sayLocal(color2 .. "Скачивание обновления . . .")
- loadfile("/bin/wget.lua")("-f",c.download_main,"/home/MAIN")
- sayLocal(color2 .. "Обновление списка вопросов . . .")
- loadfile("/bin/wget.lua")("-f",c.download_q,"/home/_q")
- sayLocal(color2 .. "Обновление списка правил . . .")
- loadfile("/bin/wget.lua")("-f",c.download_rules,"/home/_rules")
- sayLocal(color2 .. "Обновление конфига . . .")
- loadfile("/bin/wget.lua")("-f",c.download_config,"/home/_config")
- saveAllStates()
- computer.shutdown(1)
- end
- function fixAutorun()
- if fs.exists("/ShyvanaChatBotInstalled") == false then
- local f,err = io.open("/home/.shrc","a")
- f:write("\n/home/MAIN")
- f:close()
- local ff,err = io.open("/ShyvanaChatBotInstalled","w")
- ff:write("true")
- ff:close()
- end
- end
- function loadConfig(link)
- if link and link ~= "" then
- local a,b = loadfile("/bin/wget.lua")("-f",link,"/home/_config")
- if a == true then
- sayLocal(color2 .. "loadconfig: ok")
- reboot()
- else
- sayLocal(color2 .. "loadconfig: error " .. tostring(b))
- end
- else
- sayLocal(color2 .. "loadconfig error no link")
- end
- end
- function stop()
- local function saveStateOf2(tablename,table,mode) -- порезанная savestateoff только для истории
- local f,err = io.open("__" .. tablename,"w")
- if err then
- print(err)
- sayLocal(color1 .. tablename .. "§c не сохранен ")
- return true
- elseif mode == 1 then
- f:write(serialization.serialize(table))
- sayLocal(color1 .. tablename .. "§2 сохранен ")
- f:close()
- end
- end
- saveStateOf2("history",history,1)
- os.exit()
- end
- function randomPersik()
- return persiki[math.random(1,#persiki)]
- end
- function persikAnswer(reason,name)
- local persik = randomPersik()
- local tab = {
- [1] = {
- "не капси, " .. persik .. " :*",
- "отпусти шифт, " .. persik .. " :(",
- },
- [2] = {
- "не ругайся, " .. persik .. " :*",
- "так некрасиво говорить, " .. persik .. " :(",
- "как неприлично, " .. persik .. " :(",
- },
- [3] = {
- "не флуди, " .. persik .. " :*",
- "не загрязняй чат, " .. persik .. ", пожалуйста :(",
- },
- [4] = {
- "не рекламируй так часто, " .. persik .. " :*",
- },
- [5] = {
- "на этот раз только предупреждение, " .. persik .. ". больше так не делай :*",
- }
- }
- say(color1 .. tab[reason][math.random(1,#tab[reason])])
- end
- function processHelloBye(msg0,name)
- if c.persiki then
- local msg = unicode.lower(msg0)
- local currentTime = computer.uptime()
- if string.find(msg,"всем") and not string.find(msg,"%Sвсем") then
- if greetingCooldown < currentTime or (masters[name] and masters[name].canSkipHelloByeCooldowns) then
- for _,word in pairs(helloWords) do
- if string.find(msg,word) then
- local name1 = randomPersik()
- local phrase = string.gsub(helloPhrases[math.random(1,#helloPhrases)],"persik",name1)
- greetingCooldown = currentTime + c.timeout_greeting
- say(color1 .. phrase)
- return true
- end
- end
- end
- if byeCooldown < currentTime or (masters[name] and masters[name].canSkipHelloByeCooldowns) then
- for _,word in pairs(byeWords) do
- if string.find(msg,word) then
- local name1 = randomPersik()
- local phrase = string.gsub(byePhrases[math.random(1,#byePhrases)],"persik",name1)
- byeCooldown = currentTime + c.timeout_bye
- say(color1 .. phrase)
- return true
- end
- end
- end
- end
- end
- end
- function getStats()
- function compareDuration(a,b)
- return a.duration > b.duration
- end
- local toDisplay = 10
- local answer = color2 .. "Топ нарушителей:\n"
- local t = {}
- for k,v in pairs(stats) do
- table.insert(t,{name = k, duration = v.duration,mutes = v.mutes, warns = v.warns})
- end
- table.sort(t,compareDuration)
- if #t >= 1 then
- for i = 1,math.min(#t,toDisplay) do
- answer = answer .. color1 .. tostring(i) .. ". " .. color2 .. t[i].name .. color1 .. " - в муте " .. color2 .. math.floor(t[i].duration/60) .. color1 .. " минут (" .. color2 .. t[i].mutes .. color1 .. " мутов, " .. color2 .. t[i].warns .. color1 .." варнов)\n"
- end
- else
- answer = color1 .. "еще никто не нарушал :("
- end
- return answer
- end
- function getPlayerStat(name0)
- local name = getIndex(mutes,name0)
- if stats[name] then
- return color1 .. "игрок " .. color2 .. name .. color1 .. ": всего в муте " .. color2 .. math.floor(stats[name].duration/60) .. color1 .. " секунд (" .. color2 .. stats[name].mutes .. color1 .. " мутов, " .. color2 .. stats[name].warns .. color1 .. " варнов)"
- else
- return color1 .. "игрок " .. color2 .. name0 .. color1 .. " еще не нарушал"
- 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 = color1 .. "Активное голосование: " .. color2 .. activeVote .. color1 .. ": §2" .. currentVoteResults.yes .. color1 .. "/§4" .. currentVoteResults.no .. color1 .. ". До окончания: " .. color2 .. math.floor(getCurrentVoteTimer()) .. color1 .. " секунд"
- else
- answer = color1 .. "нет активных голосований"
- end
- else
- answer = 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 = color2 .. tostring(a) .. color1 .. " : " .. color2 .. b .. color1 .. " секунд осталось"
- else
- answer = 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 string.find(msg,c.command_is_player_warned) == 1 then
- local username = string.sub(msg,string.len(c.command_is_player_warned)+2)
- local a,b = isPlayerWarned(username)
- if a then
- answer = color2 .. tostring(a) .. color1 .. " : " .. color2 .. b .. color1 .. " секунд осталось"
- else
- answer = color2 .. tostring(a)
- end
- elseif string.find(msg,c.command_unwarn) == 1 then
- if masters[name].canCancelIssuedMutes then
- local username = string.sub(msg,string.len(c.command_unwarn)+2)
- unwarn(username,name)
- else
- whisper(name,"у тебя нет доступа к " .. c.command_unwarn)
- 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,color1 .. "теперь тебя видно в " .. color2 .. c.command_mods)
- masters[name].undetectable = nil
- else
- whisper(name,color1 .. "теперь тебя не видно в " .. color2 .. c.command_mods)
- masters[name].undetectable = true
- end
- elseif msg == c.command_memory_used then
- answer = color1 .. "Использование памяти: " .. color2 .. math.floor((computer.totalMemory()-computer.freeMemory())/1024) .. color1 .. "/" .. 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)
- if speech ~= "" then
- speech = string.gsub(speech,"#love","§4❤" .. color1)
- say(color1 .. speech,true)
- end
- end
- elseif msg == c.command_reboot and masters[name].canReboot then
- log(2," *** RESTART *** ")
- reboot()
- elseif msg == c.command_reboot_2 and masters[name].canReboot then
- log(2," *** RESTART2 *** ")
- reboot2()
- elseif msg == c.command_reboot_3 and masters[name].canReboot then
- log(2," *** RESTART3 *** ")
- reboot3()
- elseif string.find(msg,c.command_load_config) == 1 and masters[name].canLoadConfig then
- local args = string.sub(msg,unicode.len(c.command_load_config)+2)
- loadConfig(args)
- elseif msg == c.command_stop and masters[name].canReboot then
- log(2," *** STOP *** ")
- stop()
- elseif msg == c.command_get_stats then
- answer = getStats(name)
- elseif string.find(msg,c.command_get_stats) == 1 then
- local username = string.sub(msg,string.len(c.command_get_stats)+2)
- answer = getPlayerStat(username)
- end
- if answer ~= "" then
- whisper(name,answer)
- end
- end
- end
- function endCurrentVote(arg,name) --arg 1 или 2, 1 чтоб закончить голосование само по себе (таймером), 2 для принудительного закрытия без результатов
- if arg == 1 then
- say(color1 .. "Голосование окончено: §2\"за\"" .. color1 .. ": " .. color2 .. currentVoteResults.yes .. color1 .. ", §4\"против\"" .. color1 .. ": " .. color2 .. currentVoteResults.no)
- if votes[activeVote].isEasy then
- if currentVoteResults.yes - currentVoteResults.no >= c.vote_easy_yes_to_pass then
- votes[activeVote].passFunction()
- say(color1 .. votes[activeVote].passMessage)
- else
- votes[activeVote].failFunction()
- say(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(color1 .. "Голосование остановлено игроком " .. color2 .. name)
- activeVote = nil
- currentVoteResults = {yes = 0, no = 0}
- hasUserVoted = {}
- else
- whisper(name,color1 .. "нет активных голосований")
- end
- end
- end
- function unmute(player0,name) -- player - тот, кто в муте, name - заказчик
- local a,b,player = isPlayerMuted(player0)
- if a then
- cmd("unmute " .. player)
- mutes[player] = nil
- whisper(name,"мут снят с " .. player .. " (оставалось " .. b .. " секунд)")
- say(color2 .. name .. color1 .. " отменил мут игрока " .. color2 .. player)
- elseif not player then
- whisper(name,color1 .. "игрок не указан")
- else
- whisper(name,color1 .. "игрок " .. color2 .. player .. color1 .. " не имеет актуальных мутов от бота или неправильно указано имя")
- end
- end
- function unwarn(player0,name)
- local a,b,player = isPlayerWarned(player0)
- if a then
- cmd("unwarn " .. player)
- warns[player] = nil
- say(color2 .. name .. color1 .. " отменил варн игрока " .. color2 .. player)
- elseif not player then
- whisper(name,color1 .. "игрок не указан")
- else
- whisper(name,color1 .. "игрок " .. color2 .. player0 .. 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 .. color2 .. command .. " " .. color1 .. "- " .. description .. "\n"
- end
- answer = color2 .. "Доступные команды (вводятся в локальный чат): \n"
- addCommand(c.command_inf,"информация по определенному пункту правил (напр. " .. color2 .. c.command_inf .. " 3.1" .. color1 .. ")")
- addCommand(c.command_mods,"список модераторов онлайн")
- if not serverCommandDisabled then
- addCommand(c.command_server,"узнать время до рестарта сервера и ТПС")
- end
- addCommand(c.command_seen .. " [имя]","узнать когда игрок заходил в игру последний раз")
- addCommand(c.command_colors,"посмотреть список цветовых кодов чата (доступны прем аккаунтам)")
- addCommand("-votesun","начать голосование за отключение дождя")
- addCommand("-voteday","начать голосование за установку времени на утро")
- addCommand(c.command_yes .. " / " .. c.command_no,"отдать голос в текущем голосовании")
- whisper(name,answer)
- log(3,name .. ": " .. msg)
- end
- end
- function processHelp2(msg,name)
- msg = unicode.lower(msg)
- if msg == c.command_help2 and masters[name] then
- local answer
- function addCommand(command,description)
- answer = answer .. color2 .. command .. " " .. color1 .. "- " .. description .. "\n"
- end
- answer = color2 .. "Доступные команды для администраторов бота: \n (работают только при наличии соответствующих прав в конфиге)\n"
- addCommand(c.command_votestats,"получить инфу о текущем голосовании")
- addCommand(c.command_votestop,"отменить текущее голосование")
- addCommand(c.command_is_player_muted .. " [имя]","проверить наличие текущих мутов от бота игроку")
- addCommand(c.command_unmute .. " [имя]","отменить выданный ботом мут (если отменить вручную, бот продолжит игнорировать игрока на время бывшего мута)")
- addCommand(c.command_is_player_warned .. " [имя]","проверить наличие текущих варнов от бота игроку")
- addCommand(c.command_unwarn .. " [имя]","отменить выданный ботом варн")
- addCommand(c.command_get_stats,"посмотреть статистику по мутам и варнам игроков")
- addCommand(c.command_get_stats .. " [имя]","посмотреть статистику мутов/варнов определенного игрока")
- addCommand(c.command_toggle_detect,"стать невидимым для команды " .. color2 .. c.command_mods)
- addCommand(c.command_memory_used,"инфа по оперативной памяти бота")
- addCommand(c.command_retranslate,"говорить от имени бота, #love = ❤")
- addCommand(c.command_reboot,"обновить код бота и перезапустить")
- addCommand(c.command_reboot_2,"обновить список вопросов, список правил, конфиг и перезапустить")
- addCommand(c.command_reboot_3,"обновить все (вопросы, правила, конфиг, код бота) и перезапустить")
- addCommand(c.command_stop,"сохранить только историю и остановить бота")
- addCommand(c.command_load_config .. " [ссылка]","скачать конфиг файл с указанной ПРЯМОЙ ссылки и перезапустить (использовать не нужно)")
- 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,true) or (masters[name] and masters[name].canNOTGetIgnoredByBot) then
- msg = string.sub(msg,2)
- processHelloBye(msg,name)
- processCaps(msg,name)
- processQuestions(msg,name)
- processCensoredWords(msg,name)
- processSymbolFlood(msg,name)
- processFlood(msg,name)
- --log(2,"[g]" .. 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)
- processSeen(msg,name)
- processColors(msg,name)
- processMasterCommand(msg,name)
- if not serverCommandDisabled then
- processServerCommand(msg,name)
- end
- end
- elseif evt == "endvote" then
- endCurrentVote(arg1,name)
- end
- end
- fixAutorun()
- drawMainFrame()
- --historyInitialize()
- historyDraw()
- while true do
- getEvent()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement