Advertisement
Guest User

VK.lua

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