Advertisement
FeyMen

SpamBot+buyBot\/2.0

Jan 4th, 2025 (edited)
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 21.66 KB | None | 0 0
  1. ----------------------------------------------------------------------------
  2. -- ОБЪЕДИНЁННЫЙ СКРИПТ:
  3. --   - Левая таблица (Radar)
  4. --   - Правая таблица (Parser Online + категории)
  5. --   - Бот Legend (числовые сообщения + кулдаун 10с)
  6. --   - Бот Валерия (реклама, «чей варп?», Q/A)
  7. --   - Отправка всех сообщений (ник + текст) в Discord (через Pastebin Webhook).
  8. --   - Логирование в файл /home/discord_relay.log
  9. ----------------------------------------------------------------------------
  10.  
  11. ---------------------------
  12. -- Импорт необходимых API --
  13. ---------------------------
  14. local component     = require("component")
  15. local event         = require("event")
  16. local computer      = require("computer")
  17. local term          = require("term")
  18. local serialization = require("serialization")
  19. local internet      = require("internet")   -- нужно для HTTP-запросов
  20.  
  21. --------------------------------------------------------------------------
  22. -- Проверка: gpu, screen, chat_box, (radar - опционален), internet
  23. --------------------------------------------------------------------------
  24. local gpu = component.gpu
  25. local screen = component.screen
  26. if not gpu or not screen then
  27.   io.stderr:write("Не найден gpu или screen!\n")
  28.   return
  29. end
  30.  
  31. local bot = component.chat_box
  32. if not bot then
  33.   io.stderr:write("Не найден компонент chat_box!\n")
  34.   return
  35. end
  36.  
  37. -- Если нужен radar
  38. local radar = component.radar or nil
  39.  
  40. -- Проверка internet-карты
  41. if not component.isAvailable("internet") then
  42.   io.stderr:write("Ошибка: Интернет-карта не найдена!\n")
  43.   return
  44. end
  45.  
  46. --------------------------------------------------------------------------
  47. -- Настраиваем монитор (GPU + Screen) и разрешение
  48. --------------------------------------------------------------------------
  49. local function bindScreen(gpu, screenAddr)
  50.   if gpu.getScreen() ~= screenAddr then
  51.     gpu.bind(screenAddr)
  52.   end
  53. end
  54.  
  55. bindScreen(gpu, screen.address)
  56. local maxW, maxH = gpu.maxResolution()
  57. -- Ставим половину, чтобы текст был крупнее
  58. gpu.setResolution(math.floor(maxW/2), math.floor(maxH/2))
  59.  
  60. local scrW, scrH = gpu.getResolution()
  61. -- Делим экран на левую и правую часть
  62. local leftWidth  = math.floor(scrW/2)
  63. local rightWidth = scrW - leftWidth
  64.  
  65. --------------------------------------------------------------------------
  66. -- Лог-файл и функция log(message)
  67. --------------------------------------------------------------------------
  68. local LOG_FILE = "/home/discord_relay.log"
  69. local function log(message)
  70.   local file = io.open(LOG_FILE, "a")
  71.   if file then
  72.     file:write(os.date("%Y-%m-%d %H:%M:%S") .. ": " .. tostring(message) .. "\n")
  73.     file:close()
  74.   end
  75.   print(message)
  76. end
  77.  
  78. --------------------------------------------------------------------------
  79. -- Получаем DISCORD_WEBHOOK из Pastebin
  80. --------------------------------------------------------------------------
  81. local function getWebhookFromPastebin(pastebinUrl)
  82.   local success, content = pcall(function()
  83.     local http = internet.request(pastebinUrl)
  84.     local data = ""
  85.     for chunk in http do
  86.       data = data .. chunk
  87.     end
  88.     return data
  89.   end)
  90.  
  91.   if not success then
  92.     log("Ошибка при получении вебхука из Pastebin: " .. tostring(content))
  93.     return nil
  94.   end
  95.  
  96.   return content
  97. end
  98.  
  99. -- Укажите свой pastebinURL, где хранится сам URL вебхука
  100. local pastebinUrl = "https://pastebin.com/raw/5YGGcMi2"  -- пример
  101. local DISCORD_WEBHOOK = getWebhookFromPastebin(pastebinUrl)
  102. if not DISCORD_WEBHOOK then
  103.   log("Ошибка: Не удалось получить вебхук из Pastebin!")
  104.   return
  105. end
  106. log("Webhook получен: " .. DISCORD_WEBHOOK)
  107.  
  108. --------------------------------------------------------------------------
  109. -- Кодирование JSON вручную (простая функция)
  110. --------------------------------------------------------------------------
  111. local function encodeJSON(data)
  112.   if type(data) == "string" then
  113.     return '"' .. data:gsub('"', '\\"'):gsub("\n", "\\n") .. '"'
  114.   elseif type(data) == "number" or type(data) == "boolean" then
  115.     return tostring(data)
  116.   elseif type(data) == "table" then
  117.     local result = "{"
  118.     for k, v in pairs(data) do
  119.       result = result .. '"' .. tostring(k) .. '":' .. encodeJSON(v) .. ","
  120.     end
  121.     -- убираем последнюю запятую
  122.     result = result:sub(1, -2) .. "}"
  123.     return result
  124.   end
  125.   return "null"
  126. end
  127.  
  128. --------------------------------------------------------------------------
  129. -- Функция отправки сообщения в Discord (username, message)
  130. --------------------------------------------------------------------------
  131. local function sendToDiscord(username, message)
  132.   if not username or not message then
  133.     log("Ошибка: Пустое имя пользователя или сообщение.")
  134.     return
  135.   end
  136.  
  137.   local payload = {content = string.format("**%s**: %s", username, message)}
  138.   local jsonPayload = encodeJSON(payload)
  139.   log("Сформирован JSON Payload: " .. jsonPayload)
  140.  
  141.   local success, result = pcall(function()
  142.     local connection = internet.request(DISCORD_WEBHOOK, jsonPayload, {
  143.       ["Content-Type"] = "application/json",
  144.       ["User-Agent"]   = "OpenComputersBot/1.0"
  145.     }, "POST")
  146.  
  147.     local response = ""
  148.     for chunk in connection do
  149.       response = response .. chunk
  150.     end
  151.  
  152.     log("Ответ от вебхука: " .. response)
  153.     return response
  154.   end)
  155.  
  156.   if success then
  157.     log("Сообщение отправлено в Discord.")
  158.   else
  159.     log("Не удалось отправить сообщение: " .. tostring(result))
  160.   end
  161. end
  162.  
  163. --------------------------------------------------------------------------
  164. -- ПРАВАЯ ЧАСТЬ: Парсер (playerList + категории + онлайн/офлайн)
  165. --------------------------------------------------------------------------
  166. local playerList = {
  167.   {nick='markov2019',   gn=3},
  168.   {nick='shapka19',     gn=6},
  169.   {nick='Viences',      gn=7},
  170.   {nick='FeyMen',       gn=8},
  171.   {nick='AngryStick',   gn=1},
  172.   {nick='Creates',      gn=4},
  173.   {nick='Qunilt',       gn=5},
  174.   {nick='jmyash',       gn=1},
  175.   {nick='setNolik',     gn=1},
  176.   {nick='jewiven',      gn=0},
  177.   {nick='SpacebarMyAlly', gn=2}
  178. }
  179.  
  180. local function getCategoryInfo(gn)
  181.   local categoryInfo = {
  182.     [1] = {color = 0x006DFF, category = "Male"},
  183.     [0] = {color = 0xFF69B4, category = "Female"},
  184.     [2] = {color = 0x8A2BE2, category = "Кумыс"},
  185.     [3] = {color = 0xFFD700, category = "Пупа"},
  186.     [4] = {color = 0xFF4500, category = "ДоЯр"},
  187.     [5] = {color = 0x7CFC00, category = "Печенька"},
  188.     [6] = {color = 0x00CED1, category = "Панамка"},
  189.     [7] = {color = 0xFF7F50, category = "Фламинго"},
  190.     [8] = {color = 0x6A5ACD, category = "Червь"}
  191.   }
  192.   return categoryInfo[gn] or {color = 0xFFFFFF, category="Unknown"}
  193. end
  194.  
  195. local function isOnline(nick)
  196.   local ok = computer.addUser(nick)
  197.   if ok then
  198.     computer.removeUser(nick)
  199.     return true
  200.   end
  201.   return false
  202. end
  203.  
  204. local function drawRightTable(x0, y0, width, height)
  205.   gpu.setBackground(0x000000)
  206.   gpu.setForeground(0xFFFFFF)
  207.   gpu.fill(x0, y0, width, height, " ")
  208.  
  209.   local title = "[ PARSER ONLINE ]"
  210.   gpu.set(x0, y0, title)
  211.   gpu.fill(x0, y0+1, width, 1, "-")
  212.  
  213.   local line = y0 + 2
  214.   for i, p in ipairs(playerList) do
  215.     if line>y0+height-1 then break end
  216.     gpu.setForeground(0xFFFFFF)
  217.     gpu.set(x0, line, p.nick)
  218.  
  219.     local cat = getCategoryInfo(p.gn)
  220.     gpu.setForeground(cat.color)
  221.     gpu.set(x0+15, line, cat.category)
  222.  
  223.     if isOnline(p.nick) then
  224.       gpu.setForeground(0x00FF00)
  225.       gpu.set(x0+30, line, "[Online]")
  226.     else
  227.       gpu.setForeground(0xFF0000)
  228.       gpu.set(x0+30, line, "[Offline]")
  229.     end
  230.     line=line+1
  231.   end
  232. end
  233.  
  234. --------------------------------------------------------------------------
  235. -- ЛЕВАЯ ЧАСТЬ: Radar info
  236. --------------------------------------------------------------------------
  237. local playersRadar = {}
  238. local lastRadarTime=0
  239. local RADAR_FILE   = "/home/radar_data.txt"
  240.  
  241. local function loadRadarData()
  242.   local f=io.open(RADAR_FILE,"r")
  243.   if f then
  244.     local content=f:read("*all")
  245.     f:close()
  246.     local ok,data=pcall(serialization.unserialize, content)
  247.     if ok and type(data)=="table" then
  248.       playersRadar=data
  249.     end
  250.   end
  251. end
  252. local function saveRadarData()
  253.   local f=io.open(RADAR_FILE,"w")
  254.   if f then
  255.     f:write(serialization.serialize(playersRadar))
  256.     f:close()
  257.   end
  258. end
  259.  
  260. local function formatTime(sec)
  261.   local s=math.floor(sec%60)
  262.   local m=math.floor((sec/60)%60)
  263.   local h=math.floor(sec/3600)
  264.   return string.format("%02d:%02d:%02d",h,m,s)
  265. end
  266.  
  267. local function updateRadar()
  268.   if not radar then return end
  269.   local detected=radar.getPlayers()
  270.   local now=computer.uptime()
  271.   if lastRadarTime==0 then lastRadarTime=now end
  272.   local dt= now - lastRadarTime
  273.  
  274.   for _,pl in ipairs(detected) do
  275.     local n=pl.name
  276.     if not playersRadar[n] then
  277.       playersRadar[n]={status="Здесь", totalTime=0, lastSeen=now}
  278.     else
  279.       playersRadar[n].status="Здесь"
  280.       playersRadar[n].totalTime=(playersRadar[n].totalTime or 0)+dt
  281.       playersRadar[n].lastSeen=now
  282.     end
  283.   end
  284.  
  285.   for name,info in pairs(playersRadar) do
  286.     local found=false
  287.     for _, pl2 in ipairs(detected) do
  288.       if pl2.name==name then
  289.         found=true
  290.         break
  291.       end
  292.     end
  293.     if not found then
  294.       info.status="Вышел"
  295.     end
  296.   end
  297.  
  298.   lastRadarTime=now
  299.   saveRadarData()
  300. end
  301.  
  302. local function drawLeftTable(x0,y0,width,height)
  303.   gpu.setBackground(0x000000)
  304.   gpu.setForeground(0xFFFFFF)
  305.   gpu.fill(x0,y0,width,height," ")
  306.  
  307.   local title="[ RADAR INFO ]"
  308.   gpu.set(x0,y0,title)
  309.   gpu.fill(x0, y0+1, width,1, "-")
  310.  
  311.   local sortedList={}
  312.   for n,inf in pairs(playersRadar) do
  313.     table.insert(sortedList,{nick=n,info=inf})
  314.   end
  315.   table.sort(sortedList, function(a,b)
  316.     if a.info.status==b.info.status then
  317.       return (a.info.totalTime or 0)>(b.info.totalTime or 0)
  318.     end
  319.     return a.info.status=="Здесь"
  320.   end)
  321.  
  322.   local line=y0+2
  323.   for _,item in ipairs(sortedList) do
  324.     if line>y0+height-1 then break end
  325.     gpu.setForeground(0xFFFFFF)
  326.     gpu.set(x0, line, item.nick)
  327.  
  328.     gpu.setForeground(0x87CEEB)
  329.     gpu.set(x0+15, line, formatTime(item.info.totalTime or 0))
  330.  
  331.     if item.info.status=="Здесь" then
  332.       gpu.setForeground(0x00FF00)
  333.     else
  334.       gpu.setForeground(0xFF0000)
  335.     end
  336.     gpu.set(x0+25, line, item.info.status)
  337.     line=line+1
  338.   end
  339. end
  340.  
  341. --------------------------------------------------------------------------
  342. -- Отрисовка обеих частей
  343. --------------------------------------------------------------------------
  344. local function drawFullInterface()
  345.   gpu.setBackground(0x000000)
  346.   gpu.setForeground(0xFFFFFF)
  347.   gpu.fill(1,1, scrW,scrH," ")
  348.  
  349.   drawLeftTable(1,1, leftWidth, scrH)
  350.   drawRightTable(leftWidth+1,1, rightWidth, scrH)
  351. end
  352.  
  353. --------------------------------------------------------------------------
  354. -- Бот Legend
  355. --------------------------------------------------------------------------
  356. local legendCooldown=10
  357. local legendTimes   = {}
  358. local function SAYLegend(text)
  359.   bot.setName("§6§kL§4§kL§a§ke§0§kg§1§ke§e§kn§d§kd§8")
  360.   bot.say("§3Legend§6: " .. text)
  361. end
  362. local function canLegendSpeak(nick)
  363.   local now=os.time()
  364.   if not legendTimes[nick] or (now - legendTimes[nick]>=legendCooldown) then
  365.     legendTimes[nick]=now
  366.     return true
  367.   end
  368.   return false
  369. end
  370.  
  371. --------------------------------------------------------------------------
  372. -- Бот Валерия (реклама + Q/A + «чей варп?»)
  373. --------------------------------------------------------------------------
  374. local varConfChat="§6G"
  375. local varPrefix  ="§bКонсультант"
  376. local varName    ="§dВалерия"
  377.  
  378. local function confValeria()
  379.   bot.setName(varConfChat.."§8")
  380. end
  381. local function SAYValeria(msg)
  382.   confValeria()
  383.   bot.say("§8[§4" .. varPrefix .. "§8] " .. varName .. "§f: " .. msg)
  384. end
  385.  
  386. -- Реклама каждые 5 мин
  387. local advertisementTime=300
  388. local function advertisingMessage()
  389.   SAYValeria("§6В нашем магазине вы можете найти §aэксклюзивные товары §fпо привлекательным ценам §d^.^")
  390. end
  391.  
  392. -- «Чей варп?» — warpQueries
  393. local warpQueries = {
  394.   "чей варп", "чей варп?",
  395.   "кто владелец", "кто владелец?",
  396.   "кто хозяин",   "кто хозяин?",
  397.   "чей магазин",  "чей магазин?"
  398. }
  399. local function getOwnersOnline()
  400.   local owners={}
  401.   for _,pl in ipairs(playerList) do
  402.     if isOnline(pl.nick) then
  403.       table.insert(owners, pl.nick)
  404.     end
  405.   end
  406.   return owners
  407. end
  408.  
  409. local function handleValeriaWarpQuestion(msgLower)
  410.   for _, pattern in ipairs(warpQueries) do
  411.     if msgLower:find(pattern) then
  412.       local owners=getOwnersOnline()
  413.       if #owners==0 then
  414.         SAYValeria("§6Все владельцы варпа сейчас §cофлайн§6.")
  415.       elseif #owners==1 then
  416.         SAYValeria("§6Владелец варпа – §f" .. owners[1])
  417.       else
  418.         SAYValeria("§6Владельцы варпа – §f" .. table.concat(owners, ", "))
  419.       end
  420.       return true
  421.     end
  422.   end
  423.   return false
  424. end
  425.  
  426. -- Доп. Q/A
  427. local extraQnA = {
  428.   {
  429.     patterns={
  430.       "кто твой создатель","кто твой создатель?",
  431.       "кто тебя создал","кто тебя создал?",
  432.       "Кто твой создатель","Кто твой создатель?",
  433.       "Кто тебя создал","Кто тебя создал?"
  434.     },
  435.     answers={
  436.       "§6Мой создатель — местный гений, который научил меня говорить!",
  437.       "§6Наверное, тот, кто подкинул мне немного редстоуна и пару проводов...",
  438.       "§6Создатель? Тот, кто связал мои скрипты воедино — я ему очень благодарна!"
  439.     }
  440.   },
  441.   {
  442.     patterns={
  443.       "как дела","как дела?",
  444.       "как настроение","как настроение?",
  445.       "Как дела","Как дела?",
  446.       "Как настроение","Как настроение?"
  447.     },
  448.     answers={
  449.       "§6Всё отлично, спасибо! Моя электронная душа сегодня в прекрасном состоянии!",
  450.       "§6Замечательно, ведь блоки такие ровные и красивые!",
  451.       "§6Лучше не бывает! А у тебя как?"
  452.     }
  453.   },
  454.   {
  455.     patterns={
  456.       "какие у тебя хобби","какие у тебя хобби?",
  457.       "Какие у тебя хобби","Какие у тебя хобби?",
  458.       "чем занимаешься","чем занимаешься?",
  459.       "Чем занимаешься","Чем занимаешься?"
  460.     },
  461.     answers={
  462.       "§6Я люблю считать пиксели на экране и собирать забавные истории от гостей варпа!",
  463.       "§6В основном болтаю с тобой и слежу за состоянием магазинов!"
  464.     }
  465.   },
  466.   {
  467.     patterns={
  468.       "какая твоя мечта","какая твоя мечта?",
  469.       "Какая твоя мечта","Какая твоя мечта?",
  470.       "о чем мечтаешь","о чем мечтаешь?",
  471.       "О чем мечтаешь","О чем мечтаешь?"
  472.     },
  473.     answers={
  474.       "§6Мечтаю научиться самостоятельно крафтить вещи! Представляешь — Валерия крафтер?",
  475.       "§6Мечтаю открыть сеть варпов по всему миру!"
  476.     }
  477.   },
  478.   {
  479.     patterns={
  480.       "расскажи факт о майнкрафте","расскажи факт о майнкрафте?",
  481.       "Расскажи факт о Майнкрафте","Расскажи факт о Майнкрафте?",
  482.       "интересный факт","интересный факт?",
  483.       "Интересный факт","Интересный факт?"
  484.     },
  485.     answers={
  486.       "§6Впервые Майнкрафт стал доступен в 2009 году, изначально назывался Cave Game!",
  487.       "§6Криперы появились из-за ошибки при моделировании свиньи — их высота и ширина были перепутаны!"
  488.     }
  489.   },
  490.   {
  491.     patterns={
  492.       "как приручить животное","как приручить животное?",
  493.       "Как приручить животное","Как приручить животное?",
  494.       "как приручить волка","как приручить волка?",
  495.       "Как приручить волка","Как приручить волка?",
  496.       "как приручить кошку","как приручить кошку?",
  497.       "Как приручить кошку","Как приручить кошку?"
  498.     },
  499.     answers={
  500.       "§6Волков приручают костями, а кошек — рыбой. У каждого моба свой подход!",
  501.       "§6Для лошади нужна терпеливость и седло — вскоре она привыкнет к тебе!"
  502.     }
  503.   },
  504.   {
  505.     patterns={
  506.       "какая сегодня погода","какая сегодня погода?",
  507.       "Какая сегодня погода","Какая сегодня погода?",
  508.       "что с погодой","что с погодой?",
  509.       "Что с погодой","Что с погодой?"
  510.     },
  511.     answers={
  512.       "§6В нашем мире почти всегда блок-солнечно! А если идёт дождь — можно ловить рыбу!",
  513.       "§6Если пойдёт дождь — не грусти, у нас тут никогда не бывает скучно!"
  514.     }
  515.   },
  516.   {
  517.     patterns={
  518.       "расскажи шутку","расскажи шутку?",
  519.       "Расскажи шутку","Расскажи шутку?",
  520.       "пошути","пошути!",
  521.       "Пошути","Пошути!"
  522.     },
  523.     answers={
  524.       "§6Знаешь, как заставить Эндермена перестать таскать блоки? Сказать ему, что они некачественные!",
  525.       "§6Почему скелеты не дерутся друг с другом? Потому что у них нет guts!",
  526.       "§6Блоки сгущаются... надеюсь, это не шторм в биоме пустыни!"
  527.     }
  528.   },
  529. }
  530.  
  531. local function handleValeriaQnA(msgLower)
  532.   for _, entry in ipairs(extraQnA) do
  533.     for _, pattern in ipairs(entry.patterns) do
  534.       if msgLower:find(pattern) then
  535.         local ans = entry.answers[ math.random(#entry.answers) ]
  536.         SAYValeria(ans)
  537.         return true
  538.       end
  539.     end
  540.   end
  541.   return false
  542. end
  543.  
  544. --------------------------------------------------------------------------
  545. -- Общий обработчик чата
  546. --------------------------------------------------------------------------
  547. local function onChatMessage(_, _, nick, msg)
  548.   local lowerMsg = msg:lower()
  549.   log(string.format("Получено сообщение от %s: %s", nick, msg))
  550.  
  551.   -- Отправляем копию в Discord (пользователь, сообщение)
  552.   sendToDiscord(nick, msg)
  553.  
  554.   -- Legend: если число + кулдаун
  555.   if tonumber(msg) and canLegendSpeak(nick) then
  556.     SAYLegend("§4Спасибо за покупку, §f" .. nick .. "§6!")
  557.   end
  558.  
  559.   -- Валерия: «чей варп?»
  560.   local warpAnswered = handleValeriaWarpQuestion(lowerMsg)
  561.   if warpAnswered then return end
  562.  
  563.   -- Валерия: Q/A
  564.   handleValeriaQnA(lowerMsg)
  565. end
  566.  
  567. --------------------------------------------------------------------------
  568. -- Инициализация, запуск
  569. --------------------------------------------------------------------------
  570. -- Загружаем данные радара
  571. loadRadarData()
  572.  
  573. -- Слушаем событие чата
  574. event.listen("chat_message", onChatMessage)
  575.  
  576. -- Раз в 1 секунду: обновляем радар и перерисовываем интерфейс
  577. event.timer(1, function()
  578.   updateRadar()
  579.   drawFullInterface()
  580. end, math.huge)
  581.  
  582. -- Реклама каждые 5 минут
  583. event.timer(advertisementTime, advertisingMessage, math.huge)
  584.  
  585. term.clear()
  586. log("Все системы запущены!")
  587. log("- Левая таблица: Radar info")
  588. log("- Правая таблица: Parser Online + gn/категории + [Online]/[Offline]")
  589. log("- Legend (число + кулдаун 10с).")
  590. log("- Валерия (реклама + «чей варп?» + Q/A).")
  591. log("- Сообщения чата отправляются в Discord (через Pastebin webhook).")
  592. log("Нажмите Ctrl+Alt+C для выхода.")
  593.  
  594. -- Чтобы программа не завершалась
  595. while true do
  596.   event.pull(1)
  597. end
  598.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement