Advertisement
MazeTheme

OS

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