---------------------------------------------------- Библиотеки ---------------------------------------------------------------- local advancedLua = require("advancedLua") local json = require("json") local serialization = require("serialization") local event = require("event") local ecs = require("ECSAPI") local fs = require("filesystem") local buffer = require("doubleBuffering") local context = require("context") local image = require("image") local unicode = require("unicode") local component = require("component") local computer = require("computer") local GUI = require("GUI") local MineOSCore = require("MineOSCore") local MineOSPaths = require("MineOSPaths") ---------------------------------------------------- Константы ---------------------------------------------------------------- local VKAPIVersion = "5.52" local colors = { leftBar = 0x262626, leftBarAlternative = 0x383838, leftBarText = 0xFFFFFF, leftBarSelection = 0x00A8FF, leftBarSelectionText = 0xFFFFFF, scrollBar = 0xCCCCCC, scrollBarPipe = 0x666666, mainZone = 0xFFFFFF, senderCloudColor = 0x3392FF, senderCloudTextColor = 0xFFFFFF, yourCloudColor = 0x55BBFF, yourCloudTextColor = 0xFFFFFF, systemMessageColor = 0x555555, dateTime = 0x777777, loginGUIBackground = 0x002440, topBar = 0x002440, topBarText = 0xFFFFFF, statusBar = 0x1b1b1b, statusBarText = 0xAAAAAA, audioPlayButton = 0x002440, audioPlayButtonText = 0xFFFFFF, messageInputBarColor = 0xEEEEEE, messageInputBarTextBackgroundColor = 0xFFFFFF, messsageInputBarTextColor = 0x262626, } local leftBarHeight = buffer.getHeight() - 9 local leftBarWidth = math.floor(buffer.getWidth() * 0.20) local topBarHeight = 3 local mainZoneWidth = buffer.getWidth() - leftBarWidth local mainZoneHeight = buffer.getHeight() - topBarHeight - 1 local mainZoneX = leftBarWidth + 1 local mainZoneY = topBarHeight + 1 local cloudWidth = math.floor(mainZoneWidth * 0.7) ------------------------------------------------------------------------------------------------------------------------------- local settingsPath = MineOSPaths.applicationData .. "VK/Settings.cfg" local VKLogoImagePath = MineOSCore.getCurrentApplicationResourcesDirectory() .. "VKLogo.pic" -- local leftBarElements = {"Новости", "Друзья", "Сообщения", "Настройки", "Выход"} local leftBarElements = { "Моя страница", "Друзья", "Сообщения", "Аудиозаписи", "Новости", "Настройки", "Выход" } local currentLeftBarElement = 3 local personalInfo local access_token local whatIsOnScreen local countOfDialogsToLoadFromServer = 10 local countOfAudioToLoadFromServer = 10 local countOfMessagesToLoadFromServer = 10 local dialogToShowFrom = 1 local audioToShowFrom = 1 local messageToShowFrom = 1 local dialogScrollSpeed = 5 local audioScrollSpeed = 5 local messagesScrollSpeed = 5 local profileScrollSpeed = 2 local friendsScrollSpeed = 5 local countOfFriendsToGetOnFriendsTab = 12 local currentFriendsOffset = 0 local currentFriends = {} local countOfFriendsToDisplayInProfile = 16 local currentProfileY = mainZoneY + 2 local currentMessagesPeerID, currentMessagesAvatarText local dialogPreviewTextLimit = mainZoneWidth - 15 local currentProfile local settings = {saveAuthData = false, addSendingInfo = true} local vip = { [7799889] = {avatarColor = 0x000000, avatarTextColor = 0xCCCCCC, avatarBottomText = "DEV", avatarBottomTextColor = 0x1b1b1b}, [113499693] = {avatarColor = 0xFF99CC, avatarTextColor = 0x000000, avatarBottomText = "DEV", avatarBottomTextColor = 0xff6dbf}, [60991376] = {avatarColor = 0xEEEEEE, avatarTextColor = 0x000000, avatarBottomText = "DEV", avatarBottomTextColor = 0x555555}, } local messageEndAdderText = " (отправлено с MineOS VKClient)" local news local currentNews = 1 local countOfNewsToShow = 10 local countOfNewsToGet = 20 ---------------------------------------------------- Веб-часть ---------------------------------------------------------------- local function loadSettings() if fs.exists(settingsPath) then settings = table.fromFile(settingsPath) end end local function saveSettings() table.toFile(settingsPath, settings) end --Объекты local obj = {} local function newObj(class, name, ...) obj[class] = obj[class] or {} obj[class][name] = {...} end --Дебаг-функция на сохранение говна в файл, МАЛО ЛИ ЧО local function saveToFile(filename, stro4ka) local file = io.open(filename, "w") file:write(stro4ka) file:close() end --Банальный URL-запрос, декодирующийся через ЖУСОН в случае успеха, епты local function request(url) local success, response = ecs.internetRequest(url) if success then response = json:decode(response) end return success, response end --Отправляем запрос на авторизацию по логину и паролю local function getLoginDataRequest(username, password) local url = "https://oauth.vk.com/token?grant_type=password&client_id=3697615&client_secret=AlVXZFMUqyrnABp8ncuU&username=" .. username .. "&password=" .. password .. "&v=" .. VKAPIVersion return request(url) end --Запрос к методам VK API local function VKAPIRequest(method, ... ) local arguments = { ... } local stringArguments = "" local url = "https://api.vk.com/method/" .. method .. "?" .. table.concat(arguments, "&") .. "&access_token=" .. access_token .. "&v=" .. VKAPIVersion return request(url) end --Запрос на получение списка диалогов local function getDialogsRequest(fromDialog, count) return VKAPIRequest("messages.getDialogs", "offset=" .. fromDialog, "count=" .. count, "preview_length=" .. dialogPreviewTextLimit) end --Запрос на получение списка диалогов local function getMessagesRequest(peerID, fromMessage, count) return VKAPIRequest("messages.getHistory", "offset=" .. fromMessage, "count=" .. count, "peer_id=" .. peerID) end --Запрос на получение списка музычки local function getAudioRequest(id, fromAudio, count) return VKAPIRequest("audio.get", "offset=" .. fromAudio, "count=" .. count, "owner_id=" .. id, "need_user=1") end --Эта хуйня делает строку охуенной путем замены говна на конфетку local function optimizeStringForURLSending(code) if code then code = string.gsub(code, "([^%w ])", function (c) return string.format("%%%02X", string.byte(c)) end) code = string.gsub(code, " ", "+") end return code end local function optimizeStringForWrongSymbols(s) --Удаляем некорректные символы s = string.gsub(s, " ", " ") s = string.gsub(s, "\r\n", "\n") s = string.gsub(s, "\n", "") --Заменяем "широкие" двухпиксельные символы на знак вопроса local massiv = {} for i = 1, unicode.len(s) do massiv[i] = unicode.sub(s, i, i) if unicode.isWide(massiv[i]) then massiv[i] = "?" end end --Возвращаем оптимизрованную строку return table.concat(massiv) end local function convertIDtoPeerID(whatIsThisID, ID) if whatIsThisID == "user" then return ID elseif whatIsThisID == "chat" then return (2000000000 + ID) elseif whatIsThisID == "group" then return -ID end end local function getPeerIDFromMessageArray(messageArray) local peerID --Если это чат if messageArray.users_count then peerID = convertIDtoPeerID("chat", messageArray.chat_id) --Или если это диалог с группой какой-то elseif messageArray.user_id < 0 then peerID = convertIDtoPeerID("group", messageArray.user_id) --Или если просто какой-то сталкер-одиночка else peerID = convertIDtoPeerID("user", messageArray.user_id) end return peerID end --Запрос на отправку сообщения указанному пидору local function sendMessageRequest(peerID, message) --Делаем строчку не пидорской message = optimizeStringForURLSending(message) return VKAPIRequest("messages.send", "peer_id=" .. peerID, "message=" .. message) end local function usersInformationRequest(...) 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") end local function userFriendsRequest(ID, count, offset, order, nameCase) return VKAPIRequest("friends.get", "user_id=" .. ID, "count=" .. count, "offset=" .. offset, "order=" .. order, "name_case=" .. nameCase, "fields=domain,online,last_seen") end local function userFriendsListsRequest(ID) return VKAPIRequest("friends.getLists", "user_id=" .. ID, "return_system=1") end local function userWallRequest(ID, count, offset) return VKAPIRequest("wall.get", "owner_id=" .. ID, "count=" .. count, "offset=" .. offset) end local function setCurrentAudioPlaying(ownerID, audioID) return VKAPIRequest("audio.setBroadcast", "audio=" .. ownerID .. "_" .. audioID) end local function newsRequest(count) return VKAPIRequest("newsfeed.get", "filters=post", "return_banned=1", "max_photos=0", "count=" .. count, "fields=name,first_name,last_name") end local function setCrazyTypingRequest(peer_id) return VKAPIRequest("messages.setActivity", "type=typing", "peer_id=" .. peer_id) end ---------------------------------------------------- GUI-часть ---------------------------------------------------------------- local function createAvatarHashColor(hash) return math.abs(hash % 0xFFFFFF) end local function drawAvatar(x, y, width, height, user_id, text) local avatarColor = createAvatarHashColor(user_id) local textColor = avatarColor > 8388607 and 0x000000 or 0xFFFFFF --Хочу себе персональную авку, а то че за хуйня? if vip[user_id] then avatarColor = vip[user_id].avatarColor textColor = vip[user_id].avatarTextColor end buffer.square(x, y, width, height, avatarColor, textColor, " ") buffer.text(x + math.floor(width / 2) - math.floor(unicode.len(text) / 2), y + math.floor(height / 2), textColor, unicode.upper(text)) 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 end --Проверка клика в определенную область по "объекту". Кому на хуй вссалось ООП? local function clickedAtZone(x, y, zone) if x >= zone[1] and y >= zone[2] and x <= zone[3] and y <= zone[4] then return true end return false end --Интерфейс логина в аккаунт ВК, постараюсь сделать пографонистей --Хотя хах! Кого я обманываю, ага local function loginGUI(startUsername, startPassword) local background = 0x002440 local buttonColor = 0x666DFF local textColor = 0x262626 local username, password = startUsername, startPassword local textFieldWidth = 50 local textFieldHeight = 3 local x, y = math.floor(buffer.getWidth() / 2 - textFieldWidth / 2), math.floor(buffer.getHeight() / 2) local obj = {} obj.username = {x, y, x + textFieldWidth - 1, y + 2}; y = y + textFieldHeight + 1 obj.password = {x, y, x + textFieldWidth - 1, y + 2}; y = y + textFieldHeight + 1 obj.button = GUI.button(x, y, textFieldWidth, textFieldHeight, buttonColor, 0xEEEEEE, 0xEEEEEE, buttonColor, "Войти") local VKLogoImage = image.load(VKLogoImagePath) local loginTextBox = GUI.input(x, obj.username[2], textFieldWidth, 3, 0xEEEEEE, 0x777777, 0x777777, 0xEEEEEE, 0x262626, username, "E-Mail", false) loginTextBox.parent = { draw = function() loginTextBox:draw() end } loginTextBox.getFirstParent = function() return loginTextBox.parent end local passwordTextBox = GUI.input(x, obj.password[2], textFieldWidth, 3, 0xEEEEEE, 0x777777, 0x777777, 0xEEEEEE, 0x262626, password, "Password", false, "*") passwordTextBox.parent = { draw = function() passwordTextBox:draw() end } passwordTextBox.getFirstParent = function() return passwordTextBox.parent end local function draw() buffer.clear(colors.loginGUIBackground) buffer.image(x + 5, obj.username[2] - 15, VKLogoImage) loginTextBox:draw() passwordTextBox:draw() obj.button:draw() buffer.draw() end while true do draw() local e = {event.pull()} if e[1] == "touch" then if clickedAtZone(e[3], e[4], obj.username) then loginTextBox.eventHandler({draw = function() loginTextBox:draw() end}, loginTextBox, {[1] = "touch", [3] = loginTextBox.x, [4] = loginTextBox.y}) username = loginTextBox.text elseif clickedAtZone(e[3], e[4], obj.password) then passwordTextBox.eventHandler({draw = function() passwordTextBox:draw() end}, passwordTextBox, {[1] = "touch", [3] = passwordTextBox.x, [4] = passwordTextBox.y}) password = passwordTextBox.text elseif obj.button:isClicked(e[3], e[4]) then obj.button:press(0.2) draw() local success, loginData = getLoginDataRequest(username or "", password or "") if success then if settings.saveAuthData then settings.username = username; settings.password = password; saveSettings() end loginData.username = username loginData.password = password return loginData else GUI.error("Ошибка авторизации: " .. tostring(loginData)) end end end end end ---------------------------------------------------- GUI для взаимодействия с VK API ---------------------------------------------- local function drawPersonalAvatar(x, y, width, height) drawAvatar(x, y, width, height, personalInfo.id, unicode.sub(personalInfo.first_name, 1, 1) .. unicode.sub(personalInfo.last_name, 1, 1)) end local function status(text) buffer.square(mainZoneX, buffer.getHeight(), mainZoneWidth, 1, colors.statusBar, 0x0, " ") buffer.text(mainZoneX + 1, buffer.getHeight(), colors.statusBarText, text) buffer.draw() end local function drawTopBar(text) buffer.square(mainZoneX, 1, mainZoneWidth, 3, colors.topBar, 0x0, " ") local x = math.floor(mainZoneX + mainZoneWidth / 2 - unicode.len(text) / 2 - 1) buffer.text(x, 2, colors.topBarText, text) end --Рисуем главную зону local function clearGUIZone() buffer.square(mainZoneX, mainZoneY, mainZoneWidth, mainZoneHeight, colors.mainZone, 0x0, " ") end local function drawEmptyCloud(x, y, cloudWidth, cloudHeight, cloudColor, fromYou) local upperPixel = "▀" local lowerPixel = "▄" --Рисуем финтифлюшечки if not fromYou then buffer.set(x, y - cloudHeight + 2, colors.mainZone, cloudColor, upperPixel) buffer.set(x + 1, y - cloudHeight + 2, cloudColor, 0xFFFFFF, " ") x = x + 2 else buffer.set(x + cloudWidth + 3, y - cloudHeight + 2, colors.mainZone, cloudColor, upperPixel) buffer.set(x + cloudWidth + 2, y - cloudHeight + 2, cloudColor, 0xFFFFFF, " ") end --Заполняшечки buffer.square(x + 1, y - cloudHeight + 1, cloudWidth, cloudHeight, cloudColor, 0xFFFFFF, " ") buffer.square(x, y - cloudHeight + 2, cloudWidth + 2, cloudHeight - 2, cloudColor, 0xFFFFFF, " ") --Сгругленные краешки buffer.set(x, y - cloudHeight + 1, colors.mainZone, cloudColor, lowerPixel) buffer.set(x + cloudWidth + 1, y - cloudHeight + 1, colors.mainZone, cloudColor, lowerPixel) buffer.set(x, y, colors.mainZone, cloudColor, upperPixel) buffer.set(x + cloudWidth + 1, y, colors.mainZone, cloudColor, upperPixel) return y - cloudHeight + 1 end local function drawTextCloud(x, y, cloudColor, textColor, fromYou, text) local y = drawEmptyCloud(x, y, cloudWidth, #text + 2, cloudColor, fromYou) x = fromYou and x + 2 or x + 4 for i = 1, #text do buffer.text(x, y + i, textColor, text[i]) end return y end local function getAttachments(messageArray) local text = "Вложения: " for j = 1, #messageArray.attachments do if messageArray.attachments[j].type == "sticker" then text = text .. "стикер, " elseif messageArray.attachments[j].type == "photo" then text = text .. "фото, " elseif messageArray.attachments[j].type == "video" then text = text .. "видео, " elseif messageArray.attachments[j].type == "audio" then text = text .. "аудио, " elseif messageArray.attachments[j].type == "wall" then text = text .. "запись на стене, " end end text = unicode.sub(text, 1, -3) return text end local function drawMessageInputBar(currentText) local x, y = mainZoneX, buffer.getHeight() - 5 buffer.square(x, y, mainZoneWidth, 5, colors.messageInputBarColor, 0x0, " ") obj.messageInputBar = GUI.input(x + 2, y + 1, mainZoneWidth - 4, 3, 0xFFFFFF, 0x444444, 0x444444, 0xFFFFFF, 0x262626, nil, "Введите сообщение", true) obj.messageInputBar.parent = { draw = function() obj.messageInputBar:draw() end } obj.messageInputBar.getFirstParent = function() return obj.messageInputBar.parent end obj.messageInputBar:draw() end local function getUserNamesFromTheirIDs(IDsArray) local success, usersData = usersInformationRequest(table.unpack(IDsArray)) local userNames = {} if success and usersData.response then for i = 1, #usersData.response do userNames[usersData.response[i].id] = { first_name = usersData.response[i].first_name, last_name = usersData.response[i].last_name, } end end return success, userNames end local function messagesGUI() status("Загружаю историю переписки") local success, messages = getMessagesRequest(currentMessagesPeerID, messageToShowFrom - 1, countOfMessagesToLoadFromServer) if success and messages.response then whatIsOnScreen = "messages" if currentMessagesPeerID > 2000000000 then status("Загружаю имена пользователей из переписки (актуально для конференций)") local IDsArray = {}; for i = 1, #messages.response.items do table.insert(IDsArray, messages.response.items[i].user_id) end local userNamesSuccess, userNames = getUserNamesFromTheirIDs(IDsArray) for i = 1, #messages.response.items do messages.response.items[i].first_name = userNames[messages.response.items[i].user_id].first_name or "N/A" messages.response.items[i].last_name = userNames[messages.response.items[i].user_id].last_name or "N/A" end IDsArray = nil end clearGUIZone() drawTopBar("Сообщения") -- saveToFile("lastMessagesRequest.json", serialization.serialize(messages)) buffer.setDrawLimit(mainZoneX, mainZoneY, mainZoneX + mainZoneWidth - 1, mainZoneY + mainZoneHeight - 1) local y = buffer.getHeight() - 7 local xSender = mainZoneX + 2 local xYou = buffer.getWidth() - 7 for i = 1, #messages.response.items do local messageTextArray = {} --Если строка пиздатая if messages.response.items[i].body ~= "" then table.insert(messageTextArray, optimizeStringForWrongSymbols(messages.response.items[i].body)) end if messages.response.items[i].fwd_messages then table.insert(messageTextArray, "Пересланные сообщения") end if messages.response.items[i].attachments then table.insert(messageTextArray, getAttachments(messages.response.items[i])) end 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 messageTextArray = string.wrap(messageTextArray, cloudWidth - 4) local peerID = getPeerIDFromMessageArray(messages.response.items[i]) --Делаем дату пиздатой -- messages.response.items[i].date = os.date("%d.%m.%y в %X", messages.response.items[i].date) messages.response.items[i].date = os.date("%H:%M", messages.response.items[i].date) if messages.response.items[i].out == 1 then y = drawTextCloud(xYou - cloudWidth - 6, y, colors.yourCloudColor, colors.yourCloudTextColor, true, messageTextArray) drawPersonalAvatar(xYou, y, 6, 3) buffer.text(xYou - cloudWidth - unicode.len(messages.response.items[i].date) - 8, y + 1, colors.dateTime, messages.response.items[i].date) else y = drawTextCloud(xSender + 8, y, colors.senderCloudColor, colors.senderCloudTextColor, false, messageTextArray) 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) buffer.text(xSender + cloudWidth + 14, y + 1, colors.dateTime, messages.response.items[i].date) end y = y - 2 end local currentText -- Создаем объект тырканья drawMessageInputBar() status("История переписки загружена, ожидаю ввода сообщения") buffer.resetDrawLimit() end end local function drawDialog(y, dialogBackground, avatarID, avatarText, text1, text2, text3) --Рисуем подложку под диалог нужного цвета buffer.square(mainZoneX, y, mainZoneWidth, 5, dialogBackground, 0x0, " ") --Рисуем аватарку, чо уж drawAvatar(mainZoneX + 2, y + 1, 6, 3, avatarID, avatarText) --Пишем все, что нужно y = y + 1 if text1 then buffer.text(mainZoneX + 10, y, 0x000000, text1); y = y + 1 end if text2 then buffer.text(mainZoneX + 10, y, 0x555555, text2); y = y + 1 end if text3 then buffer.text(mainZoneX + 10, y, 0x666666, text3); y = y + 1 end end local function dialogsGUI() local success, dialogs = getDialogsRequest(dialogToShowFrom - 1, countOfDialogsToLoadFromServer) if success and dialogs.response then whatIsOnScreen = "dialogs" obj.dialogList = {} clearGUIZone() drawTopBar("Сообщения") --Ебашим КНОПАЧКИ спама obj.crazyTypingButton = GUI.adaptiveButton(mainZoneX + 2, 2, 1, 0, 0xFFFFFF, colors.topBar, 0xAAAAAA, 0x000000, "CrazyTyping") -- obj.spamButton = {buffer.adaptiveButton(obj.crazyTypingButton[3] + 2, 2, 1, 0, 0xFFFFFF, colors.topBar, "Спам")} --НУ ТЫ ПОНЯЛ, АГА status("Получаю имена пользователей по ID") local IDsArray = {} for i = 1, #dialogs.response.items do 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 table.insert(IDsArray, dialogs.response.items[i].message.user_id) end end local userNamesSuccess, userNames = getUserNamesFromTheirIDs(IDsArray) for i = 1, #dialogs.response.items do 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 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 "" end end local y = mainZoneY local avatarText = "" local peerID local color for i = 1, #dialogs.response.items do --Ебемся с цветами if dialogs.response.items[i].unread then if i % 2 == 0 then color = 0xCCDBFF else color = 0xCCDBFF end else if i % 2 == 0 then color = 0xEEEEEE else color = 0xFFFFFF end end avatarText = unicode.sub(dialogs.response.items[i].message.title, 1, 2) peerID = getPeerIDFromMessageArray(dialogs.response.items[i].message) --Ебля с текстом диалога local text1 = dialogs.response.items[i].message.title local text2 local text3 --Если это банальное сообщение if dialogs.response.items[i].message.body and dialogs.response.items[i].message.body ~= "" then text2 = optimizeStringForWrongSymbols(dialogs.response.items[i].message.body) end --Если есть какие-либо пересланные сообщения, то if dialogs.response.items[i].message.fwd_messages then text3 = "Пересланные сообщения" --Если есть какие-либо вложения, то elseif dialogs.response.items[i].message.attachments then text3 = getAttachments(dialogs.response.items[i].message) end --Рисуем диалог drawDialog(y, color, peerID, avatarText, text1, text2, text3) --Рисуем пиздюлинку, показывающую кол-во непрочитанных сообщений if dialogs.response.items[i].unread and dialogs.response.items[i].unread ~= 0 then local cyka = tostring(dialogs.response.items[i].unread) local cykaWidth = unicode.len(cyka) + 2 local cykaX = buffer.getWidth() - cykaWidth - 2 buffer.square(cykaX, y + 2, cykaWidth, 1, ecs.colors.blue, 0x0, " ") buffer.text(cykaX + 1, y + 2, 0xFFFFFF, cyka) end obj.dialogList[i] = GUI.object(mainZoneX, y, mainZoneWidth, 5) 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 y = y + 5 end end status("Список диалогов получен") end --Гуишка аудиозаписей --А-А-А-А!!!!! МОЙ КРАСИВЫЙ ТРЕУГОЛЬНИЧЕК PLAY, БЛЯДЬ!!!! ШТО ТЫ ДЕЛАЕШЬ, SANGAR, ПРЕКРАТИ!!!! local function audioGUI(ID) status("Загружаю список аудиозаписей") local success, audios = getAudioRequest(ID, audioToShowFrom - 1, countOfAudioToLoadFromServer) if success and audios.response then whatIsOnScreen = "audio" obj.audio = {} clearGUIZone() drawTopBar("Аудиозаписи " .. audios.response.items[1].name_gen) local y = mainZoneY local color for i = 2, #audios.response.items do color = 0xFFFFFF if i % 2 == 0 then color = 0xEEEEEE end buffer.square(mainZoneX, y, mainZoneWidth, 5, color, 0x0, " ") obj.audio[i] = GUI.button(mainZoneX + 2, y + 1, 5, 3, colors.audioPlayButton, colors.audioPlayButtonText, 0x66FF80, colors.audioPlayButton, ">") obj.audio[i][5] = audios.response.items[i] local x = mainZoneX + 9 buffer.text(x, y + 1, colors.audioPlayButton, audios.response.items[i].artist) x = x + unicode.len(audios.response.items[i].artist) buffer.text(x, y + 1, 0x000000, " - " .. audios.response.items[i].title) x = mainZoneX + 9 local hours = string.format("%02.f", math.floor(audios.response.items[i].duration / 3600)) local minutes = string.format("%02.f", math.floor(audios.response.items[i].duration / 60 - (hours * 60))) local seconds = string.format("%02.f", math.floor(audios.response.items[i].duration - hours * 3600 - minutes * 60)) buffer.text(x, y + 2, 0x888888, "Длительность: " .. hours .. ":" .. minutes .. ":" .. seconds) y = y + 5 end else GUI.error("Ошибка при получении списка аудиозаписей") end end local function checkField(field) if field and field ~= "" and field ~= " " then return true end return false end local function userProfileRequest() --Ебашим основную инфу status("Загружаю информацию о пользователе под ID " .. currentProfile.ID) local profileSuccess, userProfile = usersInformationRequest(currentProfile.ID) --Ебашим стену status("Загружаю содержимое стены пользователя " .. currentProfile.ID) local wallSuccess, wall = userWallRequest(currentProfile.ID, 20, currentProfile.wallOffset) --Получаем инфу о юзверях со стены local userNamesSuccess, userNames if wallSuccess and wall.response then local IDsArray = {} for i = 1, #wall.response.items do table.insert(IDsArray, wall.response.items[i].from_id) end status("Загружаю имена людей, оставивших сообщения на стене пользователя " .. currentProfile.ID) userNamesSuccess, userNames = getUserNamesFromTheirIDs(IDsArray) IDsArray = nil end --Ебашим френдсов status("Загружаю информацию о друзьях пользователя под ID " .. currentProfile.ID) local friendsSuccess, friends = userFriendsRequest(currentProfile.ID, countOfFriendsToDisplayInProfile, 0, "random", "nom") --Анализируем на пиздатость if (profileSuccess and userProfile.response) and (wallSuccess and wall.response) and (userNamesSuccess) and (friendsSuccess and friends.response) then -- saveToFile("lastUserProfileRequest.json", serialization.serialize(userProfile)) currentProfile.userProfile = userProfile currentProfile.wall = wall currentProfile.userNames = userNames currentProfile.friends = friends return true else GUI.error("Ошибка при загрузке информации о профиле") return false end end local function userProfileGUI() clearGUIZone() whatIsOnScreen = "userProfile" drawTopBar("Страница пользователя " .. currentProfile.ID) buffer.setDrawLimit(mainZoneX, mainZoneY, mainZoneX + mainZoneWidth - 1, mainZoneY + mainZoneHeight - 1) local xAvatar, yAvatar = mainZoneX + 4, currentProfileY local x, y = xAvatar, yAvatar local avatarWidth = 18 local avatarHeight = math.floor(avatarWidth / 2) --Рисуем авку currentProfile.avatarText = unicode.sub(currentProfile.userProfile.response[1].first_name, 1, 1) .. unicode.sub(currentProfile.userProfile.response[1].last_name, 1, 1) drawAvatar(x, y, avatarWidth, avatarHeight, currentProfile.ID, currentProfile.avatarText) --Рисуем имячко и статус x = x + avatarWidth + 4 buffer.text(x, y, 0x000000, currentProfile.userProfile.response[1].first_name .. " " .. currentProfile.userProfile.response[1].last_name); y = y + 1 buffer.text(x, y, 0xAAAAAA, currentProfile.userProfile.response[1].status); y = y + 2 --Инфааааа local informationOffset = 20 local informationKeyColor = 0x888888 local informationTitleColor = 0x000000 local informationValueColor = 0x002440 local informationSeparatorColor = 0xCCCCCC local function drawInfo(x, y2, key, value) if checkField(value) then value = {value} value = string.wrap(value, buffer.getWidth() - x - 4 - informationOffset) buffer.text(x, y2, informationKeyColor, key) for i = 1, #value do buffer.text(x + informationOffset, y2, informationValueColor, value[i]) y2 = y2 + 1 end y = y2 end end local function drawSeparator(x, y2, text) buffer.text(x, y2, informationTitleColor, text) buffer.text(x + unicode.len(text) + 1, y2, informationSeparatorColor, string.rep("─", buffer.getWidth() - x - unicode.len(text))) y = y + 1 end drawSeparator(x, y, "Основная информация"); y = y + 1 drawInfo(x, y, "Дата рождения:", currentProfile.userProfile.response[1].bdate) if currentProfile.userProfile.response[1].city then drawInfo(x, y, "Город:", currentProfile.userProfile.response[1].city.title) end drawInfo(x, y, "Образование:", currentProfile.userProfile.response[1].university_name) drawInfo(x, y, "Веб-сайт", currentProfile.userProfile.response[1].site); y = y + 1 drawSeparator(x, y, "Контактная информация"); y = y + 1 drawInfo(x, y, "Мобильный телефон:", currentProfile.userProfile.response[1].mobile_phone) drawInfo(x, y, "Домашний телефон:", currentProfile.userProfile.response[1].home_phone) drawInfo(x, y, "Skype:", currentProfile.userProfile.response[1].skype); y = y + 1 drawSeparator(x, y, "Личная информация"); y = y + 1 drawInfo(x, y, "Интересы:", currentProfile.userProfile.response[1].interests) drawInfo(x, y, "Деятельность:", currentProfile.userProfile.response[1].activities) drawInfo(x, y, "Любимая музыка:", currentProfile.userProfile.response[1].music) drawInfo(x, y, "Любимая фильмы:", currentProfile.userProfile.response[1].movies) drawInfo(x, y, "Любимая телешоу:", currentProfile.userProfile.response[1].tv) drawInfo(x, y, "Любимая книги:", currentProfile.userProfile.response[1].books) drawInfo(x, y, "Любимая игры:", currentProfile.userProfile.response[1].games) drawInfo(x, y, "О себе:", currentProfile.userProfile.response[1].about) -- А ВОТ И СТЕНОЧКА ПОДЪЕХАЛА НА ПРАЗДНИК ДУШИ y = y + 1 buffer.square(x, y, buffer.getWidth() - x - 2, 1, 0xCCCCCC, 0x0, " "); buffer.text(x + 1, y, 0x262626, "Стена"); y = y + 2 --Перебираем всю стенку for i = 1, #currentProfile.wall.response.items do --Если это не репост или еще не хуйня какая-то if currentProfile.wall.response.items[i].text ~= "" then -- GUI.error(userNames) 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)) 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) local date = os.date("%d.%m.%y в %H:%M", currentProfile.wall.response.items[i].date) buffer.text(buffer.getWidth() - unicode.len(date) - 2, y, 0xCCCCCC, date) y = y + 1 local text = {currentProfile.wall.response.items[i].text} text = string.wrap(text, buffer.getWidth() - x - 10) for i = 1, #text do buffer.text(x + 8, y, 0x000000, text[i]) y = y + 1 end y = y + 1 if #text == 1 then y = y + 1 end end end --ПодАвочная параша informationOffset = 13 x, y = xAvatar, yAvatar y = y + avatarHeight + 1 currentProfile.avatarWidth = avatarWidth currentProfile.sendMessageButton = GUI.button(x, y, avatarWidth, 1, 0xCCCCCC, 0x000000, 0x888888, 0x000000,"Сообщение") y = y + 2 currentProfile.audiosButton = GUI.button(x, y, avatarWidth, 1, 0xCCCCCC, 0x000000, 0x888888, 0x000000, "Аудиозаписи") y = y + 2 drawInfo(x, y, "Подписчики: ", tostring(currentProfile.userProfile.response[1].counters.followers)) drawInfo(x, y, "Фотографии: ", currentProfile.userProfile.response[1].counters.photos) drawInfo(x, y, "Видеозаписи: ", currentProfile.userProfile.response[1].counters.videos) drawInfo(x, y, "Аудиозаписи: ", currentProfile.userProfile.response[1].counters.audios) --Друзяшки, ЕПТАААААА, АХАХАХАХАХАХАХАХАХА y = y + 1 buffer.square(x, y, avatarWidth, 1, 0xCCCCCC, 0x0, " "); buffer.text(x + 1, y, 0x262626, "Друзья (" .. currentProfile.userProfile.response[1].counters.friends .. ")"); y = y + 2 local xPos, yPos = x + 1, y local count = 1 for i = 1, #currentProfile.friends.response.items do 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)) 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)) xPos = xPos + 10 if i % 2 == 0 then xPos = x + 1; yPos = yPos + 5 end count = count + 1 if count > countOfFriendsToDisplayInProfile then break end end buffer.resetDrawLimit() end local function loadAndShowProfile(ID) currentProfileY = mainZoneY + 2 currentProfile = {ID = ID, wallOffset = 0} if userProfileRequest() then userProfileGUI(currentProfile.ID) end end local function friendsGUI() status("Загружаю список друзей") local success, friends = userFriendsRequest(personalInfo.id, countOfFriendsToGetOnFriendsTab, currentFriendsOffset, "hints", "nom") status("Загружаю список категорий друзей") local successLists, friendsLists = userFriendsListsRequest(personalInfo.id) if (success and friends.response) and (successLists and friendsLists.response) then -- saveToFile("lastFriendsResponse.json", serialization.serialize(friends)) clearGUIZone() currentFriends = {sendMessageButtons = {}, openProfileButtons = {}} whatIsOnScreen = "friends" drawTopBar("Друзья") buffer.setDrawLimit(mainZoneX, mainZoneY, mainZoneX + mainZoneWidth - 1, mainZoneY + mainZoneHeight - 1) local function getListName(listID) local name = "N/A" for i = 1, #friendsLists.response.items do if friendsLists.response.items[i].id == listID then name = friendsLists.response.items[i].name break end end return name end local x, y = mainZoneX + 2, mainZoneY for i = 1, #friends.response.items do --Падложка if i % 2 == 0 then buffer.square(mainZoneX, y, mainZoneWidth, 5 + (friends.response.items[i].lists and 1 or 0), 0xEEEEEE, 0x0, " ") end --Юзер y = y + 1 local subbedName = unicode.sub(friends.response.items[i].first_name, 1, 1) .. unicode.sub(friends.response.items[i].last_name, 1, 1) drawAvatar(x, y, 6, 3, friends.response.items[i].id, subbedName) local text = friends.response.items[i].first_name .. " " .. friends.response.items[i].last_name buffer.text(x + 8, y, colors.topBar, text) 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 " " buffer.text(x + 8 + unicode.len(text), y, 0xAAAAAA, text2) if friends.response.items[i].lists then y = y + 1 local cykaX = x + 8 for listID = 1, #friends.response.items[i].lists do local listName = getListName(friends.response.items[i].lists[listID]) local listWidth = unicode.len(listName) + 2 local listBackColor = math.floor(0xFFFFFF / friends.response.items[i].lists[listID]) local listTextColor = (listBackColor > 0x7FFFFF and 0x000000 or 0xFFFFFF) buffer.square(cykaX, y, listWidth, 1, listBackColor, listTextColor, " ") buffer.text(cykaX + 1, y, listTextColor, listName) cykaX = cykaX + listWidth + 2 end end y = y + 1 buffer.text(x + 8, y, 0x999999, "Написать сообщение") currentFriends.sendMessageButtons[friends.response.items[i].id] = {x + 8, y, x + 18, y, subbedName} y = y + 1 buffer.text(x + 8, y, 0x999999, "Открыть профиль") currentFriends.openProfileButtons[friends.response.items[i].id] = {x + 8, y, x + 18, y, subbedName} y = y + 2 end buffer.resetDrawLimit() else GUI.error("Ошибка при получении списка друзей пользователя") end end local function newsGUI() clearGUIZone() drawTopBar("Новости") whatIsOnScreen = "news" buffer.setDrawLimit(mainZoneX, mainZoneY, mainZoneX + mainZoneWidth - 1, mainZoneY + mainZoneHeight - 1) local function getAvatarTextAndNameForNews(source_id) local avatarText, name = "N/A", "N/A" if source_id < 0 then for i = 1, #news.response.groups do if news.response.groups[i].id == math.abs(source_id) then avatarText = unicode.sub(news.response.groups[i].name, 1, 2) name = news.response.groups[i].name break end end else for i = 1, #news.response.profiles do if news.response.profiles[i].id == source_id then avatarText = unicode.sub(news.response.profiles[i].first_name, 1, 1) .. unicode.sub(news.response.profiles[i].last_name, 1, 1) name = news.response.profiles[i].first_name .. " " .. news.response.profiles[i].last_name break end end end return avatarText, name end local x, y = mainZoneX + 2, mainZoneY for item = currentNews, currentNews + countOfNewsToShow do if news.response.items[item] then --Делаем текст пиздатым news.response.items[item].text = optimizeStringForWrongSymbols(news.response.items[item].text) --Убираем говно из новостей if news.response.items[item].text == "" then if news.response.items[item].copy_history then news.response.items[item].text = "Репост" elseif news.response.items[item].attachments then news.response.items[item].text = getAttachments(news.response.items[item]) end end --Делаем его еще пизже local text = {news.response.items[item].text}; text = string.wrap(text, buffer.getWidth() - x - 10) --Получаем инфу нужную local avatarText, name = getAvatarTextAndNameForNews(news.response.items[item].source_id) --Сместиться потом на стока вот local yShift = 5 if #text > 2 then yShift = yShift + #text - 2 end --Рисуем авку и название хуйни if item % 2 == 0 then buffer.square(mainZoneX, y, mainZoneWidth, yShift, 0xEEEEEE, 0x0, " ") end drawAvatar(x, y + 1, 6, 3, math.abs(news.response.items[item].source_id), avatarText) buffer.text(x + 7, y + 1, colors.topBar, name) --Рисуем текст for line = 1, #text do buffer.text(x + 7, y + line + 1, 0x000000, text[line]) end y = y + yShift end end buffer.resetDrawLimit() end local function getAndShowNews() status("Загружаю список новостей") local success, news1 = newsRequest(countOfNewsToGet) if success and news1.response then news = news1 currentNews = 1 newsGUI() else GUI.error("Ошибка при получении списка новостей") end end local function drawLeftBar() --Подложка под элементы buffer.square(1, 1, leftBarWidth, buffer.getHeight(), colors.leftBar, 0xFFFFFF, " ") if personalInfo then drawPersonalAvatar(3, 2, 6, 3) buffer.text(11, 3, 0xFFFFFF, ecs.stringLimit("end", personalInfo.first_name .. " " .. personalInfo.last_name, leftBarWidth - 11)) end --Элементы obj.leftBar = {} local y, color = 6 for i = 1, #leftBarElements do color = colors.leftBarAlternative if i % 2 == 0 then color = colors.leftBar end if i == currentLeftBarElement then color = colors.leftBarSelection end newObj("leftBar", i, 1, y, leftBarWidth, y + 2) buffer.square(1, y, leftBarWidth, 3, color, 0xFFFFFF, " ") y = y + 1 buffer.text(3, y, colors.leftBarText, ecs.stringLimit("end", leftBarElements[i], leftBarWidth - 4)) y = y + 2 end end --Главное ГУИ с левтбаром и прочим local function mainGUI() drawLeftBar() --Отображаем гую нужную выбранную if leftBarElements[currentLeftBarElement] == "Сообщения" then status("Получаю список диалогов") messageToShowFrom = 1 dialogToShowFrom = 1 dialogsGUI() elseif leftBarElements[currentLeftBarElement] == "Аудиозаписи" then status("Получаю список аудозаписей") audioToShowFrom = 1 audioGUI(personalInfo.id) elseif leftBarElements[currentLeftBarElement] == "Моя страница" then loadAndShowProfile(personalInfo.id) -- loadAndShowProfile(186860159) elseif leftBarElements[currentLeftBarElement] == "Друзья" then friendsGUI() elseif leftBarElements[currentLeftBarElement] == "Новости" then getAndShowNews() end buffer.draw() end local function spam(id) while true do local randomMessages = { "Ты мое золотце", "Ты никогда не сделаешь сайт", "Ты ничтожество", "Твоя жизнь ничего не значит", "Ты ничего не добьешься", "Ты завалишь экзамены", "Ты никому не нужна", "Ты не напишешь курсовую", "Твое животное помрет завтра", "Не добавляй в ЧС!", "Передаем привет от Яши и Меня (а кто я?)", "Хуй!", "Пизда!", "Залупа!", "Пенис!", "Хер!", "Давалка!" } local text = randomMessages[math.random(1, #randomMessages)] .. " (с любовью, отправлено с OpenComputers)" sendMessageRequest(tostring(id), text) print("Отправляю сообщение: " .. text) os.sleep(2) end end ---------------------------------------------------- Старт скрипта ---------------------------------------------------------------- --Инициализируем библиотеку двойного буффера --Эх, что бы я делал, если б не накодил ее? 0.2 фпс на GPU мертвеца! buffer.flush() --Хуярим настррррроечки loadSettings() --Активируем форму логина local loginData = loginGUI(settings.username, settings.password) access_token = loginData.access_token --Получаем персональные данные _, personalInfo = usersInformationRequest(loginData.user_id) personalInfo = personalInfo.response[1] -- --Ебемся в попчанский -- spam(21321257) --Активируем главное GUI clearGUIZone() mainGUI() while true do local e = {event.pull()} if e[1] == "touch" then if whatIsOnScreen == "audio" then for key in pairs(obj.audio) do if obj.audio[key]:isClicked(e[3], e[4]) then obj.audio[key]:press(0.2) if component.isAvailable("openfm_radio") then component.openfm_radio.stop() component.openfm_radio.setURL(obj.audio[key][5].url) component.openfm_radio.start() status("Вывожу в статус играемую музыку") setCurrentAudioPlaying(currentProfile and currentProfile.ID or personalInfo.id, obj.audio[key][5].id) else GUI.error("Эта функция доступна только при наличии установленного мода OpenFM, добавляющего полноценное интернет-радио") end break end end end if whatIsOnScreen == "dialogs" then for key in pairs(obj.dialogList) do if obj.dialogList[key]:isClicked(e[3], e[4]) then 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]) buffer.draw() os.sleep(0.2) status("Загружаю переписку с пользователем " .. obj.dialogList[key][7]) currentMessagesPeerID = obj.dialogList[key][5] currentMessagesAvatarText = obj.dialogList[key][6] messagesGUI() break end end if obj.crazyTypingButton:isClicked(e[3], e[4]) then obj.crazyTypingButton:press(0.2) local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, {"EmptyLine"}, {"CenterText", ecs.colors.orange, "CrazyTyping"}, {"EmptyLine"}, {"Slider", 0xFFFFFF, ecs.colors.orange, 1, 15, 5, "Количество диалогов: ", ""}, {"Slider", 0xFFFFFF, ecs.colors.orange, 1, 100, 5, "Количество запросов: ", ""}, {"Slider", 0xFFFFFF, ecs.colors.orange, 1, 5000, 500, "Задержка между запросами: ", " мс"}, {"EmptyLine"}, {"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}} ) if data[4] == "OK" then for i = 1, data[2] do local count = 1 for key in pairs(obj.dialogList) do -- GUI.error("Ебашу спам диалогу под пиром: " .. obj.dialogList[key][5]) ecs.info("auto", "auto", "CrazyTyping", "Запрос: " .. i .. " из " .. data[2] .. ", диалог: " .. count .. " из ".. data[1] .. ", peerID: " .. obj.dialogList[key][5]) setCrazyTypingRequest(obj.dialogList[key][5]) count = count + 1 if count > data[1] then break end os.sleep(data[3] / 1000) end end buffer.draw(true) end end end if whatIsOnScreen == "messages" then if obj.messageInputBar:isClicked(e[3], e[4]) then obj.messageInputBar.eventHandler({draw = function() obj.messageInputBar:draw() end}, obj.messageInputBar, {[1] = "touch", [3] = obj.messageInputBar.x, [4] = obj.messageInputBar.y}) local newText = obj.messageInputBar.text if newText and newText ~= " " and newText ~= "" then computer.beep(1700) status("Отправляю сообщение пользователю") sendMessageRequest(currentMessagesPeerID, newText .. (settings.addSendingInfo and messageEndAdderText or "")) status("Обновляю историю переписки") messageToShowFrom = 1 messagesGUI() end drawMessageInputBar() end end if whatIsOnScreen == "userProfile" then if currentProfile.audiosButton:isClicked(e[3], e[4]) then currentProfile.audiosButton:press(0.2) audioToShowFrom = 1 audioGUI(currentProfile.ID) buffer.draw() elseif currentProfile.sendMessageButton:isClicked(e[3], e[4]) then currentProfile.sendMessageButton:press(0.2) currentMessagesPeerID = currentProfile.ID messageToShowFrom = 1 currentMessagesAvatarText = currentProfile.avatarText messagesGUI() end end if whatIsOnScreen == "friends" then for ID in pairs(currentFriends.sendMessageButtons) do if clickedAtZone(e[3], e[4], currentFriends.sendMessageButtons[ID]) then buffer.text(currentFriends.sendMessageButtons[ID][1], currentFriends.sendMessageButtons[ID][2], 0x000000, "Написать сообщение") buffer.draw() currentMessagesPeerID = ID messageToShowFrom = 1 currentMessagesAvatarText = currentFriends.sendMessageButtons[ID][5] messagesGUI() break end end for ID in pairs(currentFriends.openProfileButtons) do if clickedAtZone(e[3], e[4], currentFriends.openProfileButtons[ID]) then buffer.text(currentFriends.openProfileButtons[ID][1], currentFriends.openProfileButtons[ID][2], 0x000000, "Открыть профиль") buffer.draw() loadAndShowProfile(ID) buffer.draw() break end end end for key in pairs(obj.leftBar) do if clickedAtZone(e[3], e[4], obj.leftBar[key]) then -- GUI.error("Кликнули на лефт бар ээлемент") local oldLeftBarElement = currentLeftBarElement currentLeftBarElement = key drawLeftBar() buffer.draw() if leftBarElements[currentLeftBarElement] == "Выход" then os.sleep(0.3) buffer.clear(0x262626) ecs.prepareToExit() return elseif leftBarElements[currentLeftBarElement] == "Аудиозаписи" then currentProfile = currentProfile or {} currentProfile.ID = personalInfo.id elseif leftBarElements[currentLeftBarElement] == "Настройки" then local data = ecs.universalWindow("auto", "auto", 36, 0x262626, true, {"EmptyLine"}, {"CenterText", ecs.colors.orange, "Настройки"}, {"EmptyLine"}, {"Switch", ecs.colors.orange, 0xffffff, 0xFFFFFF, "Сохранять данные авторизации", settings.saveAuthData}, {"EmptyLine"}, {"Switch", ecs.colors.orange, 0xffffff, 0xFFFFFF, "Добавлять приписку \"Отправлено с ...\"", settings.addSendingInfo}, {"EmptyLine"}, {"CenterText", ecs.colors.orange, "OpenComputers VK Client v4.0"}, {"EmptyLine"}, {"CenterText", ecs.colors.white, "Автор: Игорь Тимофеев, vk.com/id7799889"}, {"CenterText", ecs.colors.white, "Все права защищены, епта! Попробуй только спиздить!"}, {"EmptyLine"}, {"Button", {ecs.colors.orange, 0xffffff, "OK"}, {0x999999, 0xffffff, "Отмена"}} ) if data[3] == "OK" then settings.saveAuthData = data[1] settings.addSendingInfo = data[2] if settings.saveAuthData then settings.username = loginData.username settings.password = loginData.password else settings.username = nil settings.password = nil end saveSettings() currentLeftBarElement = oldLeftBarElement end end mainGUI() break end end elseif e[1] == "scroll" then if e[5] == 1 then if whatIsOnScreen == "dialogs" then dialogToShowFrom = dialogToShowFrom - dialogScrollSpeed if dialogToShowFrom < 1 then dialogToShowFrom = 1 end status("Прокручиваю диалоги, отправляю запрос на сервер") dialogsGUI() buffer.draw() elseif whatIsOnScreen == "messages" then messageToShowFrom = messageToShowFrom + messagesScrollSpeed status("Прокручиваю сообщения, отправляю запрос на сервер") messagesGUI() buffer.draw() elseif whatIsOnScreen == "audio" then audioToShowFrom = audioToShowFrom - audioScrollSpeed if audioToShowFrom < 1 then audioToShowFrom = 1 end status("Прокручиваю аудозаписи, отправляю запрос на сервер") audioGUI(currentProfile and currentProfile.ID or personalInfo.id) buffer.draw() elseif whatIsOnScreen == "userProfile" then currentProfileY = currentProfileY + profileScrollSpeed if currentProfileY > mainZoneY + 2 then currentProfileY = mainZoneY + 2 end userProfileGUI() buffer.draw() elseif whatIsOnScreen == "friends" then currentFriendsOffset = currentFriendsOffset - friendsScrollSpeed if currentFriendsOffset < 0 then currentFriendsOffset = 0 end friendsGUI() buffer.draw() elseif whatIsOnScreen == "news" then currentNews = currentNews - 1 if currentNews < 1 then currentNews = 1 end newsGUI() buffer.draw() end else if whatIsOnScreen == "dialogs" then dialogToShowFrom = dialogToShowFrom + dialogScrollSpeed status("Прокручиваю диалоги, отправляю запрос на сервер") dialogsGUI() buffer.draw() elseif whatIsOnScreen == "messages" then messageToShowFrom = messageToShowFrom - messagesScrollSpeed if messageToShowFrom < 1 then messageToShowFrom = 1 end status("Прокручиваю сообщения, отправляю запрос на сервер") messagesGUI() buffer.draw() elseif whatIsOnScreen == "audio" then audioToShowFrom = audioToShowFrom + audioScrollSpeed status("Прокручиваю аудозаписи, отправляю запрос на сервер") audioGUI(currentProfile and currentProfile.ID or personalInfo.id) buffer.draw() elseif whatIsOnScreen == "userProfile" then currentProfileY = currentProfileY - profileScrollSpeed userProfileGUI() buffer.draw() elseif whatIsOnScreen == "friends" then currentFriendsOffset = currentFriendsOffset + friendsScrollSpeed friendsGUI() buffer.draw() elseif whatIsOnScreen == "news" then currentNews = currentNews + 1 newsGUI() buffer.draw() end end end end -- local success, dialogs = getDialogsRequest(0, 5) -- saveToFile(serialization.serialize(dialogs)) -- sendMessageRequest(dialogs.response.items[2], "тестовое сообщение, отправлено через OpenComputers VK Client by Игорь, епта")