Advertisement
Guest User

Main.lua

a guest
Oct 27th, 2017
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 53.86 KB | None | 0 0
  1.  
  2. ---------------------------------------------------- Библиотеки ----------------------------------------------------------------
  3.  
  4. local advancedLua = require("advancedLua")
  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. local GUI = require("GUI")
  17. local MineOSCore = require("MineOSCore")
  18. local MineOSPaths = require("MineOSPaths")
  19.  
  20. ---------------------------------------------------- Константы ----------------------------------------------------------------
  21.  
  22. local VKAPIVersion = "5.52"
  23.  
  24. local colors = {
  25.     leftBar = 0x262626,
  26.     leftBarAlternative = 0x383838,
  27.     leftBarText = 0xFFFFFF,
  28.     leftBarSelection = 0x00A8FF,
  29.     leftBarSelectionText = 0xFFFFFF,
  30.  
  31.     scrollBar = 0xCCCCCC,
  32.     scrollBarPipe = 0x666666,
  33.  
  34.     mainZone = 0xFFFFFF,
  35.     senderCloudColor = 0x3392FF,
  36.     senderCloudTextColor = 0xFFFFFF,
  37.     yourCloudColor = 0x55BBFF,
  38.     yourCloudTextColor = 0xFFFFFF,
  39.     systemMessageColor = 0x555555,
  40.     dateTime = 0x777777,
  41.  
  42.     loginGUIBackground = 0x002440,
  43.  
  44.     topBar = 0x002440,
  45.     topBarText = 0xFFFFFF,
  46.  
  47.     statusBar = 0x1b1b1b,
  48.     statusBarText = 0xAAAAAA,
  49.  
  50.     audioPlayButton = 0x002440,
  51.     audioPlayButtonText = 0xFFFFFF,
  52.  
  53.     messageInputBarColor = 0xEEEEEE,
  54.     messageInputBarTextBackgroundColor = 0xFFFFFF,
  55.     messsageInputBarTextColor = 0x262626,
  56. }
  57.  
  58. local leftBarHeight = buffer.height - 9
  59. local leftBarWidth = math.floor(buffer.width * 0.20)
  60.  
  61. local topBarHeight = 3
  62.  
  63. local mainZoneWidth = buffer.width - leftBarWidth
  64. local mainZoneHeight = buffer.height - topBarHeight - 1
  65. local mainZoneX = leftBarWidth + 1
  66. local mainZoneY = topBarHeight + 1
  67.  
  68. local cloudWidth = math.floor(mainZoneWidth * 0.7)
  69.  
  70. -------------------------------------------------------------------------------------------------------------------------------
  71.  
  72. local settingsPath = MineOSPaths.applicationData .. "VK/Settings.cfg"
  73. -- local leftBarElements = {"Новости", "Друзья", "Сообщения", "Настройки", "Выход"}
  74. local leftBarElements = { "Моя страница", "Друзья", "Сообщения", "Аудиозаписи", "Новости", "Настройки", "Выход" }
  75. local currentLeftBarElement = 3
  76. local personalInfo
  77. local access_token
  78. local whatIsOnScreen
  79.  
  80. local countOfDialogsToLoadFromServer = 10
  81. local countOfAudioToLoadFromServer = 10
  82. local countOfMessagesToLoadFromServer = 10
  83.  
  84. local dialogToShowFrom = 1
  85. local audioToShowFrom = 1
  86. local messageToShowFrom = 1
  87.  
  88. local dialogScrollSpeed = 5
  89. local audioScrollSpeed = 5
  90. local messagesScrollSpeed = 5
  91. local profileScrollSpeed = 2
  92. local friendsScrollSpeed = 5
  93.  
  94. local countOfFriendsToGetOnFriendsTab = 12
  95. local currentFriendsOffset = 0
  96. local currentFriends = {}
  97.  
  98. local countOfFriendsToDisplayInProfile = 16
  99. local currentProfileY = mainZoneY + 2
  100.  
  101. local currentMessagesPeerID, currentMessagesAvatarText
  102. local dialogPreviewTextLimit = mainZoneWidth - 15
  103. local currentProfile
  104.  
  105. local settings = {saveAuthData = false, addSendingInfo = true}
  106.  
  107. local vip = {
  108.     [7799889] = {avatarColor = 0x000000, avatarTextColor = 0xCCCCCC, avatarBottomText = "DEV", avatarBottomTextColor = 0x1b1b1b},
  109.     [113499693] = {avatarColor = 0xFF99CC, avatarTextColor = 0x000000, avatarBottomText = "DEV", avatarBottomTextColor = 0xff6dbf},
  110.     [60991376] = {avatarColor = 0xEEEEEE, avatarTextColor = 0x000000, avatarBottomText = "DEV", avatarBottomTextColor = 0x555555},
  111. }
  112.  
  113. local messageEndAdderText = " (отправлено с MineOS VKClient)"
  114.  
  115. local news
  116. local currentNews = 1
  117. local countOfNewsToShow = 10
  118. local countOfNewsToGet = 20
  119.  
  120. ---------------------------------------------------- Веб-часть ----------------------------------------------------------------
  121.  
  122. local function loadSettings()
  123.     if fs.exists(settingsPath) then settings = table.fromFile(settingsPath) end
  124. end
  125.  
  126. local function saveSettings()
  127.     table.toFile(settingsPath, settings)
  128. end
  129.  
  130. --Объекты
  131. local obj = {}
  132. local function newObj(class, name, ...)
  133.     obj[class] = obj[class] or {}
  134.     obj[class][name] = {...}
  135. end
  136.  
  137. --Дебаг-функция на сохранение говна в файл, МАЛО ЛИ ЧО
  138. local function saveToFile(filename, stro4ka)
  139.     local file = io.open(filename, "w")
  140.     file:write(stro4ka)
  141.     file:close()
  142. end
  143.  
  144. --Банальный URL-запрос, декодирующийся через ЖУСОН в случае успеха, епты
  145. local function request(url)
  146.     local success, response = ecs.internetRequest(url)
  147.     if success then
  148.         response = json:decode(response)
  149.     end
  150.     return success, response
  151. end
  152.  
  153. --Отправляем запрос на авторизацию по логину и паролю
  154. local function getLoginDataRequest(username, password)
  155.     local url = "https://oauth.vk.com/token?grant_type=password&client_id=3697615&client_secret=AlVXZFMUqyrnABp8ncuU&username=" .. username .. "&password=" .. password .. "&v=" .. VKAPIVersion
  156.     return request(url)
  157. end
  158.  
  159. --Запрос к методам VK API
  160. local function VKAPIRequest(method, ... )
  161.     local arguments = { ... }
  162.     local stringArguments = ""
  163.  
  164.     local url = "https://api.vk.com/method/" .. method .. "?" .. table.concat(arguments, "&") .. "&access_token=" .. access_token .. "&v=" .. VKAPIVersion
  165.  
  166.     return request(url)
  167. end
  168.  
  169. --Запрос на получение списка диалогов
  170. local function getDialogsRequest(fromDialog, count)
  171.     return VKAPIRequest("messages.getDialogs", "offset=" .. fromDialog, "count=" .. count, "preview_length=" .. dialogPreviewTextLimit)
  172. end
  173.  
  174. --Запрос на получение списка диалогов
  175. local function getMessagesRequest(peerID, fromMessage, count)
  176.     return VKAPIRequest("messages.getHistory", "offset=" .. fromMessage, "count=" .. count, "peer_id=" .. peerID)
  177. end
  178.  
  179. --Запрос на получение списка музычки
  180. local function getAudioRequest(id, fromAudio, count)
  181.     return VKAPIRequest("audio.get", "offset=" .. fromAudio, "count=" .. count, "owner_id=" .. id, "need_user=1")
  182. end
  183.  
  184. --Эта хуйня делает строку охуенной путем замены говна на конфетку
  185. local function optimizeStringForURLSending(code)
  186.   if code then
  187.     code = string.gsub(code, "([^%w ])", function (c)
  188.       return string.format("%%%02X", string.byte(c))
  189.     end)
  190.     code = string.gsub(code, " ", "+")
  191.   end
  192.   return code
  193. end
  194.  
  195. local function optimizeStringForWrongSymbols(s)
  196.     --Удаляем некорректные символы
  197.     s = string.gsub(s, "    ", " ")
  198.     s = string.gsub(s, "\r\n", "\n")
  199.     s = string.gsub(s, "\n", "")
  200.     --Заменяем "широкие" двухпиксельные символы на знак вопроса
  201.     local massiv = {}
  202.     for i = 1, unicode.len(s) do
  203.         massiv[i] = unicode.sub(s, i, i)
  204.         if unicode.isWide(massiv[i]) then massiv[i] = "?" end
  205.     end
  206.     --Возвращаем оптимизрованную строку
  207.     return table.concat(massiv)
  208. end
  209.  
  210. local function convertIDtoPeerID(whatIsThisID, ID)
  211.     if whatIsThisID == "user" then
  212.         return ID
  213.     elseif whatIsThisID == "chat" then
  214.         return (2000000000 + ID)
  215.     elseif whatIsThisID == "group" then
  216.         return -ID
  217.     end
  218. end
  219.  
  220. local function getPeerIDFromMessageArray(messageArray)
  221.     local peerID
  222.     --Если это чат
  223.     if messageArray.users_count then
  224.         peerID = convertIDtoPeerID("chat", messageArray.chat_id)
  225.     --Или если это диалог с группой какой-то
  226.     elseif messageArray.user_id < 0 then
  227.         peerID = convertIDtoPeerID("group", messageArray.user_id)
  228.     --Или если просто какой-то сталкер-одиночка
  229.     else
  230.         peerID = convertIDtoPeerID("user", messageArray.user_id)
  231.     end
  232.  
  233.     return peerID
  234. end
  235.  
  236. --Запрос на отправку сообщения указанному пидору
  237. local function sendMessageRequest(peerID, message)
  238.     --Делаем строчку не пидорской
  239.     message = optimizeStringForURLSending(message)
  240.     return VKAPIRequest("messages.send", "peer_id=" .. peerID, "message=" .. message)
  241. end
  242.  
  243. local function usersInformationRequest(...)
  244.     return VKAPIRequest("users.get", "user_ids=" .. table.concat({...}, ","), "fields=contacts,education,site,city,bdate,online,status,last_seen,quotes,about,games,books,counters,relatives,connections,blacklisted,activities,interests,music,movies,tv")
  245. end
  246.  
  247. local function userFriendsRequest(ID, count, offset, order, nameCase)
  248.     return VKAPIRequest("friends.get", "user_id=" .. ID, "count=" .. count, "offset=" .. offset, "order=" .. order, "name_case=" .. nameCase, "fields=domain,online,last_seen")
  249. end
  250.  
  251. local function userFriendsListsRequest(ID)
  252.     return VKAPIRequest("friends.getLists", "user_id=" .. ID, "return_system=1")
  253. end
  254.  
  255. local function userWallRequest(ID, count, offset)
  256.     return VKAPIRequest("wall.get", "owner_id=" .. ID, "count=" .. count, "offset=" .. offset)
  257. end
  258.  
  259. local function setCurrentAudioPlaying(ownerID, audioID)
  260.     return VKAPIRequest("audio.setBroadcast", "audio=" .. ownerID .. "_" .. audioID)
  261. end
  262.  
  263. local function newsRequest(count)
  264.     return VKAPIRequest("newsfeed.get", "filters=post", "return_banned=1", "max_photos=0", "count=" .. count, "fields=name,first_name,last_name")
  265. end
  266.  
  267. local function setCrazyTypingRequest(peer_id)
  268.     return VKAPIRequest("messages.setActivity", "type=typing", "peer_id=" .. peer_id)
  269. end
  270.  
  271.  
  272.  
  273.  
  274.  
  275. ---------------------------------------------------- GUI-часть ----------------------------------------------------------------
  276.  
  277. local function createAvatarHashColor(hash)
  278.     return math.abs(hash % 0xFFFFFF)
  279. end
  280.  
  281. local function drawAvatar(x, y, width, height, user_id, text)
  282.     local avatarColor = createAvatarHashColor(user_id)
  283.     local textColor = avatarColor > 8388607 and 0x000000 or 0xFFFFFF
  284.  
  285.     --Хочу себе персональную авку, а то че за хуйня?
  286.     if vip[user_id] then
  287.         avatarColor = vip[user_id].avatarColor
  288.         textColor = vip[user_id].avatarTextColor
  289.     end
  290.  
  291.     buffer.square(x, y, width, height, avatarColor, textColor, " ")
  292.     buffer.text(x + math.floor(width / 2) - math.floor(unicode.len(text) / 2), y + math.floor(height / 2), textColor, unicode.upper(text))
  293.  
  294.     if vip[user_id] and vip[user_id].avatarBottomText then buffer.text(x + math.floor(width / 2) - math.floor(unicode.len(text) / 2), y + height - 1, vip[user_id].avatarBottomTextColor, vip[user_id].avatarBottomText) end
  295. end
  296.  
  297. --Проверка клика в определенную область по "объекту". Кому на хуй вссалось ООП?
  298. local function clickedAtZone(x, y, zone)
  299.     if x >= zone[1] and y >= zone[2] and x <= zone[3] and y <= zone[4] then
  300.         return true
  301.     end
  302.     return false
  303. end
  304.  
  305. --Интерфейс логина в аккаунт ВК, постараюсь сделать пографонистей
  306. --Хотя хах! Кого я обманываю, ага
  307. local function loginGUI(startUsername, startPassword)
  308.     local background = 0x002440
  309.     local buttonColor = 0x666DFF
  310.     local textColor = 0x262626
  311.     local username, password = startUsername, startPassword
  312.  
  313.     local textFieldWidth = 50
  314.     local textFieldHeight = 3
  315.     local x, y = math.floor(buffer.width / 2 - textFieldWidth / 2), math.floor(buffer.height / 2)
  316.  
  317.     local obj = {}
  318.     obj.username = {x, y, x + textFieldWidth - 1, y + 2}; y = y + textFieldHeight + 1
  319.     obj.password = {x, y, x + textFieldWidth - 1, y + 2}; y = y + textFieldHeight + 1
  320.     obj.button = GUI.button(x, y, textFieldWidth, textFieldHeight, buttonColor, 0xEEEEEE, 0xEEEEEE, buttonColor, "Войти")
  321.  
  322.     local loginTextBox = GUI.input(x, obj.username[2], textFieldWidth, 3, 0xEEEEEE, 0x777777, 0x777777, 0xEEEEEE, 0x262626, username, "E-Mail", false)
  323.     local passwordTextBox = GUI.input(x, obj.password[2], textFieldWidth, 3, 0xEEEEEE, 0x777777, 0x777777, 0xEEEEEE, 0x262626, password, "Password", false, "*")
  324.  
  325.     local function draw()
  326.         buffer.clear(colors.loginGUIBackground)
  327.  
  328.         loginTextBox:draw()
  329.         passwordTextBox:draw()     
  330.         obj.button:draw()
  331.  
  332.         buffer.draw()
  333.     end
  334.  
  335.     while true do
  336.         draw()
  337.         local e = {event.pull()}
  338.         if e[1] == "touch" then
  339.             if clickedAtZone(e[3], e[4], obj.username) then
  340.                 loginTextBox.eventHandler({draw = function() loginTextBox:draw() end}, loginTextBox, {[1] = "touch", [3] = loginTextBox.x, [4] = loginTextBox.y})
  341.                 username = loginTextBox.text
  342.  
  343.             elseif clickedAtZone(e[3], e[4], obj.password) then
  344.                 passwordTextBox.eventHandler({draw = function() passwordTextBox:draw() end}, passwordTextBox, {[1] = "touch", [3] = passwordTextBox.x, [4] = passwordTextBox.y})
  345.                 password = passwordTextBox.text
  346.            
  347.             elseif obj.button:isClicked(e[3], e[4]) then
  348.                 obj.button:press(0.2)
  349.                 draw()
  350.                 local success, loginData = getLoginDataRequest(username or "", password or "")
  351.                 if success then
  352.                     if settings.saveAuthData then settings.username = username; settings.password = password; saveSettings() end
  353.                     loginData.username = username
  354.                     loginData.password = password
  355.                     return loginData
  356.                 else
  357.                     GUI.error("Ошибка авторизации: " .. tostring(loginData))
  358.                 end
  359.             end
  360.         end
  361.     end
  362. end
  363.  
  364. ---------------------------------------------------- GUI для взаимодействия с VK API ----------------------------------------------
  365.  
  366. local function drawPersonalAvatar(x, y, width, height)
  367.     drawAvatar(x, y, width, height, personalInfo.id, unicode.sub(personalInfo.first_name, 1, 1) .. unicode.sub(personalInfo.last_name, 1, 1))
  368. end
  369.  
  370. local function status(text)
  371.     buffer.square(mainZoneX, buffer.height, mainZoneWidth, 1, colors.statusBar, 0x0, " ")
  372.     buffer.text(mainZoneX + 1, buffer.height, colors.statusBarText, text)
  373.     buffer.draw()
  374. end
  375.  
  376. local function drawTopBar(text)
  377.     buffer.square(mainZoneX, 1, mainZoneWidth, 3, colors.topBar, 0x0, " ")
  378.     local x = math.floor(mainZoneX + mainZoneWidth / 2 - unicode.len(text) / 2 - 1)
  379.     buffer.text(x, 2, colors.topBarText, text)
  380. end
  381.  
  382. --Рисуем главную зону
  383. local function clearGUIZone()
  384.     buffer.square(mainZoneX, mainZoneY, mainZoneWidth, mainZoneHeight, colors.mainZone, 0x0, " ")
  385. end
  386.  
  387. local function drawEmptyCloud(x, y, cloudWidth, cloudHeight, cloudColor, fromYou)
  388.     local upperPixel = "▀"
  389.     local lowerPixel = "▄"
  390.  
  391.     --Рисуем финтифлюшечки
  392.     if not fromYou then
  393.         buffer.set(x, y - cloudHeight + 2, colors.mainZone, cloudColor, upperPixel)
  394.         buffer.set(x + 1, y - cloudHeight + 2, cloudColor, 0xFFFFFF, " ")
  395.         x = x + 2
  396.     else
  397.         buffer.set(x + cloudWidth + 3, y - cloudHeight + 2, colors.mainZone, cloudColor, upperPixel)
  398.         buffer.set(x + cloudWidth + 2, y - cloudHeight + 2, cloudColor, 0xFFFFFF, " ")
  399.     end
  400.  
  401.     --Заполняшечки
  402.     buffer.square(x + 1, y - cloudHeight + 1, cloudWidth, cloudHeight, cloudColor, 0xFFFFFF, " ")
  403.     buffer.square(x, y - cloudHeight + 2, cloudWidth + 2, cloudHeight - 2, cloudColor, 0xFFFFFF, " ")
  404.    
  405.     --Сгругленные краешки
  406.     buffer.set(x, y - cloudHeight + 1, colors.mainZone, cloudColor, lowerPixel)
  407.     buffer.set(x + cloudWidth + 1, y - cloudHeight + 1, colors.mainZone, cloudColor, lowerPixel)
  408.     buffer.set(x, y, colors.mainZone, cloudColor, upperPixel)
  409.     buffer.set(x + cloudWidth + 1, y, colors.mainZone, cloudColor, upperPixel)
  410.  
  411.     return y - cloudHeight + 1
  412. end
  413.  
  414. local function drawTextCloud(x, y, cloudColor, textColor, fromYou, text)
  415.     local y = drawEmptyCloud(x, y, cloudWidth, #text + 2, cloudColor, fromYou)
  416.     x = fromYou and x + 2 or x + 4
  417.  
  418.     for i = 1, #text do
  419.         buffer.text(x, y + i, textColor, text[i])
  420.     end
  421.  
  422.     return y
  423. end
  424.  
  425. local function getAttachments(messageArray)
  426.     local text = "Вложения: "
  427.     for j = 1, #messageArray.attachments do
  428.         if messageArray.attachments[j].type == "sticker" then
  429.             text = text .. "стикер, "
  430.         elseif messageArray.attachments[j].type == "photo" then
  431.             text = text .. "фото, "
  432.         elseif messageArray.attachments[j].type == "video" then
  433.             text = text .. "видео, "
  434.         elseif messageArray.attachments[j].type == "audio" then
  435.             text = text .. "аудио, "
  436.         elseif messageArray.attachments[j].type == "wall" then
  437.             text = text .. "запись на стене, "
  438.         end
  439.     end
  440.     text = unicode.sub(text, 1, -3)
  441.  
  442.     return text
  443. end
  444.  
  445. local function drawMessageInputBar(currentText)
  446.     local x, y = mainZoneX, buffer.height - 5
  447.     buffer.square(x, y, mainZoneWidth, 5, colors.messageInputBarColor, 0x0, " ")
  448.     obj.messageInputBar = GUI.input(x + 2, y + 1, mainZoneWidth - 4, 3, 0xFFFFFF, 0x444444, 0x444444, 0xFFFFFF, 0x262626, nil, "Введите сообщение", true)
  449.     obj.messageInputBar:draw()
  450. end
  451.  
  452. local function getUserNamesFromTheirIDs(IDsArray)
  453.     local success, usersData = usersInformationRequest(table.unpack(IDsArray))
  454.     local userNames = {}
  455.     if success and usersData.response then
  456.         for i = 1, #usersData.response do
  457.             userNames[usersData.response[i].id] = {
  458.                 first_name = usersData.response[i].first_name,
  459.                 last_name = usersData.response[i].last_name,
  460.             }
  461.         end
  462.     end
  463.     return success, userNames
  464. end
  465.  
  466. local function messagesGUI()
  467.  
  468.     status("Загружаю историю переписки")
  469.     local success, messages = getMessagesRequest(currentMessagesPeerID, messageToShowFrom - 1, countOfMessagesToLoadFromServer)
  470.     if success and messages.response then
  471.  
  472.         whatIsOnScreen = "messages"
  473.  
  474.         if currentMessagesPeerID > 2000000000 then
  475.             status("Загружаю имена пользователей из переписки (актуально для конференций)")
  476.  
  477.             local IDsArray = {};
  478.             for i = 1, #messages.response.items do table.insert(IDsArray, messages.response.items[i].user_id) end
  479.             local userNamesSuccess, userNames = getUserNamesFromTheirIDs(IDsArray)
  480.             for i = 1, #messages.response.items do
  481.                 messages.response.items[i].first_name = userNames[messages.response.items[i].user_id].first_name or "N/A"
  482.                 messages.response.items[i].last_name = userNames[messages.response.items[i].user_id].last_name or "N/A"
  483.             end
  484.             IDsArray = nil
  485.         end
  486.  
  487.         clearGUIZone()
  488.         drawTopBar("Сообщения")
  489.  
  490.         -- saveToFile("lastMessagesRequest.json", serialization.serialize(messages))
  491.  
  492.         buffer.setDrawLimit(mainZoneX, mainZoneY, mainZoneX + mainZoneWidth - 1, mainZoneY + mainZoneHeight - 1)
  493.  
  494.         local y = buffer.height - 7
  495.         local xSender = mainZoneX + 2
  496.         local xYou = buffer.width - 7
  497.  
  498.         for i = 1, #messages.response.items do
  499.  
  500.             local messageTextArray = {}
  501.  
  502.             --Если строка пиздатая
  503.             if messages.response.items[i].body ~= "" then table.insert(messageTextArray, optimizeStringForWrongSymbols(messages.response.items[i].body)) end
  504.             if messages.response.items[i].fwd_messages then table.insert(messageTextArray, "Пересланные сообщения") end
  505.             if messages.response.items[i].attachments then table.insert(messageTextArray, getAttachments(messages.response.items[i])) end
  506.             if messages.response.items[i].action == "chat_invite_user" then table.insert(messageTextArray, "Пользователь под ID " .. messages.response.items[i].from_id .. " пригласил в беседу пользователя под ID " .. messages.response.items[i].action_mid) end
  507.  
  508.             messageTextArray = string.wrap(messageTextArray, cloudWidth - 4)
  509.             local peerID = getPeerIDFromMessageArray(messages.response.items[i])
  510.  
  511.             --Делаем дату пиздатой
  512.             -- messages.response.items[i].date = os.date("%d.%m.%y в %X", messages.response.items[i].date)
  513.             messages.response.items[i].date = os.date("%H:%M", messages.response.items[i].date)
  514.  
  515.             if messages.response.items[i].out == 1 then
  516.                 y = drawTextCloud(xYou - cloudWidth - 6, y, colors.yourCloudColor, colors.yourCloudTextColor, true, messageTextArray)
  517.                 drawPersonalAvatar(xYou, y, 6, 3)
  518.                 buffer.text(xYou - cloudWidth - unicode.len(messages.response.items[i].date) - 8, y + 1, colors.dateTime, messages.response.items[i].date)
  519.             else
  520.                 y = drawTextCloud(xSender + 8, y, colors.senderCloudColor, colors.senderCloudTextColor, false, messageTextArray)
  521.                 drawAvatar(xSender, y, 6, 3, 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)
  522.                 buffer.text(xSender + cloudWidth + 14, y + 1, colors.dateTime, messages.response.items[i].date)
  523.             end
  524.  
  525.             y = y - 2
  526.         end
  527.  
  528.         local currentText
  529.  
  530.         -- Создаем объект тырканья
  531.         drawMessageInputBar()
  532.         status("История переписки загружена, ожидаю ввода сообщения")
  533.         buffer.resetDrawLimit()
  534.     end
  535. end
  536.  
  537. local function drawDialog(y, dialogBackground, avatarID, avatarText, text1, text2, text3)
  538.     --Рисуем подложку под диалог нужного цвета
  539.     buffer.square(mainZoneX, y, mainZoneWidth, 5, dialogBackground, 0x0, " ")
  540.     --Рисуем аватарку, чо уж
  541.     drawAvatar(mainZoneX + 2, y + 1, 6, 3, avatarID, avatarText)
  542.     --Пишем все, что нужно
  543.     y = y + 1
  544.     if text1 then buffer.text(mainZoneX + 10, y, 0x000000, text1); y = y + 1 end
  545.     if text2 then buffer.text(mainZoneX + 10, y, 0x555555, text2); y = y + 1 end
  546.     if text3 then buffer.text(mainZoneX + 10, y, 0x666666, text3); y = y + 1 end
  547. end
  548.  
  549. local function dialogsGUI()
  550.  
  551.     local success, dialogs = getDialogsRequest(dialogToShowFrom - 1, countOfDialogsToLoadFromServer)
  552.     if success and dialogs.response then
  553.        
  554.         whatIsOnScreen = "dialogs"
  555.  
  556.         obj.dialogList = {}
  557.  
  558.         clearGUIZone()
  559.         drawTopBar("Сообщения")
  560.  
  561.         --Ебашим КНОПАЧКИ спама
  562.         obj.crazyTypingButton = GUI.adaptiveButton(mainZoneX + 2, 2, 1, 0, 0xFFFFFF, colors.topBar, 0xAAAAAA, 0x000000, "CrazyTyping")
  563.         -- obj.spamButton = {buffer.adaptiveButton(obj.crazyTypingButton[3] + 2, 2, 1, 0, 0xFFFFFF, colors.topBar, "Спам")}
  564.  
  565.         --НУ ТЫ ПОНЯЛ, АГА
  566.         status("Получаю имена пользователей по ID")
  567.         local IDsArray = {}
  568.         for i = 1, #dialogs.response.items do
  569.             if not dialogs.response.items[i].message.chat_id and dialogs.response.items[i].message.user_id and dialogs.response.items[i].message.user_id > 0 then
  570.                 table.insert(IDsArray, dialogs.response.items[i].message.user_id)
  571.             end
  572.         end
  573.         local userNamesSuccess, userNames = getUserNamesFromTheirIDs(IDsArray)
  574.         for i = 1, #dialogs.response.items do
  575.             if not dialogs.response.items[i].message.chat_id and dialogs.response.items[i].message.user_id and dialogs.response.items[i].message.user_id > 0 then
  576.                 dialogs.response.items[i].message.title = userNames[dialogs.response.items[i].message.user_id].first_name or "N/A" .. " " .. userNames[dialogs.response.items[i].message.user_id].last_name or ""
  577.             end
  578.         end
  579.  
  580.         local y = mainZoneY
  581.         local avatarText = ""
  582.         local peerID
  583.         local color
  584.  
  585.         for i = 1, #dialogs.response.items do
  586.             --Ебемся с цветами
  587.             if dialogs.response.items[i].unread then
  588.                 if i % 2 == 0 then
  589.                     color = 0xCCDBFF
  590.                 else
  591.                     color = 0xCCDBFF
  592.                 end
  593.             else
  594.                 if i % 2 == 0 then
  595.                     color = 0xEEEEEE
  596.                 else
  597.                     color = 0xFFFFFF
  598.                 end
  599.             end
  600.            
  601.             avatarText = unicode.sub(dialogs.response.items[i].message.title, 1, 2)
  602.             peerID = getPeerIDFromMessageArray(dialogs.response.items[i].message)
  603.  
  604.             --Ебля с текстом диалога
  605.             local text1 = dialogs.response.items[i].message.title
  606.             local text2
  607.             local text3
  608.  
  609.             --Если это банальное сообщение
  610.             if dialogs.response.items[i].message.body and dialogs.response.items[i].message.body ~= "" then
  611.                 text2 = optimizeStringForWrongSymbols(dialogs.response.items[i].message.body)
  612.             end
  613.  
  614.             --Если есть какие-либо пересланные сообщения, то
  615.             if dialogs.response.items[i].message.fwd_messages then
  616.                 text3 = "Пересланные сообщения"
  617.             --Если есть какие-либо вложения, то
  618.             elseif dialogs.response.items[i].message.attachments then
  619.                 text3 = getAttachments(dialogs.response.items[i].message)
  620.             end
  621.  
  622.             --Рисуем диалог
  623.             drawDialog(y, color, peerID, avatarText, text1, text2, text3)
  624.  
  625.             --Рисуем пиздюлинку, показывающую кол-во непрочитанных сообщений
  626.             if dialogs.response.items[i].unread and dialogs.response.items[i].unread ~= 0 then
  627.                 local cyka = tostring(dialogs.response.items[i].unread)
  628.                 local cykaWidth = unicode.len(cyka) + 2
  629.                 local cykaX = buffer.width - cykaWidth - 2
  630.                 buffer.square(cykaX, y + 2, cykaWidth, 1, ecs.colors.blue, 0x0, " ")
  631.                 buffer.text(cykaX + 1, y + 2, 0xFFFFFF, cyka)
  632.             end
  633.  
  634.             obj.dialogList[i] = GUI.object(mainZoneX, y, mainZoneWidth, 5)
  635.             obj.dialogList[i][5], obj.dialogList[i][6], obj.dialogList[i][7], obj.dialogList[i][8], obj.dialogList[i][9] = peerID, avatarText, text1, text2, text3
  636.  
  637.             y = y + 5
  638.         end
  639.     end
  640.  
  641.     status("Список диалогов получен")
  642. end
  643.  
  644. --Гуишка аудиозаписей
  645. --А-А-А-А!!!!! МОЙ КРАСИВЫЙ ТРЕУГОЛЬНИЧЕК PLAY, БЛЯДЬ!!!! ШТО ТЫ ДЕЛАЕШЬ, SANGAR, ПРЕКРАТИ!!!!
  646. local function audioGUI(ID)
  647.     status("Загружаю список аудиозаписей")
  648.     local success, audios = getAudioRequest(ID, audioToShowFrom - 1, countOfAudioToLoadFromServer)
  649.     if success and audios.response then
  650.         whatIsOnScreen = "audio"
  651.         obj.audio = {}
  652.         clearGUIZone()
  653.         drawTopBar("Аудиозаписи " .. audios.response.items[1].name_gen)
  654.  
  655.         local y = mainZoneY
  656.         local color
  657.         for i = 2, #audios.response.items do
  658.             color = 0xFFFFFF
  659.             if i % 2 == 0 then color = 0xEEEEEE end
  660.  
  661.             buffer.square(mainZoneX, y, mainZoneWidth, 5, color, 0x0, " ")
  662.             obj.audio[i] = GUI.button(mainZoneX + 2, y + 1, 5, 3, colors.audioPlayButton, colors.audioPlayButtonText, 0x66FF80, colors.audioPlayButton, ">")
  663.             obj.audio[i][5] = audios.response.items[i]
  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, 0x888888, "Длительность: " .. hours .. ":" .. minutes .. ":" .. seconds)
  675.  
  676.             y = y + 5
  677.         end
  678.     else
  679.         GUI.error("Ошибка при получении списка аудиозаписей")
  680.     end
  681. end
  682.  
  683. local function checkField(field)
  684.     if field and field ~= "" and field ~= " " then return true end
  685.     return false
  686. end
  687.  
  688. local function userProfileRequest()
  689.     --Ебашим основную инфу
  690.     status("Загружаю информацию о пользователе под ID " .. currentProfile.ID)
  691.     local profileSuccess, userProfile = usersInformationRequest(currentProfile.ID)
  692.    
  693.     --Ебашим стену
  694.     status("Загружаю содержимое стены пользователя " .. currentProfile.ID)
  695.     local wallSuccess, wall = userWallRequest(currentProfile.ID, 20, currentProfile.wallOffset)
  696.     --Получаем инфу о юзверях со стены
  697.     local userNamesSuccess, userNames
  698.     if wallSuccess and wall.response then
  699.         local IDsArray = {}
  700.         for i = 1, #wall.response.items do table.insert(IDsArray, wall.response.items[i].from_id) end
  701.         status("Загружаю имена людей, оставивших сообщения на стене пользователя " .. currentProfile.ID)
  702.         userNamesSuccess, userNames = getUserNamesFromTheirIDs(IDsArray)
  703.         IDsArray = nil
  704.     end
  705.  
  706.     --Ебашим френдсов
  707.     status("Загружаю информацию о друзьях пользователя под ID " .. currentProfile.ID)
  708.     local friendsSuccess, friends = userFriendsRequest(currentProfile.ID, countOfFriendsToDisplayInProfile, 0, "random", "nom")
  709.  
  710.     --Анализируем на пиздатость
  711.     if (profileSuccess and userProfile.response) and (wallSuccess and wall.response) and (userNamesSuccess) and (friendsSuccess and friends.response) then
  712.         -- saveToFile("lastUserProfileRequest.json", serialization.serialize(userProfile))
  713.         currentProfile.userProfile = userProfile
  714.         currentProfile.wall = wall
  715.         currentProfile.userNames = userNames
  716.         currentProfile.friends = friends
  717.         return true
  718.     else
  719.         GUI.error("Ошибка при загрузке информации о профиле")
  720.         return false
  721.     end
  722. end
  723.  
  724. local function userProfileGUI()
  725.     clearGUIZone()
  726.     whatIsOnScreen = "userProfile"
  727.     drawTopBar("Страница пользователя " .. currentProfile.ID)
  728.  
  729.     buffer.setDrawLimit(mainZoneX, mainZoneY, mainZoneX + mainZoneWidth - 1, mainZoneY + mainZoneHeight - 1)
  730.  
  731.     local xAvatar, yAvatar = mainZoneX + 4, currentProfileY
  732.     local x, y = xAvatar, yAvatar
  733.     local avatarWidth = 18
  734.     local avatarHeight = math.floor(avatarWidth / 2)
  735.  
  736.     --Рисуем авку
  737.     currentProfile.avatarText =  unicode.sub(currentProfile.userProfile.response[1].first_name, 1, 1) .. unicode.sub(currentProfile.userProfile.response[1].last_name, 1, 1)
  738.     drawAvatar(x, y, avatarWidth, avatarHeight, currentProfile.ID, currentProfile.avatarText)
  739.     --Рисуем имячко и статус
  740.     x = x + avatarWidth + 4
  741.     buffer.text(x, y, 0x000000, currentProfile.userProfile.response[1].first_name .. " " .. currentProfile.userProfile.response[1].last_name); y = y + 1
  742.     buffer.text(x, y, 0xAAAAAA, currentProfile.userProfile.response[1].status); y = y + 2
  743.  
  744.     --Инфааааа
  745.     local informationOffset = 20
  746.     local informationKeyColor = 0x888888
  747.     local informationTitleColor = 0x000000
  748.     local informationValueColor = 0x002440
  749.     local informationSeparatorColor = 0xCCCCCC
  750.  
  751.     local function drawInfo(x, y2, key, value)
  752.         if checkField(value) then
  753.             value = {value}
  754.             value = string.wrap(value, buffer.width - x - 4 - informationOffset)
  755.             buffer.text(x, y2, informationKeyColor, key)
  756.             for i = 1, #value do
  757.                 buffer.text(x + informationOffset, y2, informationValueColor, value[i])
  758.                 y2 = y2 + 1
  759.             end
  760.             y = y2
  761.         end
  762.     end
  763.  
  764.     local function drawSeparator(x, y2, text)
  765.         buffer.text(x, y2, informationTitleColor, text)
  766.         buffer.text(x + unicode.len(text) + 1, y2, informationSeparatorColor, string.rep("─", buffer.width - x - unicode.len(text)))
  767.         y = y + 1
  768.     end
  769.  
  770.     drawSeparator(x, y, "Основная информация"); y = y + 1
  771.  
  772.     drawInfo(x, y, "Дата рождения:", currentProfile.userProfile.response[1].bdate)
  773.     if currentProfile.userProfile.response[1].city then drawInfo(x, y, "Город:", currentProfile.userProfile.response[1].city.title) end
  774.     drawInfo(x, y, "Образование:", currentProfile.userProfile.response[1].university_name)
  775.     drawInfo(x, y, "Веб-сайт", currentProfile.userProfile.response[1].site); y = y + 1
  776.  
  777.     drawSeparator(x, y, "Контактная информация"); y = y + 1
  778.  
  779.     drawInfo(x, y, "Мобильный телефон:", currentProfile.userProfile.response[1].mobile_phone)
  780.     drawInfo(x, y, "Домашний телефон:", currentProfile.userProfile.response[1].home_phone)
  781.     drawInfo(x, y, "Skype:", currentProfile.userProfile.response[1].skype); y = y + 1
  782.  
  783.     drawSeparator(x, y, "Личная информация"); y = y + 1
  784.  
  785.     drawInfo(x, y, "Интересы:", currentProfile.userProfile.response[1].interests)
  786.     drawInfo(x, y, "Деятельность:", currentProfile.userProfile.response[1].activities)
  787.     drawInfo(x, y, "Любимая музыка:", currentProfile.userProfile.response[1].music)
  788.     drawInfo(x, y, "Любимая фильмы:", currentProfile.userProfile.response[1].movies)
  789.     drawInfo(x, y, "Любимая телешоу:", currentProfile.userProfile.response[1].tv)
  790.     drawInfo(x, y, "Любимая книги:", currentProfile.userProfile.response[1].books)
  791.     drawInfo(x, y, "Любимая игры:", currentProfile.userProfile.response[1].games)
  792.     drawInfo(x, y, "О себе:", currentProfile.userProfile.response[1].about)
  793.  
  794.     -- А ВОТ И СТЕНОЧКА ПОДЪЕХАЛА НА ПРАЗДНИК ДУШИ
  795.     y = y + 1
  796.     buffer.square(x, y, buffer.width - x - 2, 1, 0xCCCCCC, 0x0, " "); buffer.text(x + 1, y, 0x262626, "Стена"); y = y + 2
  797.     --Перебираем всю стенку
  798.     for i = 1, #currentProfile.wall.response.items do
  799.         --Если это не репост или еще не хуйня какая-то
  800.         if currentProfile.wall.response.items[i].text ~= "" then
  801.             -- GUI.error(userNames)
  802.             drawAvatar(x, y, 6, 3, currentProfile.wall.response.items[i].from_id, unicode.sub(currentProfile.userNames[currentProfile.wall.response.items[i].from_id].first_name, 1, 1) .. unicode.sub(currentProfile.userNames[currentProfile.wall.response.items[i].from_id].last_name, 1, 1))
  803.             buffer.text(x + 8, y, informationValueColor, currentProfile.userNames[currentProfile.wall.response.items[i].from_id].first_name .. " " .. currentProfile.userNames[currentProfile.wall.response.items[i].from_id].last_name)
  804.             local date = os.date("%d.%m.%y в %H:%M", currentProfile.wall.response.items[i].date)
  805.             buffer.text(buffer.width - unicode.len(date) - 2, y, 0xCCCCCC, date)
  806.             y = y + 1
  807.             local text = {currentProfile.wall.response.items[i].text}
  808.             text = string.wrap(text, buffer.width - x - 10)
  809.             for i = 1, #text do
  810.                 buffer.text(x + 8, y, 0x000000, text[i])
  811.                 y = y + 1
  812.             end
  813.             y = y + 1
  814.             if #text == 1 then y = y + 1 end
  815.         end
  816.     end
  817.  
  818.     --ПодАвочная параша
  819.     informationOffset = 13
  820.     x, y = xAvatar, yAvatar
  821.     y = y + avatarHeight + 1
  822.  
  823.     currentProfile.avatarWidth = avatarWidth
  824.     currentProfile.sendMessageButton = GUI.button(x, y, avatarWidth, 1, 0xCCCCCC, 0x000000, 0x888888, 0x000000,"Сообщение")
  825.     y = y + 2
  826.     currentProfile.audiosButton = GUI.button(x, y, avatarWidth, 1, 0xCCCCCC, 0x000000, 0x888888, 0x000000, "Аудиозаписи")
  827.     y = y + 2
  828.  
  829.     drawInfo(x, y, "Подписчики: ", currentProfile.userProfile.response[1].counters.followers)
  830.     drawInfo(x, y, "Фотографии: ", currentProfile.userProfile.response[1].counters.photos)
  831.     drawInfo(x, y, "Видеозаписи: ", currentProfile.userProfile.response[1].counters.videos)
  832.     drawInfo(x, y, "Аудиозаписи: ", currentProfile.userProfile.response[1].counters.audios)
  833.  
  834.     --Друзяшки, ЕПТАААААА, АХАХАХАХАХАХАХАХАХА     
  835.     y = y + 1
  836.     buffer.square(x, y, avatarWidth, 1, 0xCCCCCC, 0x0, " "); buffer.text(x + 1, y, 0x262626, "Друзья (" .. currentProfile.userProfile.response[1].counters.friends .. ")"); y = y + 2
  837.     local xPos, yPos = x + 1, y
  838.     local count = 1
  839.     for i = 1, #currentProfile.friends.response.items do
  840.         drawAvatar(xPos, yPos, 6, 3, currentProfile.friends.response.items[i].id, unicode.sub(currentProfile.friends.response.items[i].first_name, 1, 1) .. unicode.sub(currentProfile.friends.response.items[i].last_name, 1, 1))
  841.         buffer.text(xPos - 1, yPos + 3, 0x000000, ecs.stringLimit("end", currentProfile.friends.response.items[i].first_name .. " " .. currentProfile.friends.response.items[i].last_name, 8))
  842.         xPos = xPos + 10
  843.         if i % 2 == 0 then xPos = x + 1; yPos = yPos + 5 end
  844.         count = count + 1
  845.         if count > countOfFriendsToDisplayInProfile then break end
  846.     end
  847.  
  848.     buffer.resetDrawLimit()
  849. end
  850.  
  851. local function loadAndShowProfile(ID)
  852.     currentProfileY = mainZoneY + 2
  853.     currentProfile = {ID = ID, wallOffset = 0}
  854.     if userProfileRequest() then userProfileGUI(currentProfile.ID) end
  855. end
  856.  
  857. local function friendsGUI()
  858.     status("Загружаю список друзей")
  859.     local success, friends = userFriendsRequest(personalInfo.id, countOfFriendsToGetOnFriendsTab, currentFriendsOffset, "hints", "nom")
  860.     status("Загружаю список категорий друзей")
  861.     local successLists, friendsLists = userFriendsListsRequest(personalInfo.id)
  862.     if (success and friends.response) and (successLists and friendsLists.response) then
  863.         -- saveToFile("lastFriendsResponse.json", serialization.serialize(friends))
  864.         clearGUIZone()
  865.         currentFriends = {sendMessageButtons = {}, openProfileButtons = {}}
  866.         whatIsOnScreen = "friends"
  867.         drawTopBar("Друзья")
  868.         buffer.setDrawLimit(mainZoneX, mainZoneY, mainZoneX + mainZoneWidth - 1, mainZoneY + mainZoneHeight - 1)
  869.  
  870.         local function getListName(listID)
  871.             local name = "N/A"
  872.             for i = 1, #friendsLists.response.items do
  873.                 if friendsLists.response.items[i].id == listID then
  874.                     name = friendsLists.response.items[i].name
  875.                     break
  876.                 end
  877.             end
  878.             return name
  879.         end
  880.  
  881.         local x, y = mainZoneX + 2, mainZoneY
  882.         for i = 1, #friends.response.items do
  883.             --Падложка
  884.             if i % 2 == 0 then buffer.square(mainZoneX, y, mainZoneWidth, 5 + (friends.response.items[i].lists and 1 or 0), 0xEEEEEE, 0x0, " ") end
  885.             --Юзер
  886.             y = y + 1
  887.             local subbedName = unicode.sub(friends.response.items[i].first_name, 1, 1) .. unicode.sub(friends.response.items[i].last_name, 1, 1)
  888.             drawAvatar(x, y, 6, 3, friends.response.items[i].id, subbedName)
  889.             local text = friends.response.items[i].first_name .. " " .. friends.response.items[i].last_name
  890.             buffer.text(x + 8, y, colors.topBar, text)
  891.             local text2 = friends.response.items[i].last_seen and (", " .. (friends.response.items[i].online == 1 and "онлайн" or "был(а) в сети " .. os.date("%d.%m.%y в %H:%M", friends.response.items[i].last_seen.time))) or " "
  892.             buffer.text(x + 8 + unicode.len(text), y, 0xAAAAAA, text2)
  893.  
  894.             if friends.response.items[i].lists then
  895.                 y = y + 1
  896.                 local cykaX = x + 8
  897.                 for listID = 1, #friends.response.items[i].lists do
  898.                     local listName = getListName(friends.response.items[i].lists[listID])
  899.                     local listWidth = unicode.len(listName) + 2
  900.                     local listBackColor = math.floor(0xFFFFFF / friends.response.items[i].lists[listID])
  901.                     local listTextColor = (listBackColor > 0x7FFFFF and 0x000000 or 0xFFFFFF)
  902.                     buffer.square(cykaX, y, listWidth, 1, listBackColor, listTextColor, " ")
  903.                     buffer.text(cykaX + 1, y, listTextColor, listName)
  904.                     cykaX = cykaX + listWidth + 2
  905.                 end
  906.             end
  907.  
  908.             y = y + 1
  909.             buffer.text(x + 8, y, 0x999999, "Написать сообщение")
  910.             currentFriends.sendMessageButtons[friends.response.items[i].id] = {x + 8, y, x + 18, y, subbedName}
  911.             y = y + 1
  912.             buffer.text(x + 8, y, 0x999999, "Открыть профиль")
  913.             currentFriends.openProfileButtons[friends.response.items[i].id] = {x + 8, y, x + 18, y, subbedName}
  914.  
  915.             y = y + 2
  916.         end
  917.  
  918.         buffer.resetDrawLimit()
  919.     else
  920.         GUI.error("Ошибка при получении списка друзей пользователя")
  921.     end
  922. end
  923.  
  924. local function newsGUI()
  925.     clearGUIZone()
  926.     drawTopBar("Новости")
  927.     whatIsOnScreen = "news"
  928.     buffer.setDrawLimit(mainZoneX, mainZoneY, mainZoneX + mainZoneWidth - 1, mainZoneY + mainZoneHeight - 1)
  929.  
  930.     local function getAvatarTextAndNameForNews(source_id)
  931.         local avatarText, name = "N/A", "N/A"
  932.         if source_id < 0 then
  933.             for i = 1, #news.response.groups do
  934.                 if news.response.groups[i].id == math.abs(source_id) then
  935.                     avatarText = unicode.sub(news.response.groups[i].name, 1, 2)
  936.                     name = news.response.groups[i].name
  937.                     break
  938.                 end
  939.             end
  940.         else
  941.             for i = 1, #news.response.profiles do
  942.                 if news.response.profiles[i].id == source_id then
  943.                     avatarText = unicode.sub(news.response.profiles[i].first_name, 1, 1) .. unicode.sub(news.response.profiles[i].last_name, 1, 1)
  944.                     name = news.response.profiles[i].first_name .. " " .. news.response.profiles[i].last_name
  945.                     break
  946.                 end
  947.             end
  948.         end
  949.         return avatarText, name
  950.     end
  951.  
  952.     local x, y = mainZoneX + 2, mainZoneY
  953.     for item = currentNews, currentNews + countOfNewsToShow do
  954.         if news.response.items[item] then
  955.             --Делаем текст пиздатым
  956.             news.response.items[item].text = optimizeStringForWrongSymbols(news.response.items[item].text)
  957.             --Убираем говно из новостей
  958.             if news.response.items[item].text == "" then
  959.                 if news.response.items[item].copy_history then
  960.                     news.response.items[item].text = "Репост"
  961.                 elseif news.response.items[item].attachments then
  962.                      news.response.items[item].text = getAttachments(news.response.items[item])
  963.                 end
  964.             end
  965.             --Делаем его еще пизже
  966.             local text = {news.response.items[item].text}; text = string.wrap(text, buffer.width - x - 10)
  967.             --Получаем инфу нужную
  968.             local avatarText, name = getAvatarTextAndNameForNews(news.response.items[item].source_id)
  969.             --Сместиться потом на стока вот
  970.             local yShift = 5
  971.             if #text > 2 then yShift = yShift + #text - 2 end
  972.            
  973.             --Рисуем авку и название хуйни
  974.             if item % 2 == 0 then buffer.square(mainZoneX, y, mainZoneWidth, yShift, 0xEEEEEE, 0x0, " ") end
  975.             drawAvatar(x, y + 1, 6, 3, math.abs(news.response.items[item].source_id), avatarText)
  976.             buffer.text(x + 7, y + 1, colors.topBar, name)
  977.             --Рисуем текст
  978.             for line = 1, #text do
  979.                 buffer.text(x + 7, y + line + 1, 0x000000, text[line])
  980.             end
  981.  
  982.             y = y + yShift
  983.         end
  984.     end
  985.  
  986.     buffer.resetDrawLimit()
  987. end
  988.  
  989. local function getAndShowNews()
  990.     status("Загружаю список новостей")
  991.     local success, news1 = newsRequest(countOfNewsToGet)
  992.     if success and news1.response then
  993.         news = news1
  994.         currentNews = 1
  995.         newsGUI()
  996.     else
  997.         GUI.error("Ошибка при получении списка новостей")
  998.     end
  999. end
  1000.  
  1001. local function drawLeftBar()
  1002.     --Подложка под элементы
  1003.     buffer.square(1, 1, leftBarWidth, buffer.height, colors.leftBar, 0xFFFFFF, " ")
  1004.    
  1005.     if personalInfo then
  1006.         drawPersonalAvatar(3, 2, 6, 3)
  1007.         buffer.text(11, 3, 0xFFFFFF, ecs.stringLimit("end", personalInfo.first_name .. " " .. personalInfo.last_name, leftBarWidth - 11))
  1008.     end
  1009.  
  1010.     --Элементы
  1011.     obj.leftBar = {}
  1012.     local y, color = 6
  1013.     for i = 1, #leftBarElements do
  1014.         color = colors.leftBarAlternative
  1015.         if i % 2 == 0 then color = colors.leftBar end
  1016.         if i == currentLeftBarElement then color = colors.leftBarSelection end
  1017.  
  1018.         newObj("leftBar", i, 1, y, leftBarWidth, y + 2)
  1019.  
  1020.         buffer.square(1, y, leftBarWidth, 3, color, 0xFFFFFF, " ")
  1021.         y = y + 1
  1022.         buffer.text(3, y, colors.leftBarText, ecs.stringLimit("end", leftBarElements[i], leftBarWidth - 4))
  1023.         y = y + 2
  1024.     end
  1025. end
  1026.  
  1027. --Главное ГУИ с левтбаром и прочим
  1028. local function mainGUI()
  1029.     drawLeftBar()
  1030.     --Отображаем гую нужную выбранную
  1031.     if leftBarElements[currentLeftBarElement] == "Сообщения" then
  1032.         status("Получаю список диалогов")
  1033.         messageToShowFrom = 1
  1034.         dialogToShowFrom = 1
  1035.         dialogsGUI()
  1036.     elseif leftBarElements[currentLeftBarElement] == "Аудиозаписи" then
  1037.         status("Получаю список аудозаписей")
  1038.         audioToShowFrom = 1
  1039.         audioGUI(personalInfo.id)
  1040.     elseif leftBarElements[currentLeftBarElement] == "Моя страница" then
  1041.         loadAndShowProfile(personalInfo.id)
  1042.         -- loadAndShowProfile(186860159)
  1043.     elseif leftBarElements[currentLeftBarElement] == "Друзья" then
  1044.         friendsGUI()
  1045.     elseif leftBarElements[currentLeftBarElement] == "Новости" then
  1046.         getAndShowNews()
  1047.     end
  1048.  
  1049.     buffer.draw()
  1050. end
  1051.  
  1052. local function spam(id)
  1053.     while true do
  1054.         local randomMessages = {
  1055.             "Ты мое золотце",
  1056.             "Ты никогда не сделаешь сайт",
  1057.             "Ты ничтожество",
  1058.             "Твоя жизнь ничего не значит",
  1059.             "Ты ничего не добьешься",
  1060.             "Ты завалишь экзамены",
  1061.             "Ты никому не нужна",
  1062.             "Ты не напишешь курсовую",
  1063.             "Твое животное помрет завтра",
  1064.             "Не добавляй в ЧС!",
  1065.             "Передаем привет от Яши и Меня (а кто я?)",
  1066.             "Хуй!",
  1067.             "Пизда!",
  1068.             "Залупа!",
  1069.             "Пенис!",
  1070.             "Хер!",
  1071.             "Давалка!"
  1072.         }
  1073.         local text = randomMessages[math.random(1, #randomMessages)] .. " (с любовью, отправлено с OpenComputers)"
  1074.         sendMessageRequest(tostring(id), text)
  1075.         print("Отправляю сообщение: " .. text)
  1076.         os.sleep(2)
  1077.     end
  1078. end
  1079.  
  1080.  
  1081. ---------------------------------------------------- Старт скрипта ----------------------------------------------------------------
  1082.  
  1083. --Инициализируем библиотеку двойного буффера
  1084. --Эх, что бы я делал, если б не накодил ее? 0.2 фпс на GPU мертвеца!
  1085. buffer.start()
  1086. --Хуярим настррррроечки
  1087. loadSettings()
  1088. --Активируем форму логина
  1089. local loginData = loginGUI(settings.username, settings.password)
  1090. access_token = loginData.access_token
  1091. --Получаем персональные данные
  1092. _, personalInfo = usersInformationRequest(loginData.user_id)
  1093. personalInfo = personalInfo.response[1]
  1094.  
  1095. -- --Ебемся в попчанский
  1096. -- spam(21321257)
  1097.  
  1098. --Активируем главное GUI
  1099. clearGUIZone()
  1100. mainGUI()
  1101.  
  1102. while true do
  1103.     local e = {event.pull()}
  1104.     if e[1] == "touch" then
  1105.  
  1106.         if whatIsOnScreen == "audio" then
  1107.             for key in pairs(obj.audio) do
  1108.                 if obj.audio[key]:isClicked(e[3], e[4]) then
  1109.                     obj.audio[key]:press(0.2)
  1110.  
  1111.                     if component.isAvailable("openfm_radio") then
  1112.                         component.openfm_radio.stop()
  1113.                         component.openfm_radio.setURL(obj.audio[key][5].url)
  1114.                         component.openfm_radio.start()
  1115.                         status("Вывожу в статус играемую музыку")
  1116.                         setCurrentAudioPlaying(currentProfile and currentProfile.ID or personalInfo.id, obj.audio[key][5].id)
  1117.                     else
  1118.                         GUI.error("Эта функция доступна только при наличии установленного мода OpenFM, добавляющего полноценное интернет-радио")
  1119.                     end
  1120.  
  1121.                     break
  1122.                 end
  1123.             end
  1124.         end
  1125.  
  1126.         if whatIsOnScreen == "dialogs" then
  1127.             for key in pairs(obj.dialogList) do
  1128.                 if obj.dialogList[key]:isClicked(e[3], e[4]) then
  1129.                     drawDialog(obj.dialogList[key].y, 0xFF8888, obj.dialogList[key][5], obj.dialogList[key][6], obj.dialogList[key][7], obj.dialogList[key][8], obj.dialogList[key][9])
  1130.                     buffer.draw()
  1131.                     os.sleep(0.2)
  1132.                     status("Загружаю переписку с пользователем " .. obj.dialogList[key][7])
  1133.                     currentMessagesPeerID = obj.dialogList[key][5]
  1134.                     currentMessagesAvatarText = obj.dialogList[key][6]
  1135.                     messagesGUI()
  1136.                     break
  1137.                 end
  1138.             end
  1139.  
  1140.             if obj.crazyTypingButton:isClicked(e[3], e[4]) then
  1141.                 obj.crazyTypingButton:press(0.2)
  1142.                 local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
  1143.                     {"EmptyLine"},
  1144.                     {"CenterText", ecs.colors.orange, "CrazyTyping"},
  1145.                     {"EmptyLine"},
  1146.                     {"Slider", 0xFFFFFF, ecs.colors.orange, 1, 15, 5, "Количество диалогов: ", ""},
  1147.                     {"Slider", 0xFFFFFF, ecs.colors.orange, 1, 100, 5, "Количество запросов: ", ""},
  1148.                     {"Slider", 0xFFFFFF, ecs.colors.orange, 1, 5000, 500, "Задержка между запросами: ", " мс"},
  1149.                     {"EmptyLine"},
  1150.                     {"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
  1151.                 )
  1152.                 if data[4] == "OK" then
  1153.                     for i = 1, data[2] do
  1154.                         local count = 1
  1155.                         for key in pairs(obj.dialogList) do
  1156.                             -- GUI.error("Ебашу спам диалогу под пиром: " .. obj.dialogList[key][5])
  1157.                             ecs.info("auto", "auto", "CrazyTyping", "Запрос: " .. i ..  " из " .. data[2] ..  ", диалог: " .. count .. " из ".. data[1] .. ", peerID: " .. obj.dialogList[key][5])
  1158.                             setCrazyTypingRequest(obj.dialogList[key][5])
  1159.                             count = count + 1
  1160.                             if count > data[1] then break end
  1161.                             os.sleep(data[3] / 1000)
  1162.                         end
  1163.                     end
  1164.                     buffer.draw(true)
  1165.                 end
  1166.             end
  1167.         end
  1168.  
  1169.         if whatIsOnScreen == "messages" then
  1170.             if obj.messageInputBar:isClicked(e[3], e[4]) then
  1171.                 obj.messageInputBar.eventHandler({draw = function() obj.messageInputBar:draw() end}, obj.messageInputBar, {[1] = "touch", [3] = obj.messageInputBar.x, [4] = obj.messageInputBar.y})
  1172.                 local newText = obj.messageInputBar.text
  1173.                 if newText and newText ~= " " and newText ~= "" then
  1174.                     computer.beep(1700)
  1175.                     status("Отправляю сообщение пользователю")
  1176.                     sendMessageRequest(currentMessagesPeerID, newText .. (settings.addSendingInfo and messageEndAdderText or ""))
  1177.                     status("Обновляю историю переписки")
  1178.                     messageToShowFrom = 1
  1179.                     messagesGUI()
  1180.                 end
  1181.                 drawMessageInputBar()
  1182.             end
  1183.         end
  1184.  
  1185.         if whatIsOnScreen == "userProfile" then
  1186.             if currentProfile.audiosButton:isClicked(e[3], e[4]) then
  1187.                 currentProfile.audiosButton:press(0.2)
  1188.                 audioToShowFrom = 1
  1189.                 audioGUI(currentProfile.ID)
  1190.                 buffer.draw()
  1191.             elseif currentProfile.sendMessageButton:isClicked(e[3], e[4]) then
  1192.                 currentProfile.sendMessageButton:press(0.2)
  1193.                 currentMessagesPeerID = currentProfile.ID
  1194.                 messageToShowFrom = 1
  1195.                 currentMessagesAvatarText = currentProfile.avatarText
  1196.                 messagesGUI()
  1197.             end
  1198.         end
  1199.  
  1200.         if whatIsOnScreen == "friends" then
  1201.             for ID in pairs(currentFriends.sendMessageButtons) do
  1202.                 if clickedAtZone(e[3], e[4], currentFriends.sendMessageButtons[ID]) then
  1203.                     buffer.text(currentFriends.sendMessageButtons[ID][1], currentFriends.sendMessageButtons[ID][2], 0x000000, "Написать сообщение")
  1204.                     buffer.draw()
  1205.                     currentMessagesPeerID = ID
  1206.                     messageToShowFrom = 1
  1207.                     currentMessagesAvatarText = currentFriends.sendMessageButtons[ID][5]
  1208.                     messagesGUI()
  1209.                     break
  1210.                 end
  1211.             end
  1212.  
  1213.             for ID in pairs(currentFriends.openProfileButtons) do
  1214.                 if clickedAtZone(e[3], e[4], currentFriends.openProfileButtons[ID]) then
  1215.                     buffer.text(currentFriends.openProfileButtons[ID][1], currentFriends.openProfileButtons[ID][2], 0x000000, "Открыть профиль")
  1216.                     buffer.draw()
  1217.                     loadAndShowProfile(ID)
  1218.                     buffer.draw()
  1219.                     break
  1220.                 end
  1221.             end
  1222.         end
  1223.  
  1224.         for key in pairs(obj.leftBar) do
  1225.             if clickedAtZone(e[3], e[4], obj.leftBar[key]) then
  1226.                 -- GUI.error("Кликнули на лефт бар ээлемент")
  1227.                 local oldLeftBarElement = currentLeftBarElement
  1228.                 currentLeftBarElement = key
  1229.  
  1230.                 drawLeftBar()
  1231.                 buffer.draw()
  1232.  
  1233.                 if leftBarElements[currentLeftBarElement] == "Выход" then
  1234.                     os.sleep(0.3)
  1235.                     buffer.clear(0x262626)
  1236.                     ecs.prepareToExit()
  1237.                     return
  1238.                 elseif leftBarElements[currentLeftBarElement] == "Аудиозаписи" then
  1239.                     currentProfile = currentProfile or {}
  1240.                     currentProfile.ID = personalInfo.id
  1241.                 elseif leftBarElements[currentLeftBarElement] == "Настройки" then
  1242.                     local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true,
  1243.                         {"EmptyLine"},
  1244.                         {"CenterText", ecs.colors.orange, "Настройки"},
  1245.                         {"EmptyLine"},
  1246.                         {"Switch", ecs.colors.orange, 0xffffff, 0xFFFFFF, "Сохранять данные авторизации", settings.saveAuthData},
  1247.                         {"EmptyLine"},
  1248.                         {"Switch", ecs.colors.orange, 0xffffff, 0xFFFFFF, "Добавлять приписку \"Отправлено с ...\"", settings.addSendingInfo},
  1249.                         {"EmptyLine"},
  1250.                         {"CenterText", ecs.colors.orange, "OpenComputers VK Client v4.0"},
  1251.                         {"EmptyLine"},
  1252.                         {"CenterText", ecs.colors.white, "Автор: Игорь Тимофеев, vk.com/id7799889"},
  1253.                         {"CenterText", ecs.colors.white, "Все права защищены, епта! Попробуй только спиздить!"},
  1254.                         {"EmptyLine"},
  1255.                         {"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}}
  1256.                     )
  1257.                     if data[3] == "OK" then
  1258.                         settings.saveAuthData = data[1]
  1259.                         settings.addSendingInfo = data[2]
  1260.  
  1261.                         if settings.saveAuthData then
  1262.                             settings.username = loginData.username
  1263.                             settings.password = loginData.password
  1264.                         else
  1265.                             settings.username = nil
  1266.                             settings.password = nil
  1267.                         end
  1268.                         saveSettings()
  1269.  
  1270.                         currentLeftBarElement = oldLeftBarElement
  1271.                     end
  1272.                 end
  1273.  
  1274.                 mainGUI()
  1275.                 break
  1276.             end
  1277.         end
  1278.     elseif e[1] == "scroll" then
  1279.         if e[5] == 1 then
  1280.             if whatIsOnScreen == "dialogs" then
  1281.                 dialogToShowFrom = dialogToShowFrom - dialogScrollSpeed
  1282.                 if dialogToShowFrom < 1 then dialogToShowFrom = 1 end
  1283.                 status("Прокручиваю диалоги, отправляю запрос на сервер")
  1284.                 dialogsGUI()
  1285.                 buffer.draw()
  1286.             elseif whatIsOnScreen == "messages" then
  1287.                 messageToShowFrom = messageToShowFrom + messagesScrollSpeed
  1288.                 status("Прокручиваю сообщения, отправляю запрос на сервер")
  1289.                 messagesGUI()
  1290.                 buffer.draw()
  1291.             elseif whatIsOnScreen == "audio" then
  1292.                 audioToShowFrom = audioToShowFrom - audioScrollSpeed
  1293.                 if audioToShowFrom < 1 then audioToShowFrom = 1 end
  1294.                 status("Прокручиваю аудозаписи, отправляю запрос на сервер")
  1295.                 audioGUI(currentProfile and currentProfile.ID or personalInfo.id)
  1296.                 buffer.draw()
  1297.             elseif whatIsOnScreen == "userProfile" then
  1298.                 currentProfileY = currentProfileY + profileScrollSpeed
  1299.                 if currentProfileY > mainZoneY + 2 then currentProfileY = mainZoneY + 2 end
  1300.                 userProfileGUI()
  1301.                 buffer.draw()
  1302.             elseif whatIsOnScreen == "friends" then
  1303.                 currentFriendsOffset = currentFriendsOffset - friendsScrollSpeed
  1304.                 if currentFriendsOffset < 0 then currentFriendsOffset = 0 end
  1305.                 friendsGUI()
  1306.                 buffer.draw()
  1307.             elseif whatIsOnScreen == "news" then
  1308.                 currentNews = currentNews - 1
  1309.                 if currentNews < 1 then currentNews = 1 end
  1310.                 newsGUI()
  1311.                 buffer.draw()
  1312.             end
  1313.         else
  1314.             if whatIsOnScreen == "dialogs" then
  1315.                 dialogToShowFrom = dialogToShowFrom + dialogScrollSpeed
  1316.                 status("Прокручиваю диалоги, отправляю запрос на сервер")
  1317.                 dialogsGUI()
  1318.                 buffer.draw()
  1319.             elseif whatIsOnScreen == "messages" then
  1320.                 messageToShowFrom = messageToShowFrom - messagesScrollSpeed
  1321.                 if messageToShowFrom < 1 then messageToShowFrom = 1 end
  1322.                 status("Прокручиваю сообщения, отправляю запрос на сервер")
  1323.                 messagesGUI()
  1324.                 buffer.draw()
  1325.             elseif whatIsOnScreen == "audio" then
  1326.                 audioToShowFrom = audioToShowFrom + audioScrollSpeed
  1327.                 status("Прокручиваю аудозаписи, отправляю запрос на сервер")
  1328.                 audioGUI(currentProfile and currentProfile.ID or personalInfo.id)
  1329.                 buffer.draw()
  1330.             elseif whatIsOnScreen == "userProfile" then
  1331.                 currentProfileY = currentProfileY - profileScrollSpeed
  1332.                 userProfileGUI()
  1333.                 buffer.draw()
  1334.             elseif whatIsOnScreen == "friends" then
  1335.                 currentFriendsOffset = currentFriendsOffset + friendsScrollSpeed
  1336.                 friendsGUI()
  1337.                 buffer.draw()
  1338.             elseif whatIsOnScreen == "news" then
  1339.                 currentNews = currentNews + 1
  1340.                 newsGUI()
  1341.                 buffer.draw()
  1342.             end
  1343.         end
  1344.     end
  1345. end
  1346.  
  1347. -- local success, dialogs = getDialogsRequest(0, 5)
  1348. -- saveToFile(serialization.serialize(dialogs))
  1349.  
  1350.  
  1351. -- sendMessageRequest(dialogs.response.items[2], "тестовое сообщение, отправлено через OpenComputers VK Client by Игорь, епта")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement