Advertisement
Guest User

Untitled

a guest
Mar 30th, 2016
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 32.16 KB | None | 0 0
  1.  
  2. ---------------------------------------------------- Библиотеки ----------------------------------------------------------------
  3.  
  4. local internet = require("internet")
  5. local json = require("json")
  6. local serialization = require("serialization")
  7. local event = require("event")
  8. local ecs = require("ECSAPI")
  9. local fs = require("filesystem")
  10. local buffer = require("doubleBuffering")
  11. local context = require("context")
  12. local image = require("image")
  13. local unicode = require("unicode")
  14. local component = require("component")
  15. local computer = require("computer")
  16.  
  17. ---------------------------------------------------- Константы ----------------------------------------------------------------
  18.  
  19. local VKAPIVersion = "5.50"
  20.  
  21. local colors = {
  22.     leftBar = 0x262626,
  23.     leftBarAlternative = 0x383838,
  24.     leftBarText = 0xFFFFFF,
  25.     leftBarSelection = 0x00A8FF,
  26.     leftBarSelectionText = 0xFFFFFF,
  27.  
  28.     scrollBar = 0xCCCCCC,
  29.     scrollBarPipe = 0x666666,
  30.  
  31.     mainZone = 0xFFFFFF,
  32.     senderCloudColor = 0x3392FF,
  33.     senderCloudTextColor = 0xFFFFFF,
  34.     yourCloudColor = 0x55BBFF,
  35.     yourCloudTextColor = 0xFFFFFF,
  36.     systemMessageColor = 0x555555,
  37.     dateTime = 0x777777,
  38.  
  39.     loginGUIBackground = 0x002440,
  40.  
  41.     topBar = 0x002440,
  42.     topBarText = 0xFFFFFF,
  43.  
  44.     statusBar = 0x262626,
  45.     statusBarText = 0xAAAAAA,
  46.  
  47.     audioPlayButton = 0x002440,
  48.     audioPlayButtonText = 0xFFFFFF,
  49.  
  50.     messageInputBarColor = 0xEEEEEE,
  51.     messageInputBarTextBackgroundColor = 0xFFFFFF,
  52.     messsageInputBarTextColor = 0x262626,
  53. }
  54.  
  55. local leftBarHeight = buffer.screen.height - 9
  56. local leftBarWidth = math.floor(buffer.screen.width * 0.17)
  57.  
  58. local topBarHeight = 3
  59.  
  60. local mainZoneWidth = buffer.screen.width - leftBarWidth
  61. local mainZoneHeight = buffer.screen.height - topBarHeight - 1
  62. local mainZoneX = leftBarWidth + 1
  63. local mainZoneY = topBarHeight + 1
  64.  
  65. local cloudWidth = math.floor(mainZoneWidth * 0.7)
  66.  
  67. -------------------------------------------------------------------------------------------------------------------------------
  68.  
  69. local VKLogoImagePath = "MineOS/Applications/VK.app/Resources/VKLogo.pic"
  70. -- local leftBarElements = {"Новости", "Друзья", "Сообщения", "Настройки", "Выход"}
  71. local leftBarElements = { "Сообщения", "Аудиозаписи", "Группы", "Выход" }
  72. local currentLeftBarElement = 1
  73. local personalInfo
  74. local access_token
  75. local whatIsOnScreen
  76.  
  77. local countOfDialogsToLoadFromServer = 10
  78. local countOfAudioToLoadFromServer = 10
  79. local countOfMessagesToLoadFromServer = 10
  80.  
  81. local dialogToShowFrom = 1
  82. local audioToShowFrom = 1
  83. local messageToShowFrom = 1
  84.  
  85. local dialogScrollSpeed = 5
  86. local audioScrollSpeed = 5
  87. local messagesScrollSpeed = 5
  88.  
  89. local currentMessagesPeerID, currentMessagesAvatarText, currentMessagesFullName
  90. local dialogPreviewTextLimit = mainZoneWidth - 15
  91.  
  92. ---------------------------------------------------- Веб-часть ----------------------------------------------------------------
  93.  
  94. --Объекты
  95. local obj = {}
  96. local function newObj(class, name, ...)
  97.     obj[class] = obj[class] or {}
  98.     obj[class][name] = {...}
  99. end
  100.  
  101. --Дебаг-функция на сохранение говна в файл, МАЛО ЛИ ЧО
  102. local function saveToFile(stro4ka)
  103.     local file = io.open("test.lua", "w")
  104.     file:write(stro4ka)
  105.     file:close()
  106. end
  107.  
  108. --Модифицированная функция интернет-запросов, стандартная фу-фу-фу, ошибка на ошибке и HTTP Response Error погоняет!
  109. --Заметка: переписать на компонетное API, в рот ебал автора либы. Хм, велосипеды?
  110. local function request(url)
  111.     local data = ""
  112.     --Выполняем запрос на подключение
  113.     local success, response = pcall(internet.request, url)
  114.     --Если все ок, то делаем чтение из response, иначе выдаем ошибку, че не так с подключением
  115.     --(скорее всего, ошибка будет связана с отстутствием инета или неверными URL, которые ТЫ, СУКА, лично и вбиваешь в код)
  116.     if success then
  117.         while true do
  118.             --Делаем запрос на чтение из response
  119.             local success, reason = pcall(response)
  120.             --Если все ок, то идем дальше, иначе кидаем ошибку
  121.             --(скорее всего, это будет серверная ошибка, неверный пасс там, 404, бла-бла)
  122.             if success then
  123.                 --Если конец response не достигнут, то записываем в data все, что пришло с сервака, иначе по съебкам!
  124.                 if reason then
  125.                     data = data .. reason
  126.                 else
  127.                     break
  128.                 end
  129.             else
  130.                 return false, reason
  131.             end
  132.         end
  133.        
  134.         --Если все охуенно, то возвращаем true и преобразованный JSON-ответ в таблицу Lua
  135.         return true, json:decode(data)
  136.     else
  137.         return false, response
  138.     end
  139. end
  140.  
  141. --Отправляем запрос на авторизацию по логину и паролю
  142. local function getLoginDataRequest(username, password)
  143.     local url = "https://oauth.vk.com/token?grant_type=password&client_id=3697615&client_secret=AlVXZFMUqyrnABp8ncuU&username=" .. username .. "&password=" .. password .. "&v=" .. VKAPIVersion
  144.     return request(url)
  145. end
  146.  
  147. --Запрос к методам VK API
  148. local function VKAPIRequest(method, ... )
  149.     local arguments = { ... }
  150.     local stringArguments = ""
  151.  
  152.     local url = "https://api.vk.com/method/" .. method .. "?" .. table.concat(arguments, "&") .. "&access_token=" .. access_token .. "&v=" .. VKAPIVersion
  153.  
  154.     return request(url)
  155. end
  156.  
  157. --Запрос на получение списка диалогов
  158. local function getDialogsRequest(fromDialog, count)
  159.     return VKAPIRequest("messages.getDialogs", "offset=" .. fromDialog, "count=" .. count, "preview_length=" .. dialogPreviewTextLimit)
  160. end
  161.  
  162. --Запрос на получение списка диалогов
  163. local function getMessagesRequest(peerID, fromMessage, count)
  164.     return VKAPIRequest("messages.getHistory", "offset=" .. fromMessage, "count=" .. count, "peer_id=" .. peerID)
  165. end
  166.  
  167. --Запрос на получение списка музычки
  168. local function getAudioRequest(id, fromAudio, count)
  169.     return VKAPIRequest("audio.get", "offset=" .. fromAudio, "count=" .. count, "owner_id=" .. id, "need_user=1")
  170. end
  171.  
  172. --Эта хуйня делает строку охуенной путем замены говна на конфетку
  173. local function optimizeStringForURLSending(code)
  174.   if code then
  175.     code = string.gsub(code, "([^%w ])", function (c)
  176.       return string.format("%%%02X", string.byte(c))
  177.     end)
  178.     code = string.gsub(code, " ", "+")
  179.   end
  180.   return code
  181. end
  182.  
  183. local function optimizeStringForWrongSymbols(s)
  184.     --Удаляем некорректные символы
  185.     s = string.gsub(s, "    ", " ")
  186.     s = string.gsub(s, "\r\n", "\n")
  187.     s = string.gsub(s, "\n", "")
  188.     --Заменяем "широкие" двухпиксельные символы на знак вопроса
  189.     local massiv = {}
  190.     for i = 1, unicode.len(s) do
  191.         massiv[i] = unicode.sub(s, i, i)
  192.         if unicode.isWide(massiv[i]) then massiv[i] = "?" end
  193.     end
  194.     --Возвращаем оптимизрованную строку
  195.     return table.concat(massiv)
  196. end
  197.  
  198. local function convertIDtoPeerID(whatIsThisID, ID)
  199.     if whatIsThisID == "user" then
  200.         return ID
  201.     elseif whatIsThisID == "chat" then
  202.         return (2000000000 + ID)
  203.     elseif whatIsThisID == "group" then
  204.         return -ID
  205.     end
  206. end
  207.  
  208. local function getPeerIDFromMessageArray(messageArray)
  209.     local peerID
  210.     --Если это чат
  211.     if messageArray.users_count then
  212.         peerID = convertIDtoPeerID("chat", messageArray.chat_id)
  213.     --Или если это диалог с группой какой-то
  214.     elseif messageArray.user_id < 0 then
  215.         peerID = convertIDtoPeerID("group", messageArray.user_id)
  216.     --Или если просто какой-то сталкер-одиночка
  217.     else
  218.         peerID = convertIDtoPeerID("user", messageArray.user_id)
  219.     end
  220.  
  221.     return peerID
  222. end
  223.  
  224. --Запрос на отправку сообщения указанному пидору
  225. local function sendMessageRequest(peerID, message)
  226.     --Делаем строчку не пидорской
  227.     message = optimizeStringForURLSending(message)
  228.     return VKAPIRequest("messages.send", "peer_id=" .. peerID, "message=" .. message)
  229. end
  230.  
  231. local function usersInformationRequest(...)
  232.     return VKAPIRequest("users.get", "user_ids=" .. table.concat({...}, ","), "fields=city,bdate,online,status,last_seen,followers_count")
  233. end
  234.  
  235. ---------------------------------------------------- GUI-часть ----------------------------------------------------------------
  236.  
  237. local function createAvatarHashColor(hash)
  238.     return math.abs(hash % 0xFFFFFF)
  239. end
  240.  
  241. local function drawAvatar(x, y, user_id, text)
  242.     local avatarColor = createAvatarHashColor(user_id)
  243.     local textColor = avatarColor > 8388607 and 0x000000 or 0xFFFFFF
  244.  
  245.     buffer.square(x, y, 6, 3, avatarColor, textColor, " ")
  246.     buffer.text(x + 2, y + 1, textColor, unicode.upper(text))
  247. end
  248.  
  249. --Проверка клика в определенную область по "объекту". Кому на хуй вссалось ООП?
  250. local function clickedAtZone(x, y, zone)
  251.     if x >= zone[1] and y >= zone[2] and x <= zone[3] and y <= zone[4] then
  252.         return true
  253.     end
  254.     return false
  255. end
  256.  
  257. --Интерфейс логина в аккаунт ВК, постараюсь сделать пографонистей
  258. --Хотя хах! Кого я обманываю, ага
  259. local function loginGUI(startUsername, startPassword)
  260.     local background = 0x002440
  261.     local buttonColor = 0x666DFF
  262.     local textColor = 0x262626
  263.     local username, password = startUsername or "E-Mail или номер телефона", startPassword or "Пароль"
  264.  
  265.     local textFieldWidth = 50
  266.     local textFieldHeight = 3
  267.     local x, y = math.floor(buffer.screen.width / 2 - textFieldWidth / 2), math.floor(buffer.screen.height / 2 - 3)
  268.  
  269.     local obj = {}
  270.     obj.username = {x, y, x + textFieldWidth - 1, y + 2}; y = y + textFieldHeight + 1
  271.     obj.password = {x, y, x + textFieldWidth - 1, y + 2}; y = y + textFieldHeight + 1
  272.     obj.button = {x, y, x + textFieldWidth - 1, y + 2}
  273.  
  274.     local VKLogoImage = image.load(VKLogoImagePath)
  275.  
  276.     local function draw()
  277.         buffer.clear(colors.loginGUIBackground)
  278.  
  279.         buffer.image(x + 5, obj.username[2] - 15, VKLogoImage)
  280.  
  281.         buffer.square(x, obj.username[2], textFieldWidth, 3, 0xFFFFFF, 0x000000, " ")
  282.         buffer.square(x, obj.password[2], textFieldWidth, 3, 0xFFFFFF, 0x000000, " ")
  283.         buffer.text(x + 1, obj.username[2] + 1, textColor, ecs.stringLimit("end", username, textFieldWidth - 2))
  284.         buffer.text(x + 1, obj.password[2] + 1, textColor, ecs.stringLimit("end", string.rep("●", unicode.len(password)), textFieldWidth - 2))
  285.  
  286.         buffer.button(x, obj.button[2], textFieldWidth, textFieldHeight, buttonColor, 0xFFFFFF, "Войти")
  287.  
  288.         buffer.draw()
  289.     end
  290.  
  291.     while true do
  292.         draw()
  293.         local e = {event.pull()}
  294.         if e[1] == "touch" then
  295.             if clickedAtZone(e[3], e[4], obj.username) then
  296.                 username = ""
  297.                 username = ecs.inputText(x + 1, obj.username[2] + 1, textFieldWidth - 2, username, 0xFFFFFF, 0x262626) or ""
  298.            
  299.             elseif clickedAtZone(e[3], e[4], obj.password) then
  300.                 password = ""
  301.                 password = ecs.inputText(x + 1, obj.password[2] + 1, textFieldWidth - 2, password, 0xFFFFFF, 0x262626, false, "*") or ""
  302.            
  303.             elseif clickedAtZone(e[3], e[4], obj.button) then
  304.                 buffer.button(x, obj.button[2], textFieldWidth, textFieldHeight, 0xFFFFFF, buttonColor, "Войти")
  305.                 buffer.draw()
  306.                 os.sleep(0.2)
  307.                 draw()
  308.                 local success, loginData = getLoginDataRequest(username, password)
  309.                 if success then
  310.                     return loginData
  311.                 else
  312.                     ecs.error("Неверный пароль!" .. tostring(loginData))
  313.                 end
  314.             end
  315.         end
  316.     end
  317. end
  318.  
  319. ---------------------------------------------------- GUI для взаимодействия с VK API ----------------------------------------------
  320.  
  321. local function drawPersonalAvatar(x, y)
  322.     drawAvatar(x, y, personalInfo.id, unicode.sub(personalInfo.first_name, 1, 1) .. unicode.sub(personalInfo.last_name, 1, 1))
  323. end
  324.  
  325. local function status(text)
  326.     buffer.square(mainZoneX, buffer.screen.height, mainZoneWidth, 1, colors.statusBar)
  327.     buffer.text(mainZoneX + 1, buffer.screen.height, colors.statusBarText, text)
  328.     buffer.draw()
  329. end
  330.  
  331. local function drawTopBar(text)
  332.     buffer.square(mainZoneX, 1, mainZoneWidth, 3, colors.topBar)
  333.     local x = math.floor(mainZoneX + mainZoneWidth / 2 - unicode.len(text) / 2 - 1)
  334.     buffer.text(x, 2, colors.topBarText, text)
  335. end
  336.  
  337. --Рисуем главную зону
  338. local function clearGUIZone()
  339.     buffer.square(mainZoneX, mainZoneY, mainZoneWidth, mainZoneHeight, colors.mainZone)
  340. end
  341.  
  342.  
  343.  
  344.  
  345.  
  346.  
  347.  
  348. local function drawEmptyCloud(x, y, cloudWidth, cloudHeight, cloudColor, fromYou)
  349.     local upperPixel = "▀"
  350.     local lowerPixel = "▄"
  351.  
  352.     --Рисуем финтифлюшечки
  353.     if not fromYou then
  354.         buffer.set(x, y - cloudHeight + 2, colors.mainZone, cloudColor, upperPixel)
  355.         buffer.set(x + 1, y - cloudHeight + 2, cloudColor, 0xFFFFFF, " ")
  356.         x = x + 2
  357.     else
  358.         buffer.set(x + cloudWidth + 3, y - cloudHeight + 2, colors.mainZone, cloudColor, upperPixel)
  359.         buffer.set(x + cloudWidth + 2, y - cloudHeight + 2, cloudColor, 0xFFFFFF, " ")
  360.     end
  361.  
  362.     --Заполняшечки
  363.     buffer.square(x + 1, y - cloudHeight + 1, cloudWidth, cloudHeight, cloudColor, 0xFFFFFF, " ")
  364.     buffer.square(x, y - cloudHeight + 2, cloudWidth + 2, cloudHeight - 2, cloudColor, 0xFFFFFF, " ")
  365.    
  366.     --Сгругленные краешки
  367.     buffer.set(x, y - cloudHeight + 1, colors.mainZone, cloudColor, lowerPixel)
  368.     buffer.set(x + cloudWidth + 1, y - cloudHeight + 1, colors.mainZone, cloudColor, lowerPixel)
  369.     buffer.set(x, y, colors.mainZone, cloudColor, upperPixel)
  370.     buffer.set(x + cloudWidth + 1, y, colors.mainZone, cloudColor, upperPixel)
  371.  
  372.     return y - cloudHeight + 1
  373. end
  374.  
  375. local function stringWrap(text, limit)
  376.     local strings = {}
  377.     local textLength = unicode.len(text)
  378.     local subFrom = 1
  379.     while subFrom <= textLength do
  380.         table.insert(strings, unicode.sub(text, subFrom, subFrom + limit - 1))
  381.         subFrom = subFrom + limit
  382.     end
  383.     return strings
  384. end
  385.  
  386. local function drawTextCloud(x, y, cloudColor, textColor, fromYou, text)
  387.     local y = drawEmptyCloud(x, y, cloudWidth, #text + 2, cloudColor, fromYou)
  388.     x = fromYou and x + 2 or x + 4
  389.  
  390.     for i = 1, #text do
  391.         buffer.text(x, y + i, textColor, text[i])
  392.     end
  393.  
  394.     return y
  395. end
  396.  
  397. local function getAttachments(messageArray)
  398.     local text = "Вложения: "
  399.     for j = 1, #messageArray.attachments do
  400.         if messageArray.attachments[j].type == "sticker" then
  401.             text = text .. "стикер, "
  402.         elseif messageArray.attachments[j].type == "photo" then
  403.             text = text .. "фото, "
  404.         elseif messageArray.attachments[j].type == "video" then
  405.             text = text .. "видео, "
  406.         elseif messageArray.attachments[j].type == "audio" then
  407.             text = text .. "аудио, "
  408.         elseif messageArray.attachments[j].type == "wall" then
  409.             text = text .. "запись на стене, "
  410.         end
  411.     end
  412.     text = unicode.sub(text, 1, -3)
  413.  
  414.     return text
  415. end
  416.  
  417. local function drawMessageInputBar(currentText)
  418.     local x, y = mainZoneX, buffer.screen.height - 5
  419.     obj.messageInputBar = { x, y, x + mainZoneWidth - 7, y + 2}
  420.     buffer.square(x, y, mainZoneWidth, 5, colors.messageInputBarColor)
  421.     buffer.square(x + 2, y + 1, mainZoneWidth - 4, 3, colors.messageInputBarTextBackgroundColor)
  422.     buffer.text(x + 4, y + 2, colors.messsageInputBarTextColor, ecs.stringLimit("start", currentText or "Введите сообщение", mainZoneWidth - 8))
  423. end
  424.  
  425. local function getUserNamesFromMessagesArray(messagesArray)
  426.     local usersToGetNames = {}
  427.     for i = 1, #messagesArray do
  428.         if messagesArray[i].user_id and messagesArray[i].user_id > 0 then
  429.             table.insert(usersToGetNames, messagesArray[i].user_id)
  430.         end
  431.     end
  432.  
  433.     local success, usersData = usersInformationRequest(table.unpack(usersToGetNames))
  434.     if success and usersData.response then
  435.         for i = 1, #messagesArray do
  436.             if messagesArray[i].user_id and messagesArray[i].user_id > 0 then
  437.                 for j = 1, #usersData.response do
  438.                     if usersData.response[j].id == messagesArray[i].user_id then
  439.                         messagesArray[i].first_name = usersData.response[j].first_name
  440.                         messagesArray[i].last_name = usersData.response[j].last_name
  441.                     end
  442.                 end
  443.             end
  444.         end
  445.     end
  446.  
  447.     return messagesArray
  448. end
  449.  
  450. local function messagesGUI()
  451.  
  452.     local success, messages = getMessagesRequest(currentMessagesPeerID, messageToShowFrom - 1, countOfMessagesToLoadFromServer)
  453.     if success and messages.response then
  454.  
  455.         whatIsOnScreen = "messages"
  456.  
  457.         if currentMessagesPeerID > 2000000000 then
  458.             status("Загружаю имена пользователей из переписки (актуально для конференций)")
  459.             messages.response.items = getUserNamesFromMessagesArray(messages.response.items)
  460.         end
  461.  
  462.         clearGUIZone()
  463.         drawTopBar("Диалог с \"" .. currentMessagesFullName .. "\"")
  464.  
  465.         saveToFile(serialization.serialize(messages))
  466.  
  467.         buffer.setDrawLimit(mainZoneX, mainZoneY, mainZoneWidth, mainZoneHeight)
  468.  
  469.         local y = buffer.screen.height - 7
  470.         local xSender = mainZoneX + 2
  471.         local xYou = buffer.screen.width - 7
  472.  
  473.         for i = 1, #messages.response.items do
  474.  
  475.             local messageTextArray = {}
  476.  
  477.             if messages.response.items[i].body ~= "" then table.insert(messageTextArray, optimizeStringForWrongSymbols(messages.response.items[i].body)) end
  478.             if messages.response.items[i].fwd_messages then table.insert(messageTextArray, "Пересланные сообщения") end
  479.             if messages.response.items[i].attachments then table.insert(messageTextArray, getAttachments(messages.response.items[i])) end
  480.  
  481.             messageTextArray = ecs.stringWrap(messageTextArray, cloudWidth - 4)
  482.             local peerID = getPeerIDFromMessageArray(messages.response.items[i])
  483.  
  484.             --Делаем дату пиздатой
  485.             -- messages.response.items[i].date = os.date("%d.%m.%y в %X", messages.response.items[i].date)
  486.             messages.response.items[i].date = os.date("%H:%M", messages.response.items[i].date)
  487.  
  488.             if messages.response.items[i].out == 1 then
  489.                 y = drawTextCloud(xYou - cloudWidth - 6, y, colors.yourCloudColor, colors.yourCloudTextColor, true, messageTextArray)
  490.                 drawPersonalAvatar(xYou, y)
  491.                 buffer.text(xYou - cloudWidth - unicode.len(messages.response.items[i].date) - 8, y + 1, colors.dateTime, messages.response.items[i].date)
  492.             else
  493.                 y = drawTextCloud(xSender + 8, y, colors.senderCloudColor, colors.senderCloudTextColor, false, messageTextArray)
  494.                 drawAvatar(xSender, y, peerID, messages.response.items[i].first_name and (unicode.sub(messages.response.items[i].first_name, 1, 1) .. unicode.sub(messages.response.items[i].last_name, 1, 1)) or currentMessagesAvatarText)
  495.                 buffer.text(xSender + cloudWidth + 14, y + 1, colors.dateTime, messages.response.items[i].date)
  496.             end
  497.  
  498.             y = y - 2
  499.         end
  500.  
  501.         local currentText
  502.  
  503.         drawMessageInputBar(currentText)
  504.  
  505.         status("История переписки загружена, ожидаю ввода сообщения")
  506.  
  507.         buffer.resetDrawLimit()
  508.         -- buffer.draw()
  509.     end
  510. end
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517. --У-у-у, господи, какие же уроды! Вроде такое охуенное вк апи, а пиздец!
  518. --Крч, эта функция получает имена юзеров по их айдишникам и загоняет их
  519. --в массив вместо title.
  520. --Собсна, нахуя? ДА ПОТОМУ ЧТО dialogs возвращают только ID юзеров с историей
  521. --сообщений, а не их имя. Ну, а имена КОНФ нормас пишутся. Что за бред?
  522. --Идите на хуйЙ!!!!!! КОСТЫЛЕЕБСТВО
  523. local function getUserNamesFromDialogArray(dialogs)
  524.     local usersToGetNames = {}
  525.    
  526.     for i = 1, #dialogs.response.items do
  527.         if dialogs.response.items[i].message.user_id and dialogs.response.items[i].message.user_id > 0 then
  528.             table.insert(usersToGetNames, dialogs.response.items[i].message.user_id)
  529.         end
  530.     end
  531.  
  532.     local success, usersData = usersInformationRequest(table.unpack(usersToGetNames))
  533.     if success and usersData.response then
  534.         for i = 1, #dialogs.response.items do
  535.             if not dialogs.response.items[i].message.chat_id then
  536.                 for j = 1, #usersData.response do
  537.                     if usersData.response[j].id == dialogs.response.items[i].message.user_id then
  538.                         dialogs.response.items[i].message.title = usersData.response[j].first_name .. " " .. usersData.response[j].last_name
  539.                     end
  540.                 end
  541.             end
  542.         end
  543.     end
  544.  
  545.     return dialogs
  546. end
  547.  
  548. local function drawDialog(y, dialogBackground, avatarID, avatarText, text1, text2, text3)
  549.     --Рисуем подложку под диалог нужного цвета
  550.     buffer.square(mainZoneX, y, mainZoneWidth, 5, dialogBackground)
  551.     --Рисуем аватарку, чо уж
  552.     drawAvatar(mainZoneX + 2, y + 1, avatarID, avatarText)
  553.     --Пишем все, что нужно
  554.     y = y + 1
  555.     if text1 then buffer.text(mainZoneX + 10, y, 0x000000, text1); y = y + 1 end
  556.     if text2 then buffer.text(mainZoneX + 10, y, 0x555555, text2); y = y + 1 end
  557.     if text3 then buffer.text(mainZoneX + 10, y, 0x666666, text3); y = y + 1 end
  558. end
  559.  
  560. local function dialogsGUI()
  561.  
  562.     local success, dialogs = getDialogsRequest(dialogToShowFrom - 1, countOfDialogsToLoadFromServer)
  563.     if success and dialogs.response then
  564.  
  565.         -- saveToFile(serialization.serialize(dialogs))
  566.        
  567.         whatIsOnScreen = "dialogs"
  568.  
  569.         obj.dialogList = {}
  570.  
  571.         clearGUIZone()
  572.         drawTopBar("Сообщения")
  573.         buffer.draw()
  574.  
  575.         --НУ ТЫ ПОНЯЛ, АГА
  576.         status("Получаю имена пользователей по ID")
  577.         dialogs = getUserNamesFromDialogArray(dialogs)
  578.  
  579.         local y = mainZoneY
  580.         local avatarText = ""
  581.         local peerID
  582.         local color
  583.  
  584.         for i = 1, #dialogs.response.items do
  585.             --Ебемся с цветами
  586.             if dialogs.response.items[i].unread then
  587.                 if i % 2 == 0 then
  588.                     color = 0xCCDBFF
  589.                 else
  590.                     color = 0xCCDBFF
  591.                 end
  592.             else
  593.                 if i % 2 == 0 then
  594.                     color = 0xEEEEEE
  595.                 else
  596.                     color = 0xFFFFFF
  597.                 end
  598.             end
  599.            
  600.             --Рисуем пиздюлинку, показывающую кол-во непрочитанных сообщений
  601.             if dialogs.response.items[i].unread and dialogs.response.items[i].unread ~= 0 then
  602.                 local cyka = tostring(dialogs.response.items[i].unread)
  603.                 local cykaWidth = unicode.len(cyka) + 2
  604.                 local cykaX = buffer.screen.width - cykaWidth - 4
  605.                 buffer.square(cykaX, y + 2, cykaWidth, 1, ecs.colors.blue)
  606.                 buffer.text(cykaX + 1, y + 2, 0xFFFFFF, cyka)
  607.             end
  608.  
  609.            
  610.             avatarText = unicode.sub(dialogs.response.items[i].message.title, 1, 2)
  611.             peerID = getPeerIDFromMessageArray(dialogs.response.items[i].message)
  612.  
  613.             --Ебля с текстом диалога
  614.             local text1 = dialogs.response.items[i].message.title
  615.             local text2
  616.             local text3
  617.  
  618.             --Если это банальное сообщение
  619.             if dialogs.response.items[i].message.body and dialogs.response.items[i].message.body ~= "" then
  620.                 text2 = optimizeStringForWrongSymbols(dialogs.response.items[i].message.body)
  621.             end
  622.  
  623.             --Если есть какие-либо пересланные сообщения, то
  624.             if dialogs.response.items[i].message.fwd_messages then
  625.                 text3 = "Пересланные сообщения"
  626.             --Если есть какие-либо вложения, то
  627.             elseif dialogs.response.items[i].message.attachments then
  628.                 text3 = getAttachments(dialogs.response.items[i].message)
  629.             end
  630.  
  631.             --Рисуем диалог
  632.             drawDialog(y, color, peerID, avatarText, text1, text2, text3)
  633.  
  634.             newObj("dialogList", i, mainZoneX, y, mainZoneX + mainZoneWidth - 1, y + 4, peerID, avatarText, text1, text2, text3)
  635.  
  636.             y = y + 5
  637.         end
  638.     end
  639.  
  640.     status("Список диалогов получен")
  641. end
  642.  
  643. local function audioGUI(ID)
  644.     local success, audios = getAudioRequest(ID, audioToShowFrom - 1, countOfAudioToLoadFromServer)
  645.     if success and audios.response then
  646.         whatIsOnScreen = "audio"
  647.  
  648.         obj.audio = {}
  649.  
  650.         clearGUIZone()
  651.         drawTopBar("Аудиозаписи " .. audios.response.items[1].name_gen)
  652.  
  653.         local y = mainZoneY
  654.         local color
  655.         for i = 2, #audios.response.items do
  656.             color = 0xFFFFFF
  657.             if i % 2 == 0 then color = 0xEEEEEE end
  658.  
  659.             buffer.square(mainZoneX, y, mainZoneWidth, 5, color)
  660.  
  661.             buffer.button(mainZoneX + 2, y + 1, 5, 3, colors.audioPlayButton, colors.audioPlayButtonText, "ᐅ")
  662.  
  663.             newObj("audio", i, mainZoneX + 2, y + 1, mainZoneX + 7, y + 3, audios.response.items[i].url)
  664.  
  665.             local x = mainZoneX + 9
  666.             buffer.text(x, y + 1, colors.audioPlayButton, audios.response.items[i].artist)
  667.             x = x + unicode.len(audios.response.items[i].artist)
  668.             buffer.text(x, y + 1, 0x000000, " - " .. audios.response.items[i].title)
  669.  
  670.             x = mainZoneX + 9
  671.             local hours = string.format("%02.f", math.floor(audios.response.items[i].duration / 3600))
  672.             local minutes = string.format("%02.f", math.floor(audios.response.items[i].duration / 60 - (hours * 60)))
  673.             local seconds = string.format("%02.f", math.floor(audios.response.items[i].duration - hours * 3600 - minutes * 60))
  674.             buffer.text(x, y + 2, 0x555555, "Длительность: " .. hours .. ":" .. minutes .. ":" .. seconds)
  675.  
  676.             y = y + 5
  677.         end
  678.     end
  679. end
  680.  
  681. --Главное ГУИ с левтбаром и прочим
  682. local function mainGUI()
  683.     --Подложка под элементы
  684.     buffer.square(1, 1, leftBarWidth, buffer.screen.height, colors.leftBar, 0xFFFFFF, " ")
  685.    
  686.     if personalInfo then
  687.         drawPersonalAvatar(3, 2)
  688.         buffer.text(11, 3, 0xFFFFFF, ecs.stringLimit("end", personalInfo.first_name .. " " .. personalInfo.last_name, leftBarWidth - 11))
  689.     end
  690.  
  691.     --Элементы
  692.     obj.leftBar = {}
  693.     local y, color = 6
  694.     for i = 1, #leftBarElements do
  695.         color = colors.leftBarAlternative
  696.         if i % 2 == 0 then color = colors.leftBar end
  697.         if i == currentLeftBarElement then color = colors.leftBarSelection end
  698.  
  699.         newObj("leftBar", i, 1, y, leftBarWidth, y + 2)
  700.  
  701.         buffer.square(1, y, leftBarWidth, 3, color, 0xFFFFFF, " ")
  702.         y = y + 1
  703.         buffer.text(3, y, colors.leftBarText, ecs.stringLimit("end", leftBarElements[i], leftBarWidth - 4))
  704.         y = y + 2
  705.     end
  706.  
  707.     if leftBarElements[currentLeftBarElement] == "Сообщения" then
  708.         status("Получаю список диалогов")
  709.         messageToShowFrom = 1
  710.         dialogToShowFrom = 1
  711.         dialogsGUI()
  712.     elseif leftBarElements[currentLeftBarElement] == "Аудиозаписи" then
  713.         status("Получаю список аудозаписей")
  714.         audioToShowFrom = 1
  715.         audioGUI(personalInfo.id)
  716.     end
  717.  
  718.     buffer.draw()
  719. end
  720.  
  721. ---------------------------------------------------- Старт скрипта ----------------------------------------------------------------
  722.  
  723. --Инициализируем библиотеку двойного буффера
  724. --Эх, что бы я делал, если б не накодил ее? 0.2 фпс на GPU мертвеца!
  725. buffer.start()
  726. --Активируем форму логина
  727. local loginData = loginGUI("cyka@yandex.com", "13131313")
  728. access_token = loginData.access_token
  729. --Получаем персональные данные
  730. _, personalInfo = usersInformationRequest(loginData.user_id)
  731. personalInfo = personalInfo.response[1]
  732.  
  733. --Активируем главное GUI
  734. clearGUIZone()
  735. mainGUI()
  736.  
  737. while true do
  738.     local e = {event.pull()}
  739.     if e[1] == "touch" then
  740.  
  741.         if whatIsOnScreen == "audio" then
  742.             for key in pairs(obj.audio) do
  743.                 if clickedAtZone(e[3], e[4], obj.audio[key]) then
  744.                     buffer.button(obj.audio[key][1], obj.audio[key][2], 5, 3, 0x66FF80,  colors.audioPlayButton, "ᐅ")
  745.                     buffer.draw()
  746.                     os.sleep(0.2)
  747.                     buffer.button(obj.audio[key][1], obj.audio[key][2], 5, 3, colors.audioPlayButton, colors.audioPlayButtonText, "ᐅ")
  748.                     buffer.draw()
  749.  
  750.                     if component.isAvailable("openfm_radio") then
  751.                         component.openfm_radio.stop()
  752.                         component.openfm_radio.setURL(obj.audio[key][5])
  753.                         component.openfm_radio.start()
  754.                     else
  755.                         ecs.error("Эта функция доступна только при наличии установленного мода OpenFM, добавляющего полноценное интернет-радио")
  756.                     end
  757.  
  758.                     break
  759.                 end
  760.             end
  761.         end
  762.  
  763.         if whatIsOnScreen == "dialogs" then
  764.             for key in pairs(obj.dialogList) do
  765.                 if clickedAtZone(e[3], e[4], obj.dialogList[key]) then
  766.                     drawDialog(obj.dialogList[key][2], 0xFF8888, obj.dialogList[key][5], obj.dialogList[key][6], obj.dialogList[key][7], obj.dialogList[key][8], obj.dialogList[key][9])
  767.                     buffer.draw()
  768.                     os.sleep(0.2)
  769.                     status("Загружаю переписку с пользователем " .. obj.dialogList[key][7])
  770.                     currentMessagesPeerID = obj.dialogList[key][5]
  771.                     currentMessagesAvatarText = obj.dialogList[key][6]
  772.                     currentMessagesFullName = obj.dialogList[key][7]
  773.                     messagesGUI()
  774.                     break
  775.                 end
  776.             end
  777.         end
  778.  
  779.         if whatIsOnScreen == "messages" then
  780.             if clickedAtZone(e[3], e[4], obj.messageInputBar) then
  781.                 drawMessageInputBar(" ")
  782.                 buffer.draw()
  783.                 local newText = ecs.inputText(obj.messageInputBar[1] + 4, obj.messageInputBar[2] + 2, obj.messageInputBar[3] - obj.messageInputBar[1], "", colors.messageInputBarTextBackgroundColor, colors.messsageInputBarTextColor)
  784.                 if newText and newText ~= " " then
  785.                     computer.beep(1700)
  786.                     status("Отправляю сообщение пользователю")
  787.                     sendMessageRequest(currentMessagesPeerID, newText .. " (отправлено с OpenComputers)")
  788.                     status("Обновляю историю переписки")
  789.                     messageToShowFrom = 1
  790.                     messagesGUI()
  791.                 end
  792.                 drawMessageInputBar(" ")
  793.             end
  794.         end
  795.  
  796.         for key in pairs(obj.leftBar) do
  797.             if clickedAtZone(e[3], e[4], obj.leftBar[key]) then
  798.                 -- ecs.error("Кликнули на лефт бар ээлемент")
  799.                 currentLeftBarElement = key
  800.                 mainGUI()
  801.  
  802.                 if leftBarElements[currentLeftBarElement] == "Выход" then
  803.                     os.sleep(0.3)
  804.                     buffer.clear(0x262626)
  805.                     ecs.prepareToExit()
  806.                     return
  807.                 end
  808.  
  809.                 break
  810.             end
  811.         end
  812.     elseif e[1] == "scroll" then
  813.         if e[5] == 1 then
  814.             if whatIsOnScreen == "dialogs" then
  815.                 dialogToShowFrom = dialogToShowFrom - dialogScrollSpeed
  816.                 if dialogToShowFrom < 1 then dialogToShowFrom = 1 end
  817.                 status("Прокручиваю диалоги, отправляю запрос на сервер")
  818.                 dialogsGUI()
  819.                 buffer.draw()
  820.             elseif whatIsOnScreen == "messages" then
  821.                 messageToShowFrom = messageToShowFrom + messagesScrollSpeed
  822.                 status("Прокручиваю сообщения, отправляю запрос на сервер")
  823.                 messagesGUI()
  824.                 buffer.draw()
  825.             elseif whatIsOnScreen == "audio" then
  826.                 audioToShowFrom = audioToShowFrom - audioScrollSpeed
  827.                 if audioToShowFrom < 1 then audioToShowFrom = 1 end
  828.                 status("Прокручиваю аудозаписи, отправляю запрос на сервер")
  829.                 audioGUI(personalInfo.id)
  830.                 buffer.draw()
  831.             end
  832.         else
  833.             if whatIsOnScreen == "dialogs" then
  834.                 dialogToShowFrom = dialogToShowFrom + dialogScrollSpeed
  835.                 status("Прокручиваю диалоги, отправляю запрос на сервер")
  836.                 dialogsGUI()
  837.                 buffer.draw()
  838.             elseif whatIsOnScreen == "messages" then
  839.                 messageToShowFrom = messageToShowFrom - messagesScrollSpeed
  840.                 if messageToShowFrom < 1 then messageToShowFrom = 1 end
  841.                 status("Прокручиваю сообщения, отправляю запрос на сервер")
  842.                 messagesGUI()
  843.                 buffer.draw()
  844.             elseif whatIsOnScreen == "audio" then
  845.                 audioToShowFrom = audioToShowFrom + audioScrollSpeed
  846.                 status("Прокручиваю аудозаписи, отправляю запрос на сервер")
  847.                 audioGUI(personalInfo.id)
  848.                 buffer.draw()
  849.             end
  850.         end
  851.     end
  852. end
  853.  
  854. -- local success, dialogs = getDialogsRequest(0, 5)
  855. -- saveToFile(serialization.serialize(dialogs))
  856.  
  857.  
  858. -- sendMessageRequest(dialogs.response.items[2], "тестовое сообщение, отправлено через OpenComputers VK Client by Игорь, епта")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement