Advertisement
Guest User

Untitled

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