Advertisement
llzverll

vk

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