Лидеры
Популярный контент
Показан контент с высокой репутацией 12.02.2019 во всех областях
-
2 баллаА я костылял си апи в луа для опенкомпов. Нет, плюсы даже я костылять не стал — мне и си хватило. Ситуация была такова. Я тогда ещё пилил свою гуи-либу-убийцу-всего-живого-своей-охрененностью, и она как-то подозрительно тормозила. А когда программы подозрительно тормозят, юзают профилятор. Который желательно писать на си, дабы минимизировать задержки. Что я и сделал, после чего последовали долгие недели попыток прицепить си-модуль к луа на OC. Ну, прежде всего, я чутка пропатчил мод: внёс внутрь песочницуы дебаг-либу родную и не менее родной модуль package, который умеет запускать си-модули. Затем я всяко-разно пытался скомпилировать свой профилятор так, что при загрузке его он подхватывал бы символы луа. Не получилось. Поэтому я взял сырцы луа, которые юзаются в OC. Я их взял, всунул туда свой профилятор и сцомпилировал их вместе так, будто профилятор был встроенной либой луа. Костыли страшные, да. Получившимся подменил то, что лежало стандартно внутри мода, и пересобрал последний. Такими шаманствами я таки осилил получить свой ненаглядный профилятор внутри опенкомпа, и потому смог пропрофилировать свою гуи-либу-убийцу-всего-живого-своей-охрененностью. Это мне, конечно, ни о чём не поведало новом и ничем не помогло, да и гуи-либу эту я таки забросил, но это уже другая история. А можно без костылей? Не, без костылей не получится. Не потому, что плюсы — это уже костыль. Хотя это тоже справедливо (то есть, нет, конечно, не будем холивар разводить). А потому, что авторам мода и в голову не приходило, что кто-то чем-то подобным будет заниматься, и, более того, намеренно всяко-разно отрезали куски луа так, чтобы это оказалось в принципе невозможным. Потому как всем известно, как просто в си выстрелить в ногу вне зависимости от желаний владельца этой ноги, что недопустимо на публичных серверах всяких. Поэтому остаётся учить Луа. Язык это хороший, простой, минималистичный, красивый и полезный, хотя и чутка неудобный порою, как минимум, для заядлого заплюсневевшего программиста из-за динамической типизации.
-
2 баллаНе так давно @LeshaInc выкладывал свою программку, фтп клиент-то, и кто-то сказал про ssh. Это, конечно, задача интересная, но речь не об этом. Уже тогда на протяжении дней трёх я изучал вот этот документец. И с тех пор, добавив более 4 тысяч, удалив более двух тысяч строк кода, перечитав этот RFC вдоль и поперёк, исписав 22 страницы моего настольно-напольного блокнота, погуглив 183 запроса про тлс (надо же, гугловская статистика иногда бывает полезна для себя), чуть не потратив 2500 рублей на 12 страниц, описывающих формат десятичных чисел ( ) и даже найдя один баг в Computronics, который мне не давал покоя часов двенадцать, а то и больше, в общем случае... Я наварил TLS сокеты в OpenComputers. Что такое TLS? В нашей ирке спрашивавшим я отвечал так: это такая штука, из-за которой появляется замочек в адресной строке браузера. Фактически, это корректно, и им этого достаточно, но позволю немного поглубже объяснить. В девяностых годах компания Netscape разработала концепцию и реализацию безопасной передачи данных через недоверенное соединение. Назвалось это чудо SSL, что означает Secure Sockets Layer — слой безопасных сокетов, и выпущено было две версии: 2.0 и 3.0. Версия 1.0 была настолько дырявой, что даже не была никогда выпущена в публичный доступ. Но и, как это неудивительно, ни 2.0, ни 3.0 сейчас мало того, что не считаются безопасными, их поддержку уже исключают из всяких популярных подуктов типа Firefox или Chrome. Netscape, впрочем, недолго держала это изобретение. Ребята из Internet Engineering Task Force (IETF) в 1999 году выпустили свою, 3.1 версию SSL, которая хоть и имела некоторую совместимость с прошлой версией, но имела много нового и исправляла некоторые проблемы безопасности в прошлом протоколе. Версия SSL от IETF с тех пор называется TLS. Все версии, для справки: ?: SSL 1.0 1992: SSL 2.0 1995: SSL 3.0 1999: SSL 3.1 // TLS 1.0 2006: SSL 3.2 // TLS 1.1 2008: SSL 3.3 // TLS 1.2 И хоть сейчас SSL и TLS используются взаимозаменяемо, правильнее, всё же, говорить TLS. И всё же, что это за штука такая? TLS и его предшественник, SSL, — это протокол-прослойка между слоем данных приложений и слоем TCP. Как-то так: Слой данных приложений [Application Data]. Слой безопасности [Transport Layer Security, TLS]. Слой протокола контроля передачи данных [TCP]. Таким образом, переход на TLS не требует огромных изменений в код, достаточно заменить обычную имплементацию сокетов на защищённую и сгенерировать ключи. Данные с верхнего слоя шифруются и передаются по низшему слою к адресату, где данные снова расшифровываются, сверяются и обрабатываются. Как работает TLS. Перед тем, как передавать данные, неплохо было бы договориться с другим концом соединения, какой набор шифрования использовать, передать некоторые дополнительные данные, подтвердить подлинность сервера (для защиты от встраивания в соединение) и, конечно, обменяться ключами, которыми будет шифроваться информация. Для этого предназначена процедура рукопожатия — Handshake. Клиентом генерируется рандомная информация, шифруется асимметричным шифратором (ECDH-RSA или RSA) и передаётся серверу. Перед этим сервер предоставляет цепочку сертификатов, каждый последующий сертификат которого подтверждает предыдущий. В конце цепочки получается самоподписанный сертификат, которому надо доверять (есть целые списки таких корневых сертификатов). После того, как рандомные байты переданы, сервер и клиент из них генерируют ключи: два ключа проверки валидности информации (на сервер и клиент отдельно для защиты от атаки), два ключа симметричного шифрования данных и, если того требует шифратор, два инициализирующих вектора. В конце рукопожатия отправляют финальное сообщение, которое уже шифруется. Оно содержит хэш всех сообщений рукопожатия, чтобы предотвратить перехват трафика. Каждое шифрованное сообщение имеет специальный код авторизации (MAC), который включает хэш пересылаемых данных и номер последовательности, который имеется отдельно для приёма и отдачи, начинается с 0 и увеличивается на 1 с каждым отосланным сообщением. Таким образом, если сообщение было перехвачено и позже отослано, или трафик был перепутан, то и сервер, и клиент после проверки кода авторизации закрывают соединение. Как видно, протокол этот отнюдь не простой, а потому я ещё больше ценю свою программку. Она не полностью соответствует стандартам, в ней нет проверки сертификата, да и сиферы пока только с RSA, но уже позволяет создать соединение с GitHub, Google, да и другими HTTPS-сайтами. Оно работает для меня как-то нестойко, шатко, долго, в общем, неустойчиво. Но ведь работает! На скрине выше успешно была получена информация длиной в 27763 байта. Библиотека предоставляет таблицу с одной функцией: tlsSocket(host: string[, port: number]). Возвращает она обёрнутый сокет: таблицу с функциями: socket.write(data: string) — посылает данные на сервер. socket.read(): string or nil, string — читает данные с сокета. socket.close() — закрывает сокет (делает это правильным способом, оповещая сервер). socket.id(): string — возвращает ID сокета. socket.isClosed(): boolean — говорит, закрыт ли сокет. socket.setTimeout(to: number) — устанавливает предельное время ожидания данных с сокета, в общем, таймаут соединения. Все функции вызываются с ., не с :! Зависимости: Компоненты Карта данных второго уровня. Она предоставляет получение рандомных данных и HMAC. Улучшенный шифратор (Advanced Cipher Block) из Computronics. RSA шифрование. Интернет-карта, чтобы, очевидно, посылать запросы. Библиотеки libder-decoder — моя собственная библиотека, которая парсит сертификаты. libbigint — либа БОЛЬШИХ чисел (сначала была библиотека от @Zer0Galaxy, но работала она жутчайше медленно: более минуты против пары секунд). lua-lockbox — либа с криптофункциями. К сожалению, не все они работают на Lua 5.3, но есть рабочий AES-128 шифратор. Lua 5.3. На прошлой версии работать не будет! OpenOS 1.6. OpenComputers 1.6. Установка из OPPM: oppm install libtls. Исходный код. P. S. Прошло достаточно много времени, и теперь уже на дворе (с 2018) выкачен TLS 1.3, который как-то слишком разительно отличается от TLS 1.2, который я изучал и имплементировал. Но 1.2 должен пока (минимум ещё годов 4-5) работать.
-
1 баллПочему же нет? На главной странице есть литература по которой можно выучиться. Может маленько устарела, но азы то изучить вполне пойдет. Если любишь обзоры где все подробно разжевано, то есть канал @1Ridav Там правда по ComputerCraft но там разница в работе не сильно большая, Lua разжеван до основания, я собственно по тем видео и учился. А так, рекомендую заглядывать в раздел Гайды, обзоры по модам там много чего интересного можно найти. Ну и советую погуглить файлы справки по lua, справочник зачастую удобнее чем шараханье по сайту в попытках найти нужную тебе функцию. У меня он называется Lua 5.3.chm с переводом, если не найдете, кричите, скину. И кстати lua попроще крестов будет.
-
1 баллВсем здрасти. Скрины: Клиент 1: Клиент 2: Лог сервера: Реализовано: Выдача IP Передача данных по выданым IP Регистрация/удаление доменов Получение IP адреса по домену То что хочется реализовать: Улучшить защиту, возможно сделать шифрование -Улучшить способ передачи данных между внутриигровыми IP Сделать библиотеку для пользовательских программ(С++, Java, Python, итп) для управления\получения данных OC через сервер, а так же поддержку Arduino(Можно будет выводить значения на экран подключеный к Arduino) Добавить поддержку децентрализации если в сети более 1 сервера(Можно будет делать межсерверные DNS-запросы) (Продолжение следует) Плюсы: Можно соединять OC компьютеры стоящие на разных MC серверах Быстрая работа сервера Минусы: Нужна оптимизация и поиск багов Плохая защита Исходники GitHub: https://github.com/TheConnBit/OpenComputersDHCP-DNS P.S. Там же объяснение всех команд, итп Исходники для ленивых (обновлено): Сервер (Запускать через консоль java -jar и лучше в отдельной папке): DHCP-DNS-Server.jar Клиентская библиотека: ddns.lua На скрине показано: подключение к серверу, выдача IP, регистрация домена, запрос IP домена, передача данных, получение, удаление домена, отключение Вообщем, сильно не пинайте за код. Если кто возьмется искать\найдёт баги или будут предложения что улучшить\добавить, пишите мне сюда или на почту bithovalsky@gmail.com Сначало была идея только DHCP сервера, но потом я накнулся на статью Programmist135: http://computercraft.ru/topic/1853-dns/ и реализовал DNS. Последние изменения: - - v1.1 Исправлены названия функций Исправлен перевод Функция Resolve теперь возвращает IP Пофикшены отключения сервером клиентов из за таймаута Echo запроса Список доменов теперь указывается в файле config.properties Изменён способ отправки сообщений по IP, появились порты --Bit
-
1 баллДроны - как керосин. Они есть везде. Еще года два назад это было просто еще одно интересное видео на Ютубе. Год назад они вдруг оказались в интернет магазинах. Затем просочились в рекламу на ТВ, и вот теперь - они есть и в OpenComputers! Пришла пора с ними разобраться. 1. Матчасть Дрон, в данном случае - квадрокоптер, это беспилотный летающий аппарат, приводимый в движение двумя парами горизонтальных винтов. Приостановливая вращение винтов с одного боку, дрон двигается в сторону (стрейф). Эти винты вращаются в разном направлении (два - по часовой срелке и два - против), за счет чего дрон не нуждается в стабилизирующем хвостовом пропеллере (как вертолет). За счет этого же он и разворачивается в воздухе, замедлив вращение однонаправленной пары винтов. Дрон обладает небольшой массой, для экономии энергии, которой у него не много (на 10-30 минут полета в среднем). (с) Википедия 2. Дроны и OpenComputers Приблизительное изображение дрона в OpenComputers =): В мире Майнкрафта дрон представляет из себя "сущность" (Entity). Это значит, что он обладает возможностями мобов Майнкрафта. (В то время как робот - это блок.) Его можно сдвинуть с места толкая. Он умеет пролетать сквозь двери и калитки (в отличии от робота). Он движется не последовательно, из блока в блок, а из точки в точку. Причем маршрут может лежать по диагонали. Конечно, движется он по кратчайшей линии, и если на пути окажется стена - дрон столкнется с нею. Программирование дрона как две капли воды похоже на программирование микроконтроллера. Вы точно так же записываете программу на EEPROM, и при необходимости меняете ее на верстаке. Только в отличии от контроллера, вам становится доступен новый компонент: drone. Подробнее об командах дрона можно узнать здесь: OpenComputers/Дрон. (Или здесь: ocdoc.wiki (англ.)) 3. План Нужна какая-нибудь несложная задача, для целей эксперимента. Используем программку send из предыдущего поста, для удаленного управления. Зальем ее на планшет. А дрон пусть... носит свиней. Будем оригинальными и непоследовательными. 1. Команда 'add X Y Z Name From'. Добавляем точку Name к маршруту, цепляя ее к точке From. Зададим дрону последовательность точек, которые образуют граф - безопасные маршруты. 2. Команда 'catch' - дрон ловит свинью. 3. Команда 'drop' - дрон выпускает свинью. 4. Команда 'to X' - дрон летит в точку Х. Для начала не будем особо заморачиваться с графом маршрутов. Это будет простое неориентированное дерево. Примерно такое: 4. Строим полигон Построим что-нибудь подходящее для тестов. Отметим ключевые точки будущего графа красными блоками. А синий блок - будет стартовой площадкой дрона. Поскольку я играю без модов на энергию, мой планшет и дрон будут работать вечно. И я не заморачиваюсь станцией подзарядки. Иначе, к схеме выше было бы необходимо добавить станцию, где дрон мог бы зарядить аккумулятор. 5. Пишем программу Скрипт для удаленного управления скопипастим из прошлого поста, подправим, чтобы умела отправлять несколько переменных и зальем на планшетик, для удобства. (Для этого, соберите планшет - не забудьте клавиатуру и видеокарту! - положите его в зарядник и запустите с подключенного компа команду install. Укажите адрес винчестера планшета - и все, что было у вас на компе автоматически загрузится в планшет, включая даже ваши собственные программы.) local com = require('component') local modem = com.modem local args = {...} modem.broadcast(27, table.unpack(args)) io.write("Message: ") print(table.unpack(args)) Далее - более сложная часть. Программа дрона. Программа предназначена для EEPROM. Значит соблюдаем те же правила: используем computer, component и API имеющихся у дрона компонентов. Включая его родной компонент drone. В нашем случае, дрон вооружен апргейдом-лассо (leash) и беспроводной сетевой картой (modem) для связи. Стоит отметить, что процесс отладки программы (по крайней мере в текущем билде мода) достаточно неудобен. В случае ошибки дрон отказывается включиться, издав тонкий писк, и не выводя никакой информации. Получить отчет об ошибке при помощи анализатора не выйдет - ведь Shift+ПКМ просто снимает дрона. Автор обещал в скором времени это исправить. Ну а пока - помучаемся. Отредактировать чип в стороннем редакторе, не вынимая его из дрона тоже не выйдет. В отличии от файловых систем, которые имеют удобную папку вида /saves/World/opencomputers/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/, чипы EEPROM хранят свой код в NBT тегах предмета. Этим же обусловлено и ограничение размера кода в 4 килобайта. 5.1. Основная часть Это цикл который ждет указаний, а затем запускает соответствующую функцию. drone = component.proxy(component.list("drone")()) modem = component.proxy(component.list("modem")()) leash = component.proxy(component.list("leash")()) modem.open(27) route = {} path = {} current = "" while true do name, _, sender, _, _, message, x, y, z, point, from = computer.pullSignal(1) if name == "modem_message" then if message == 'add' then add(tonumber(x), tonumber(y), tonumber(z), point, from) if current == "" then current = point end elseif message == 'to' then to(x) elseif message == 'catch' then catch() elseif message == 'drop' then drop() end end if #path > 0 and drone.getOffset() < 1 then drone.move(route[path[#path]].x-route[current].x, route[path[#path]].y-route[current].y, route[path[#path]].z-route[current].z) current = path[#path] path[#path] = nil end end modem.close() Чтобы облегчить себе жизнь (и тестирование bios), вы можете сделать так: напишите заглушку для компонента drone (и других, если надо), вроде этой: http://pastebin.com/EVYzN5Bj Просто скопируйте в папку на компьютере, где вы пишете программу для дрона. Затем измените первые строки программы следующим образом: component = require('component') computer = require('computer') drone = require('drone') modem = component.modem -- leash = component.proxy(component.list("leash")()) Затем добавьте в цикл условие выхода по нажатию кнопки: if name == 'key_down' then break end И вы можете просто запустить вашу программу для дрона на компьютере. Разумеется полноценной эмуляцией дрона тут и не пахнет, зато очень удобно отслеживать глупые синтаксические и логические ошибки. Как устроен код основного цикла? Переменная route - хранит таблицу "вейпоинтов" (waypoints). Это вершины графа и информация о связях между ними. Переменная path - хранит путь от текущей вершины до цели. Переменная current - отмечает текущее местоположение дрона в графе. В цикле мы читаем получаемые сообщения и вызываем соответствующие функции. Первая переданная вершина считается дроном текущей. Во второй части цикла происходит проверка. Если путь до цели - не пуст (это значит, что дрону надо куда-то лететь) и дрон уже долетел до текущей вершины (getOffset()), то программа берет следующую вершину из path, отправляет дрона к ней и объявляет ее текущей. 5.2. Функции-команды Теперь последовательно добавим функции для каждой команды. function add(x, y, z, name, from) route[name] = {x=x, y=y, z=z, link = {}} if from ~= nil then if route[name] == nil or route[from] == nil then drone.setStatusText("Error!") else table.insert(route[name].link, from) table.insert(route[from].link, name) end end end Тут все просто. Пишем вершину в список. Если он связана с другой вершиной (from ~= nil), то в специальную табличку link заносим две связи: из name в from, и из from в name. function search(target, point, prev) for key, name in pairs(route[point].link) do if name == target then table.insert(path, point) return true end end for key, name in pairs(route[point].link) do if name ~= prev then if search(target, name, point) then table.insert(path, point) return true end end end return false end function to(name) path = {} table.insert(path, name) search(name, current) end Функция to обнуляет старый путь (на всякий случай), затем вставляет в него цель пути (name) и запускает функцию search, которая рекурсивно ищет и записывает остальные промежуточные вершины на маршруте от name до current (текущей локации). Функция search сделана достаточно примитивно (возможно вы предложите более эффективный способ?). Поскольку мы договорились, в целях упрощения использовать граф-дерево (не содержаший петель), от любой точки к другой существует один и только один маршрут, который функция и находит перебором связанных вершин. function catch() for c = 2, 5 do if leash.leash(c) then return true end end return false end function drop() leash.unleash() end Тут все элементарно. 6. Подготовка Пишем программу на дрона, заряжаем планшет и выдвигаемся в зону действий. Дрона ставим на синий куб (стартовая площадка) и включаем. После уточнения на местности, составляем карту вейпоинтов и строим на бумажке будущий граф: Для каждого загона добавлены две точки - name и name_up. Основные "трассы" дрона лежат на высоте в 6 блоков. А в каждом загоне спускаются к земле. (Чтобы заарканить животное, выстреливая лассо вбок, дрону желательно находиться на одном уровне с жертвой). С планшета вносим координаты в память дрона. Примерно так: Главное - не ошибиться. Т.к. в код не была добавлена защита "от дурака" =) Алгоритм позволяет добавлять вершину "на лету". В любой момент вы можете добавить еще одну ветку к схеме. Теперь все готово к тесту. 7. Запуск Все готово. Проверим, как он двигается. Введем send to sheeps в консоль планшета. Дрон уверенно поднимается в воздух и опускается в загоне в овцами. Теперь введем send to pigs. Функция search снова вычислит путь и робот переместится в указанную вершину: Функции catch и drop тоже работают штатно =) Хотя и не лишены некоторых глюков (ведь физика веревки не просчитывается): 8. Итоги а) Дрон - любопытная штуковина. б) Полный код прошивки. использованный в этом посте - здесь: http://pastebin.com/Cy1UR6vy в) Навигация по вейпоинтам - интересный и очень распространенный способ организации сложного движения. Схему можно усложнить - опционально добавлять только одну связь в таблицу link - тогда получатся ребра с односторонним движением. Добавить петли, оптимизировать поиск кратчайшего пути. Еще можно облегчить правление дроном - хранить все команды для конкретной задачи в виде файла-скрипта, который запускать одной командой и т.д. Enjoy!
-
1 баллНеожиданно для себя! Напилил HTTP/HTTPS 1.1 (во второй версии разбираться лень) либу. Работает она абсолютно идентично функции component.request(), вот только поддерживает HTTPS и принимает четвёртый параметр: метод запроса (GET по умолчанию, если не посылается тело запроса, и POST в противном случае). Кроме того, она превращает все хедеры в формат Train-Case, так что можно спокойно получать данные хедеров в своих программах. Однако всё это делается за счёт меньшей производительности, так что лучше использовать стандартные функции, если ничего из вышеперечисленного не требуется. Библиотека возвращает функцию отправки запроса: http(url: string[, body: string[, headers: table[, method: string]]]): table — посылает запрос на сервер. http(url: string, kwargs: table): table — делает то же самое, но принимает таблицу с аргументами, чтобы не путаться. В таблице аргументов все параметры опциональны. Вот пример полной таблички: { body = "Hello here\n", headers = { connection = "close" }, method = "PUT" } Возвращают обе функцию таблицу с теми же функциями, что у компонента (и да, тут не надо ставить двоеточие, как и в OC'шном реквесте): response.read([n: number]): string or nil — прочесть некоторое количество данных. Вообще, вся информация читается сразу же, но можно ограничить вывод аргументом. Можно отдать math.huge (или вообще не указывать аргумент), и тогда возвратится все данные полученные. response.close() — закрыть соединение. response.finishConnect(): boolean — возвращает, открыто ли соединение (в стандартном OC немного по-другому работает, там не буля, а nil с причиной, ну и ладно). response.response(): number, string, table — возвращает код статуса (204 или 404, например), текстовое описание статуса ("No Content", "Not Found") и хедеры таблицей таблиц (ибо хедеров одинаковых может быть несколько). Вот так может выглядеть выхлоп response.response(): 200 "OK" {["Content-Length"]={"12"}, ["Content-Type"]={"application/octet-stream"}, Date={"Fri, 05 Aug 2016 15:35:34 GMT"}, ["Last-Modified"]={"Fri, 05 Aug 2016 14:56:08 GMT"} Server={"SimpleHTTP/0.6 Python/2.7.12"}} Установка из OPPM: oppm install libhttp. Ну и исходный код.
-
1 балл
-
1 баллНадо пробовать. Еще насчет приватов надо проверить. А то один дрон будет хозяина петлей держать, а второй - грабить. =) Спасибо, исправил.
-
1 балл
-
1 балл
-
1 балл
-
1 балл
-
1 балл
Эта таблица лидеров рассчитана в Москва/GMT+03:00
