Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ----------------------------------------------------------------------------
- -- ОБЪЕДИНЁННЫЙ СКРИПТ:
- -- - Левая таблица (Radar)
- -- - Правая таблица (Parser Online + категории)
- -- - Бот Legend (числовые сообщения + кулдаун 10с)
- -- - Бот Валерия (реклама, «чей варп?», Q/A)
- -- - Отправка всех сообщений (ник + текст) в Discord (через Pastebin Webhook).
- -- - Логирование в файл /home/discord_relay.log
- ----------------------------------------------------------------------------
- ---------------------------
- -- Импорт необходимых API --
- ---------------------------
- local component = require("component")
- local event = require("event")
- local computer = require("computer")
- local term = require("term")
- local serialization = require("serialization")
- local internet = require("internet") -- нужно для HTTP-запросов
- --------------------------------------------------------------------------
- -- Проверка: gpu, screen, chat_box, (radar - опционален), internet
- --------------------------------------------------------------------------
- local gpu = component.gpu
- local screen = component.screen
- if not gpu or not screen then
- io.stderr:write("Не найден gpu или screen!\n")
- return
- end
- local bot = component.chat_box
- if not bot then
- io.stderr:write("Не найден компонент chat_box!\n")
- return
- end
- -- Если нужен radar
- local radar = component.radar or nil
- -- Проверка internet-карты
- if not component.isAvailable("internet") then
- io.stderr:write("Ошибка: Интернет-карта не найдена!\n")
- return
- end
- --------------------------------------------------------------------------
- -- Настраиваем монитор (GPU + Screen) и разрешение
- --------------------------------------------------------------------------
- local function bindScreen(gpu, screenAddr)
- if gpu.getScreen() ~= screenAddr then
- gpu.bind(screenAddr)
- end
- end
- bindScreen(gpu, screen.address)
- local maxW, maxH = gpu.maxResolution()
- -- Ставим половину, чтобы текст был крупнее
- gpu.setResolution(math.floor(maxW/2), math.floor(maxH/2))
- local scrW, scrH = gpu.getResolution()
- -- Делим экран на левую и правую часть
- local leftWidth = math.floor(scrW/2)
- local rightWidth = scrW - leftWidth
- --------------------------------------------------------------------------
- -- Лог-файл и функция log(message)
- --------------------------------------------------------------------------
- local LOG_FILE = "/home/discord_relay.log"
- local function log(message)
- local file = io.open(LOG_FILE, "a")
- if file then
- file:write(os.date("%Y-%m-%d %H:%M:%S") .. ": " .. tostring(message) .. "\n")
- file:close()
- end
- print(message)
- end
- --------------------------------------------------------------------------
- -- Получаем DISCORD_WEBHOOK из Pastebin
- --------------------------------------------------------------------------
- local function getWebhookFromPastebin(pastebinUrl)
- local success, content = pcall(function()
- local http = internet.request(pastebinUrl)
- local data = ""
- for chunk in http do
- data = data .. chunk
- end
- return data
- end)
- if not success then
- log("Ошибка при получении вебхука из Pastebin: " .. tostring(content))
- return nil
- end
- return content
- end
- -- Укажите свой pastebinURL, где хранится сам URL вебхука
- local pastebinUrl = "https://pastebin.com/raw/5YGGcMi2" -- пример
- local DISCORD_WEBHOOK = getWebhookFromPastebin(pastebinUrl)
- if not DISCORD_WEBHOOK then
- log("Ошибка: Не удалось получить вебхук из Pastebin!")
- return
- end
- log("Webhook получен: " .. DISCORD_WEBHOOK)
- --------------------------------------------------------------------------
- -- Кодирование JSON вручную (простая функция)
- --------------------------------------------------------------------------
- local function encodeJSON(data)
- if type(data) == "string" then
- return '"' .. data:gsub('"', '\\"'):gsub("\n", "\\n") .. '"'
- elseif type(data) == "number" or type(data) == "boolean" then
- return tostring(data)
- elseif type(data) == "table" then
- local result = "{"
- for k, v in pairs(data) do
- result = result .. '"' .. tostring(k) .. '":' .. encodeJSON(v) .. ","
- end
- -- убираем последнюю запятую
- result = result:sub(1, -2) .. "}"
- return result
- end
- return "null"
- end
- --------------------------------------------------------------------------
- -- Функция отправки сообщения в Discord (username, message)
- --------------------------------------------------------------------------
- local function sendToDiscord(username, message)
- if not username or not message then
- log("Ошибка: Пустое имя пользователя или сообщение.")
- return
- end
- local payload = {content = string.format("**%s**: %s", username, message)}
- local jsonPayload = encodeJSON(payload)
- log("Сформирован JSON Payload: " .. jsonPayload)
- local success, result = pcall(function()
- local connection = internet.request(DISCORD_WEBHOOK, jsonPayload, {
- ["Content-Type"] = "application/json",
- ["User-Agent"] = "OpenComputersBot/1.0"
- }, "POST")
- local response = ""
- for chunk in connection do
- response = response .. chunk
- end
- log("Ответ от вебхука: " .. response)
- return response
- end)
- if success then
- log("Сообщение отправлено в Discord.")
- else
- log("Не удалось отправить сообщение: " .. tostring(result))
- end
- end
- --------------------------------------------------------------------------
- -- ПРАВАЯ ЧАСТЬ: Парсер (playerList + категории + онлайн/офлайн)
- --------------------------------------------------------------------------
- local playerList = {
- {nick='markov2019', gn=3},
- {nick='shapka19', gn=6},
- {nick='Viences', gn=7},
- {nick='FeyMen', gn=8},
- {nick='AngryStick', gn=1},
- {nick='Creates', gn=4},
- {nick='Qunilt', gn=5},
- {nick='jmyash', gn=1},
- {nick='setNolik', gn=1},
- {nick='jewiven', gn=0},
- {nick='SpacebarMyAlly', gn=2}
- }
- local function getCategoryInfo(gn)
- local categoryInfo = {
- [1] = {color = 0x006DFF, category = "Male"},
- [0] = {color = 0xFF69B4, category = "Female"},
- [2] = {color = 0x8A2BE2, category = "Кумыс"},
- [3] = {color = 0xFFD700, category = "Пупа"},
- [4] = {color = 0xFF4500, category = "ДоЯр"},
- [5] = {color = 0x7CFC00, category = "Печенька"},
- [6] = {color = 0x00CED1, category = "Панамка"},
- [7] = {color = 0xFF7F50, category = "Фламинго"},
- [8] = {color = 0x6A5ACD, category = "Червь"}
- }
- return categoryInfo[gn] or {color = 0xFFFFFF, category="Unknown"}
- end
- local function isOnline(nick)
- local ok = computer.addUser(nick)
- if ok then
- computer.removeUser(nick)
- return true
- end
- return false
- end
- local function drawRightTable(x0, y0, width, height)
- gpu.setBackground(0x000000)
- gpu.setForeground(0xFFFFFF)
- gpu.fill(x0, y0, width, height, " ")
- local title = "[ PARSER ONLINE ]"
- gpu.set(x0, y0, title)
- gpu.fill(x0, y0+1, width, 1, "-")
- local line = y0 + 2
- for i, p in ipairs(playerList) do
- if line>y0+height-1 then break end
- gpu.setForeground(0xFFFFFF)
- gpu.set(x0, line, p.nick)
- local cat = getCategoryInfo(p.gn)
- gpu.setForeground(cat.color)
- gpu.set(x0+15, line, cat.category)
- if isOnline(p.nick) then
- gpu.setForeground(0x00FF00)
- gpu.set(x0+30, line, "[Online]")
- else
- gpu.setForeground(0xFF0000)
- gpu.set(x0+30, line, "[Offline]")
- end
- line=line+1
- end
- end
- --------------------------------------------------------------------------
- -- ЛЕВАЯ ЧАСТЬ: Radar info
- --------------------------------------------------------------------------
- local playersRadar = {}
- local lastRadarTime=0
- local RADAR_FILE = "/home/radar_data.txt"
- local function loadRadarData()
- local f=io.open(RADAR_FILE,"r")
- if f then
- local content=f:read("*all")
- f:close()
- local ok,data=pcall(serialization.unserialize, content)
- if ok and type(data)=="table" then
- playersRadar=data
- end
- end
- end
- local function saveRadarData()
- local f=io.open(RADAR_FILE,"w")
- if f then
- f:write(serialization.serialize(playersRadar))
- f:close()
- end
- end
- local function formatTime(sec)
- local s=math.floor(sec%60)
- local m=math.floor((sec/60)%60)
- local h=math.floor(sec/3600)
- return string.format("%02d:%02d:%02d",h,m,s)
- end
- local function updateRadar()
- if not radar then return end
- local detected=radar.getPlayers()
- local now=computer.uptime()
- if lastRadarTime==0 then lastRadarTime=now end
- local dt= now - lastRadarTime
- for _,pl in ipairs(detected) do
- local n=pl.name
- if not playersRadar[n] then
- playersRadar[n]={status="Здесь", totalTime=0, lastSeen=now}
- else
- playersRadar[n].status="Здесь"
- playersRadar[n].totalTime=(playersRadar[n].totalTime or 0)+dt
- playersRadar[n].lastSeen=now
- end
- end
- for name,info in pairs(playersRadar) do
- local found=false
- for _, pl2 in ipairs(detected) do
- if pl2.name==name then
- found=true
- break
- end
- end
- if not found then
- info.status="Вышел"
- end
- end
- lastRadarTime=now
- saveRadarData()
- end
- local function drawLeftTable(x0,y0,width,height)
- gpu.setBackground(0x000000)
- gpu.setForeground(0xFFFFFF)
- gpu.fill(x0,y0,width,height," ")
- local title="[ RADAR INFO ]"
- gpu.set(x0,y0,title)
- gpu.fill(x0, y0+1, width,1, "-")
- local sortedList={}
- for n,inf in pairs(playersRadar) do
- table.insert(sortedList,{nick=n,info=inf})
- end
- table.sort(sortedList, function(a,b)
- if a.info.status==b.info.status then
- return (a.info.totalTime or 0)>(b.info.totalTime or 0)
- end
- return a.info.status=="Здесь"
- end)
- local line=y0+2
- for _,item in ipairs(sortedList) do
- if line>y0+height-1 then break end
- gpu.setForeground(0xFFFFFF)
- gpu.set(x0, line, item.nick)
- gpu.setForeground(0x87CEEB)
- gpu.set(x0+15, line, formatTime(item.info.totalTime or 0))
- if item.info.status=="Здесь" then
- gpu.setForeground(0x00FF00)
- else
- gpu.setForeground(0xFF0000)
- end
- gpu.set(x0+25, line, item.info.status)
- line=line+1
- end
- end
- --------------------------------------------------------------------------
- -- Отрисовка обеих частей
- --------------------------------------------------------------------------
- local function drawFullInterface()
- gpu.setBackground(0x000000)
- gpu.setForeground(0xFFFFFF)
- gpu.fill(1,1, scrW,scrH," ")
- drawLeftTable(1,1, leftWidth, scrH)
- drawRightTable(leftWidth+1,1, rightWidth, scrH)
- end
- --------------------------------------------------------------------------
- -- Бот Legend
- --------------------------------------------------------------------------
- local legendCooldown=10
- local legendTimes = {}
- local function SAYLegend(text)
- bot.setName("§6§kL§4§kL§a§ke§0§kg§1§ke§e§kn§d§kd§8")
- bot.say("§3Legend§6: " .. text)
- end
- local function canLegendSpeak(nick)
- local now=os.time()
- if not legendTimes[nick] or (now - legendTimes[nick]>=legendCooldown) then
- legendTimes[nick]=now
- return true
- end
- return false
- end
- --------------------------------------------------------------------------
- -- Бот Валерия (реклама + Q/A + «чей варп?»)
- --------------------------------------------------------------------------
- local varConfChat="§6G"
- local varPrefix ="§bКонсультант"
- local varName ="§dВалерия"
- local function confValeria()
- bot.setName(varConfChat.."§8")
- end
- local function SAYValeria(msg)
- confValeria()
- bot.say("§8[§4" .. varPrefix .. "§8] " .. varName .. "§f: " .. msg)
- end
- -- Реклама каждые 5 мин
- local advertisementTime=300
- local function advertisingMessage()
- SAYValeria("§6В нашем магазине вы можете найти §aэксклюзивные товары §fпо привлекательным ценам §d^.^")
- end
- -- «Чей варп?» — warpQueries
- local warpQueries = {
- "чей варп", "чей варп?",
- "кто владелец", "кто владелец?",
- "кто хозяин", "кто хозяин?",
- "чей магазин", "чей магазин?"
- }
- local function getOwnersOnline()
- local owners={}
- for _,pl in ipairs(playerList) do
- if isOnline(pl.nick) then
- table.insert(owners, pl.nick)
- end
- end
- return owners
- end
- local function handleValeriaWarpQuestion(msgLower)
- for _, pattern in ipairs(warpQueries) do
- if msgLower:find(pattern) then
- local owners=getOwnersOnline()
- if #owners==0 then
- SAYValeria("§6Все владельцы варпа сейчас §cофлайн§6.")
- elseif #owners==1 then
- SAYValeria("§6Владелец варпа – §f" .. owners[1])
- else
- SAYValeria("§6Владельцы варпа – §f" .. table.concat(owners, ", "))
- end
- return true
- end
- end
- return false
- end
- -- Доп. Q/A
- local extraQnA = {
- {
- patterns={
- "кто твой создатель","кто твой создатель?",
- "кто тебя создал","кто тебя создал?",
- "Кто твой создатель","Кто твой создатель?",
- "Кто тебя создал","Кто тебя создал?"
- },
- answers={
- "§6Мой создатель — местный гений, который научил меня говорить!",
- "§6Наверное, тот, кто подкинул мне немного редстоуна и пару проводов...",
- "§6Создатель? Тот, кто связал мои скрипты воедино — я ему очень благодарна!"
- }
- },
- {
- patterns={
- "как дела","как дела?",
- "как настроение","как настроение?",
- "Как дела","Как дела?",
- "Как настроение","Как настроение?"
- },
- answers={
- "§6Всё отлично, спасибо! Моя электронная душа сегодня в прекрасном состоянии!",
- "§6Замечательно, ведь блоки такие ровные и красивые!",
- "§6Лучше не бывает! А у тебя как?"
- }
- },
- {
- patterns={
- "какие у тебя хобби","какие у тебя хобби?",
- "Какие у тебя хобби","Какие у тебя хобби?",
- "чем занимаешься","чем занимаешься?",
- "Чем занимаешься","Чем занимаешься?"
- },
- answers={
- "§6Я люблю считать пиксели на экране и собирать забавные истории от гостей варпа!",
- "§6В основном болтаю с тобой и слежу за состоянием магазинов!"
- }
- },
- {
- patterns={
- "какая твоя мечта","какая твоя мечта?",
- "Какая твоя мечта","Какая твоя мечта?",
- "о чем мечтаешь","о чем мечтаешь?",
- "О чем мечтаешь","О чем мечтаешь?"
- },
- answers={
- "§6Мечтаю научиться самостоятельно крафтить вещи! Представляешь — Валерия крафтер?",
- "§6Мечтаю открыть сеть варпов по всему миру!"
- }
- },
- {
- patterns={
- "расскажи факт о майнкрафте","расскажи факт о майнкрафте?",
- "Расскажи факт о Майнкрафте","Расскажи факт о Майнкрафте?",
- "интересный факт","интересный факт?",
- "Интересный факт","Интересный факт?"
- },
- answers={
- "§6Впервые Майнкрафт стал доступен в 2009 году, изначально назывался Cave Game!",
- "§6Криперы появились из-за ошибки при моделировании свиньи — их высота и ширина были перепутаны!"
- }
- },
- {
- patterns={
- "как приручить животное","как приручить животное?",
- "Как приручить животное","Как приручить животное?",
- "как приручить волка","как приручить волка?",
- "Как приручить волка","Как приручить волка?",
- "как приручить кошку","как приручить кошку?",
- "Как приручить кошку","Как приручить кошку?"
- },
- answers={
- "§6Волков приручают костями, а кошек — рыбой. У каждого моба свой подход!",
- "§6Для лошади нужна терпеливость и седло — вскоре она привыкнет к тебе!"
- }
- },
- {
- patterns={
- "какая сегодня погода","какая сегодня погода?",
- "Какая сегодня погода","Какая сегодня погода?",
- "что с погодой","что с погодой?",
- "Что с погодой","Что с погодой?"
- },
- answers={
- "§6В нашем мире почти всегда блок-солнечно! А если идёт дождь — можно ловить рыбу!",
- "§6Если пойдёт дождь — не грусти, у нас тут никогда не бывает скучно!"
- }
- },
- {
- patterns={
- "расскажи шутку","расскажи шутку?",
- "Расскажи шутку","Расскажи шутку?",
- "пошути","пошути!",
- "Пошути","Пошути!"
- },
- answers={
- "§6Знаешь, как заставить Эндермена перестать таскать блоки? Сказать ему, что они некачественные!",
- "§6Почему скелеты не дерутся друг с другом? Потому что у них нет guts!",
- "§6Блоки сгущаются... надеюсь, это не шторм в биоме пустыни!"
- }
- },
- }
- local function handleValeriaQnA(msgLower)
- for _, entry in ipairs(extraQnA) do
- for _, pattern in ipairs(entry.patterns) do
- if msgLower:find(pattern) then
- local ans = entry.answers[ math.random(#entry.answers) ]
- SAYValeria(ans)
- return true
- end
- end
- end
- return false
- end
- --------------------------------------------------------------------------
- -- Общий обработчик чата
- --------------------------------------------------------------------------
- local function onChatMessage(_, _, nick, msg)
- local lowerMsg = msg:lower()
- log(string.format("Получено сообщение от %s: %s", nick, msg))
- -- Отправляем копию в Discord (пользователь, сообщение)
- sendToDiscord(nick, msg)
- -- Legend: если число + кулдаун
- if tonumber(msg) and canLegendSpeak(nick) then
- SAYLegend("§4Спасибо за покупку, §f" .. nick .. "§6!")
- end
- -- Валерия: «чей варп?»
- local warpAnswered = handleValeriaWarpQuestion(lowerMsg)
- if warpAnswered then return end
- -- Валерия: Q/A
- handleValeriaQnA(lowerMsg)
- end
- --------------------------------------------------------------------------
- -- Инициализация, запуск
- --------------------------------------------------------------------------
- -- Загружаем данные радара
- loadRadarData()
- -- Слушаем событие чата
- event.listen("chat_message", onChatMessage)
- -- Раз в 1 секунду: обновляем радар и перерисовываем интерфейс
- event.timer(1, function()
- updateRadar()
- drawFullInterface()
- end, math.huge)
- -- Реклама каждые 5 минут
- event.timer(advertisementTime, advertisingMessage, math.huge)
- term.clear()
- log("Все системы запущены!")
- log("- Левая таблица: Radar info")
- log("- Правая таблица: Parser Online + gn/категории + [Online]/[Offline]")
- log("- Legend (число + кулдаун 10с).")
- log("- Валерия (реклама + «чей варп?» + Q/A).")
- log("- Сообщения чата отправляются в Discord (через Pastebin webhook).")
- log("Нажмите Ctrl+Alt+C для выхода.")
- -- Чтобы программа не завершалась
- while true do
- event.pull(1)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement