Advertisement
Guest User

vcontact.lua

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