Перейти к содержимому

Fingercomp

Гуру
  • Публикации

    1 629
  • Зарегистрирован

  • Посещение

  • Победитель дней

    283

Записи блога, опубликованные пользователем Fingercomp

  1. Fingercomp
    Minecraft Mods



    #2



    Обзор обновления MoarPeripherals 1.5



    #2. Turtle Teleport.


    Вторая часть обзора обновления этого замечательнейшего аддона 1.5 у Вас перед глазами! Сегодня мы поговорим о незамысловатой штуковине, а именно о Turtle Teleport, или, в русском переводе, черепашьему телепорту. Строение делаю похожим на пред. часть.
     
    I. Что это такое и с чем его едят?
    Ну, не знаю, как Вы будете грызть этот блок, но нужен он для телепортации туртлей, что следует из весьма интересного названия. Всё
     
    II. API.
    Телепорт имеет всего 3 функции:
    requiredFuel(x, y, z) :: numberЭтот блок не такой читерный, как кажется. Он кушает топливо! Но маленько, не страшно Эта ф-ия показывается, сколько ед. топлива потребуется для телепортации.
    [*]getTurtleLocation() :: boolean, table OR boolean, string
    Возвращает в случае успеха вторым аргументом таблицу, содержащую координаты. Пример: { 0, 64, 0}

    [*]teleportTo(x, y, z) :: boolean OR boolean, string
    Собственно, телепортирует черепаху.



    III. Launch!
    Пора выпить чашечку кода и заняться самым весёлым.
    1. Исходная позиция. Обращаю внимание, что черепаха должна находиться над телепортом.

    2. Я написал простенькую прогу, которая демонстрирует возможности этого блока. Начнём с подключения блока и получения ф-ий.

    3. Как работает ф-ия getTurtleLocation(). Комментариев не требуется?

    4. Допустим, мы хотим запустить туртлю на 10 блоков в плюс по всем координатам. Расчитываем необходимое кол-во топлива.

    5. Попробуем запустить. Упс! Черепаха разряжена, о чём нам сообщают.

    6. Запускаем, наконец, черепаху! true

    7. И снимок того, куда телепортнулась туртля.

     
    IV. Заключение.
    Надеюсь, Вам эта информация была интересна. Оставляйте комментарии, оценки, "Лайки". И, конечно же, ждите новых записей у меня в блоге =)
  2. Fingercomp
    OPENCOMPUTERS V. 1.5.7 — DOCUMENT ALL THE THINGS!


    Приветствую Вас, уважаемый читатель! На момент написания этой записи 18 часов назад (14 апреля 2015 года) была релизнута версия 1.5.7, в которой есть некоторые изменения, на которые мы посмотрим:
    Добавлено: Теперь у принтов можно указать силу редстоун сигнала, который они смогут испускать.
    Автодополнение через TAB в Lua интерпретаторе.
    Принты теперь вообще бомбой стали: они могут излучать свет!
    Теперь вместо картриджей в принтер можно вставлять обычные ванильные красители, но с куда меньшей эффективностью.
    Ключик. По большей части для 1.8. Но работает с некоторыми другими модами Комментарий переводчика: надо бы на грифабельность проверить.

    [*]И, самое вкусное... КНИЖКА-МАНУАЛ! Описано в ней всё самое вкусное в ОС
    Комментарий переводчика: хороший шаг! Ведь в НЕИ не всегда всё можно уместить, а вот в книжке — почему бы и нет?



    [*]Изменено:
    Хотите ли Вы этого или нет, но вам придётся крафтить этот мануал, так как рецепты Луа БИОСа и OpenOS теперь крафтятся с использованием этой штуковины.
    Скорость функции gpu.setPalette() теперь стала быстрее. Также добавлена зависимость скорости от уровня видеокарты.

    [*]Пофикшено:
    Потенциальный краш, возникающий при попытке отрендерить символ, который не может быть сгенерирован.
    Хамелиум блоки ломают мипмап.



  3. Fingercomp
    ДВАДЦАТЬ! Новая версия, 1.5.20, готова к скачиванию. Рассмотрим изменения:
    Добавлено: Функция compareStackToDatabase для контроллера инвентаря и транспозера. Конвертер для обработки информации о зачарованиях. Французский перевод в мануалах. От Pyeroh. Перевод на немецкий язык в мануалах. Подготовлен Shadow1Raven. Можно отключить излучение света для голографических проекторов.
    [*]Изменено:
    Обновлено API для Forestry.
    [*]Исправлено:
    Скорость ломания кабелей с мультиблоками FMP. Нанотапки дают эффект замедления, если они разряжены. Несовместимость с Чизелем, которая позволяла делать из обычных сундуков эндер-сундуки. O_o Отсутвие проверки NBT-данных при объединении предметов, полученных от агентов, при ломании блока. Наниты не работли в других измерениях. Вероятный краш при использовании команд OpenComputers. Продолжение эпопеи о зарядниках: вероятный краш при нескольких таковых. Переполнение, когда кто-то особо тупой устанавливает фигалионные размеры дисков. Завышенная задержка в релеях.



  4. Fingercomp
    Приветствую Вас, уважаемый читатель! На протяжении уже нескольких недель я думал, о чём мне писать в блоге... И, наконец, нашёл.
    Я начинаю переводить чэйнджлоги ОС. Полезно и нетрудно.
    5 апреля 2015 года резилнулась версия OC 1.5.6, в которой кое-что изменили. Посмотрим на список изменений!
    Добавлено: Хамелиум теперь можно поедать. Но лучше не надо. Больше, БОЛЬШЕ АЕ2 интеграции! Автор выражает благодарность DrummerMC.
    [*]Изменено:
    Дискеты и харддрайвы теперь стираются через перекрафт самого себя, Шифт-клик отключён. Улучшенное обращение с рецептами. Теперь можно поставить false и отключить рецепт вообще. Миссинги будут генерировать ошибки уровня "Внимание".
    [*]Пофикшено:
    WAILA теперь показывает инфу о 3D-принте корректно. Конвертер для Форести применяется не только для пчёлокоттеждей/изунализаторов/..., но и для пчёл в инвентарях. Комментарий переводчика: Мне непонятно, что это за конвертер появился.


    [*]Дисассемблер игнорировал размер выхода рецептов... В общем, из 1 наггета получался 1 слиток. Дюпобаг. [*]Потенциальные краши в интеграции с АЕ2 даже в новых версиях... Будем надеяться, что сработает. [*]Улучшена интеграция ForgeMultipart и 3D-принтов. Ими теперь можно прикрывать кабели из Project:R3D, например. [*]Редстоун контроллер теперь по-нормальному включает компьютер. [*]Бесконечныепроводные сообщения вызывали загрузку чанков.


    Вот и всё в этой версии. В принципе, ничего дополнительно объяснять не нужно, потому я здесь заканичваю. Комментарии, как всегда, приветствуются =)
  5. Fingercomp
    Окей, новую версию ждать не пришлось год в этот раз. 1.7.0! В наличии много всяких улучшений в OpenOS, баги фиксятся, а не создаются, но каких-либо особых изменений в самом моде нет.
     
    Начнём с новых штучек в моде.
    Версия для 1.11.2 и 1.12.1. Поддержка Forge Energy, интеграция с CC, Project:R3D, WR-CBE, IC2, Hwyla, AE2. Датчик движений можно пихать свободно как апгрейд для роботов. Китайский перевод. Пофикшены фризы монитора у роботов. С 1.12 юзаются ванильные железные наггетсы. Рефакторинг API и кода в целом. Методы getAllStacks и getInventoryName для контроллера инвентаря и транспозера. Наконец-то! Ивент drop посылается и при простом клике (раньше только при таскании). Улучшенная поддержка многожидкостных контейнеров. Вернее, многоконтейнерных блоков. Как-то так. Отсутствующие глифы стали шириною в 1 символ. Бесконечный цикл в мануале. Отличная фича была. Правда, это только со сломанными страницами проявлялось. Роботы не все инструменты адекватно использовали. Теперь все, наверное. Обломали способ загрузить процессор на хостовом компе из игры.

    Ну, мне обманывать смысла не было, да: в осном фиксы всякие. Зато в OpenOS тонны всякого.
    Новая библиотека в OpenOS: thread. Туториал попробую когда-нибудь сообразить. Рефакторинг, чистка и прочие такого рода мероприятия. Фиксы всяких прог и либ (ls, lib/event, lib/keyboard). Вряд ли это интересно. loadfile теперь работает с относительными путями. tty вынесен из lib/term; поддержка кодов vt100. Фиксы окружений в load, bin/lua и шелле. Прога pastebin теперь работает через https. Улучшение производительности всего и вся. Здесь же и либа сериализации. ls использует цвета из переменной окружения LS_COLORS, которая теперь содержит коды vt100. @LeshaInc хотел немного славы, поэтому отдельно упоминаю его — он посоветовал. Лэшань же написал bin/tree, которая включается в стандартную поставку. И, конечно же. Запускается быстрее! Жрёт меньше памяти (140 кБ)! Крутой номер версии!

    Поэтому обновляйтесь. Тем более, что этот релиз имеет наибольшее число поддерживаемых версий. 1.7.10, 1.8.9, 1.9.4, 1.10.2, 1.11.2, 1.12.1. Выбирайте по вкусу на странице релиза.
     
    P. S. Оказывается, я давно не писал сюда что-либо. Тогда тизерну в качестве компенсации. Готовлю потихоньку небольшой кукбук с рецептами по OC, OpenOS и Lua. Думаю скоро выложить. Посмотрим, как оно пойдёт.
  6. Fingercomp
    Решил больше не ждать с этим. Где-то пару месяцев назад решил начать пилить одну штуку — кукбук, или книгу "рецептов". Изначально задумывалось как сборник просто именно рецептов как в кулинарной книге: тонна кода и немного объяснений; получилось наоборот, естественно, — до того, что в некоторых "рецептах" кода нет, — ну это, наверное, потому что я не умею толком через код объяснять.
     
    В любом случае, теперь это сборник полезных туториалов по практическому применению.
     
    Он разделён на 3 раздела.
    Lua — статьи, непосредственно затрагивающие код и написание программ. Сниппеты кода, гайды по функциям. OpenOS — статьи абстракции уровня выше немного. Здесь всё об использовании шелла, стандартных программ и прочих фичах дефолтной оси OC. OC — статьи, не относящиеся непосредственно к разработке программ или фичам OpenOS. Наверное, это in-world штуки всякие, по большей части. Например, инфа о том, как собрать идеальный хрякокоптер или правильно тестировать нанытов. Потом могут быть статьи о всяких блоках, да и прочих фичах самого мода.

    Когда я сейчас пишу эту запись, в кукбуке есть уже 13 рецептов.
     
    Ссылочка на книжку. Заходите, почитайте.
     
    Есть слухи, что на гитбуксе можно отсылать пулл реквесты... Они здесь называются чендж-реквестами, но разницы никакой. Если есть идея для ещё одного рецепта и желание написать статью — присывайте эти реквесты; если желания нет — можно написать идею в комментариях. Я пока не особо понимаю, чего ещё бы добавить в кукбук.
  7. Fingercomp
    CSV идёт от Comma-Separated Values, что, в общем, довольно точно описывает этот формат хранения таблиц. Вот типичная таблица:
    aaa,bbb,ccc,dddeee,fff,ggg,hhh
    Как видно, строки отделяются \n, а ячейки ­— запятой. Последняя строка может иметь или не иметь \n.
     
    Формат очень простой. Описывается он в RFC 4180. Там всего 7 пунктов. Ну а раз простой, давайте соорудим парсер.
     
    Вот у нас есть строка aaa,bbb,ccc,ddd\neee,fff,ggg,hhh. Задача: сделать из неё
    [ [ "aaa", "bbb", "ccc", "ddd" ], [ "eee", "fff", "ggg", "hhh" ]]
     
    Так как позже я немного усложню парсер, очевидный вариант со split, которая делит строку, опустим. Сделаем так:
    def parse_csv(s): # Сюда идёт результат result = [] # Текущая строка row = [] # Текущая ячейка cell = "" # Проходимся по строке for i in range(len(s)): # Текущий символ c = s[i] if c == ",": # Если символ — запятая, закрываем ячейку row.append(cell) cell = "" elif c == "\n": # Если это перевод строки, то закрываем ячейку и строку row.append(cell) cell = "" result.append(row) row = [] else: # Любой другой символ добавляем в ячейку cell += c # Возвращаем результат return result
    Запускаем:
    >>> parse_csv("aaa,bbb,ccc,ddd\neee,fff,ggg,hhh\n")[['aaa', 'bbb', 'ccc', 'ddd'], ['eee', 'fff', 'ggg', 'hhh']] >>> parse_csv("aaa,bbb,ccc,ddd\neee,fff,ggg,hhh")[['aaa', 'bbb', 'ccc', 'ddd']]
     
    Действительно, в конце может и не быть \n. Давайте поправим:
    def parse_csv(s): result = [] row = [] cell = "" for i in range(len(s)): c = s[i] if c == ",": row.append(cell) cell = "" elif c == "\n": row.append(cell) cell = "" result.append(row) row = [] else: cell += c # Если ячейка не пуста if cell: # Закрываем ячейку и строку row.append(cell) result.append(row) return result
    Проверяем:
    >>> parse_csv("aaa,bbb,ccc,ddd\neee,fff,ggg,hhh\n")[['aaa', 'bbb', 'ccc', 'ddd'], ['eee', 'fff', 'ggg', 'hhh']] >>> parse_csv("aaa,bbb,ccc,ddd\neee,fff,ggg,hhh")[['aaa', 'bbb', 'ccc', 'ddd'], ['eee', 'fff', 'ggg', 'hhh']]
    Замечательно.
     
    Почему я проверяю только ячейку, а не строку ещё? Просто пустая ячейка и непустая строка может быть только тогда, когда на конце строки висит запятая. aaa,bbb,. А это явно запрещено по RFC.
     

    В текущем виде в ячейке у нас не получится хранить \n и ,. Если первый символ ещё кое-как, то без запятой как-то совсем не весело, верно?
    На наше счастье, в спецификации есть и это. Ячейку можно поместить в двойные кавычки (", кто не понял), тогда до следующей кавычки обрабатываться \n и , не будут.
     
    Давайте улучшим наш парсер, добавив поддержку этих самых кавычек. Так как у нас посимвольный парсинг, сделать это гораздо проще. Вот так:
    def parse_csv(s): result = [] row = [] cell = "" # Начиналась ли текущая ячейка с кавычки quoted = False for i in range(len(s)): c = s[i] if quoted: if c == '"': # Закрывающая кавычка quoted = False else: cell += c else: if c == '"': if not cell: # Открывающая кавычка в начале ячейки quoted = True else: # Кавычка в середине строки: запрещено return False elif c == ",": row.append(cell) cell = "" elif c == "\n": row.append(cell) cell = "" result.append(row) row = [] else: cell += c if cell: if quoted: # Где-то не закрыли кавычки return False row.append(cell) result.append(row) return result
     
    Проверяем:

     
     
    Всё верно, кроме последнего. В середине строки в закавыченных строках эти самые кавычки должны быть экранированы вот так: "". Например: "aaa""bbb,ccc",ddd,eee. Давайте починим и это.

    def parse_csv(s): result = [] row = [] cell = "" quoted = False # Является ли предыдущий символ кавычкой prevQuote = False for i in range(len(s)): c = s[i] if quoted: if c == '"': # Помечаем, что у нас есть кавычка в середине строки. # Она может быть экранированной. prevQuote = True quoted = False else: cell += c else: if c == '"': if not cell: quoted = True else: if prevQuote: # Если у нас прошлый символ был кавычкой, # то получаем экранированную кавычку. cell += '"' quoted = True prevQuote = False else: return False elif c == ",": row.append(cell) cell = "" # Кавычка была закрывающей prevQuote = False elif c == "\n": row.append(cell) cell = "" result.append(row) row = [] # Кавычка была закрывающей prevQuote = False else: if prevQuote: # Мы ждали кавычку или закрытие ячейки. return False cell += c if cell: if quoted: return False row.append(cell) result.append(row) return result
     
    Опять тестируем:

     
     
    Вот и всё. 44 строки кода на Python — и мы можем парсить CSV.
    Я также переписал парсер на Lua, опубликовал его в OPPM под libcsv. Можете качать и радоваться. Вот сырцы.
     
    Ну и надеюсь, это было менее сложно, чем мои записи про пакетные менеджеры до этого, и вы смогли прочитать это .
  8. Fingercomp
    Добавлено Версия дисковода гибких дисков (дискет, если что) для серверов. Возможность взаимодействовать с некоторыми хранилищами предметов с помощью контроллера инвентаря (не особо понял, что тут нового. Видимо, новые инвентари или черех адаптер). Поддержка энергии RotaryCraft. Возможность задать границы вывода (я про viewport, да) на GPU, так что теперь можно химичить с производительностью всякими нестандартными путями. Кабели запоминают цвета, в которых их красили, при срубании. Можно их теперь ещё и в сетке крафта красить. Интеграция с IC2 на 1.8.9. Можно переключаться между всеми лут-дискетами, перекрафчивая их с ключом. computer.getDeviceInfo() — метод, который возвращает базовую инфу об устройствах (от планок памяти до всяких шифраторов CX). computer.getProgramLocations() — функция, которая возвращает, на каких лут-дискетах какие лут-программы лежат. Торговый апгрейд для роботов. Торговля с жителями, об этом я уже писал. Можно задать свои HTTP-хедеры вместе с, ммм, HTTP-запросом. debug.playSoundAt, которая, как ни странно, играет звуки. Возможность задать используемый CPU из AE2 при запросе на автокрафт. Интеграция с ThaumicEnergistics. Цветные дронотапки (hover boots). Индикатор сетевой активности на серверах. Перевод на бразильский язык.
    [*]Изменено
    Мажорнейшее и вообще самое основное — серверные стойки. Я о них писал, да. Удалённые терминалы (Remote Terminals) подключаться должны к серверу удалённых терминалов (Remote Terminal Servers), штучке для серверной стойки. Компонент дисководиков. Можно теперь программно выкидывать диски из дисководов. Нёрф геолайзера — учитывается теперь дистанция до блока, а не колонны. Зато область сканирования можно задавать не только в виде колонны, а в виде кубоидов объёмом до 64 блоков. Упрощены рецепты. Новый шрифт поставлен. Можно сменить ещё с помощью ресурспаков. Один солидный книжный том изменений в OpenOS.
    [*]Починено
    Зависания при крафте, возвращающем тот же предмет, что и данный на входе. Всякие проблемы с рецептами режима грега. Обработка userdata в LuaJ. Конвертация энергии некоторых модов. Проблемы производительности из-за слишком усердной компресси данных, передаваемых клиенту. Тоже проблемы производительности, связанные с отправкой пакетов с дескрипторами компьютеров на клиенты. Обновление LuaJ с фиксами багов. Интеграция с Mystcarft. Напомню, категория "починено". Интеграция с ключом BuildCraft. Роботы могли черпать блоки текучих жидкостей, не источников. Генератор поедал нещадно предметы, если они не были вовремя оттуда вынуты. Контейнеры апгрейдов никогда не выпадали из планшетов при разборке. Сломанный код сохранения информации о блоках OC в версиях MC выше 1.8. Микроконтроллеры ловили только сигналы с сетевой карты.



    Вот это всё и есть OC 1.6. Вот чем он так крут по сравнению с прошлой версией. Ченджлог на страницу!
     
    Со времени первого коммита OC 1.6 до текущего момента прошло 465 дней. Это год и 100 дней. И ведь всё это время я ошибочно думал, что вот-вот, немного подождать, и будет 1.6.0, пару изменений ещё только.
     
    Здесь оригинал списка гигантского и ссылки на скачивание.
    У меня есть несколько записей, посвящённых обновлениям в этой версии. Если ещё их не читали, рекомендую ознакомиться.
  9. Fingercomp
    Начну со слов автора мода: "давайте будем считать, что кандидата к релизу не было. Не потому, что он был сломан, нет. Просто я добавил несколько вещей, которые требуют тестирования, поэтому у нас снова будет бета".
     
    Изменения
    ДобавленоНовая функция computer.getDeviceInfo() теперь возвращает список всех компонентов, имеющихся у устройства, включая планки памяти, процессоры и пр. Для показа их в OpenOS есть теперь команда lshw.
    [*]Изменено
    Большинство "магических файловых систем" у компонентов было перенесено в дискеты. То есть, теперь, чтобы иметь либу lib/internet.lua, например, придётся любую из уже имеющихся стандартных дискет OC (дискету OpenOS, например) в сетке крафта объединять с ключом OC (Scrench), пока не получится нужная дискета, а потом скопировать файлы с дискеты на устройство. Но есть и положительная сторона изменения: те диски стандартные, которые можно было найти только в данжах, теперь могут быть спокойно получены через тот же самый ключ. Теперь игрок не будет в AFK для сервера, если он что-то пишет в мониторах, например. Команда /oc_dn будет теперь выводить дебаг-инфу и в чат выполнившего эту команду. Та самая команда saveConfiguration, которую я внезапно обнаружил некоторое время назад, теперь таки добавлена в мануал.
    [*]Пофикшено
    Контейнеры с жидкостью могли пропадать в апгрейде-генераторе (например, cells из ИК2 с лавой). Роботы могли всасывать вёдра жидкости не из источника её в мире, а из прилегающих "текущих" блоков. Всякие внутренние функции были тоже пофикшены. Потенциальный фикс какого-то бага с серверной стойкой. gpu.setResolution возвращала false, даже если разрешение было изменено успешно. При разборке планшета теперь будет, как и положено, возвращаться с нормальным шансом контейнер апгрейдов.
    [*]OpenOS
    Добавлены devfs. Те самые магические штуки внутри /dev. /dev/null, /dev/zero. Перенаправление I/O. Это не так страшно: myprogram > stdout.log 2> stderr.log. Но объяснять, что это, не буду — кто знает, тот поймёт. Более тысячи (ТЫСЯЧИ) юнит-тестов для OpenOS. Множество мелких фиксов.



    Напомню, что разработка OC 1.6 уже заняла более 1 года и ещё 2-3 месяцев. Список изменений на релизе обещает быть огромнейшим.
     
    Скачать новую версию можно, как обычно, на билд-сервере:
    1.7.10: http://ci.cil.li/view/OpenComputers/job/OpenComputers-1.6-MC1.7.10/lastSuccessfulBuild/artifact/build/libs/OpenComputers-MC1.7.10-1.6.0.4-beta.2-universal.jar 1.8.9: http://ci.cil.li/view/OpenComputers/job/OpenComputers-1.6-MC1.8.9/lastSuccessfulBuild/artifact/build/libs/OpenComputers-MC1.8.9-1.6.0.5-beta.2.jar 1.9.4: http://ci.cil.li/view/OpenComputers/job/OpenComputers-1.6-MC1.9.4/lastSuccessfulBuild/artifact/build/libs/OpenComputers-MC1.9.4-1.6.0.1-beta.2.jar

    Или же на GitHub, если угодно.
  10. Fingercomp
    Багофиксы, в основном только они. Вот из того, что добавилось:
    У планшетов можно получать полноценное направление взгляда игрока. Количество максимальных частей пакета добавлено в информацию об устройстве (та, что computer.getDeviceInfo(). [1.10.2] Интеграция с ExtraCells и Mekanism. [1.12.2] Интеграция с ComputerCraft.

    Остальное:
    Изменили рецепт алмазных кусков по умолчанию. Пофиксили область видимости датчика движения. Планшетам разрешили отрубать экран. Дроны адекватно заставили воспринимать чанклодырное улучшение. Item conduits из EnderIO чего-то из микроконтроллеров доставали ненужного. Несовместимость с IC2 Classic устранена. В IRC-клиенте с дискеты пофиксили CTCP. [1.11.2] Какая-то бага с добавлением предметов в улучшение-БД. [1.11.2] И ещё бага с доступом к компонентам вроде дисковода в планшетах.

    Обновления в OpenOS:
    Нет необходимости теперь, в кои-то веки, писать = в начале строк в интерпретаторе Lua. Оно автоматически возвращает. Можно в error пихать таблицы, и крашиться не должно. Наконец-то разрешили монтировать системы файловые в существующие директории. Ещё можно примонтировать директорию в другое место. Если вы напишете одну команду и 10 раз другую, то в истории последняя будет только один раз. Не придётся 10 раз тыкать "вверх", чтобы первую команду получить. Фиксили проблемы с загрузкой OpenOS на медленных хостах. Я думаю, это ошибка TLWY, которая при старте кидалась. .shrc может принимать ввод. Пофиксили поиск названия клавиши по коду в либе keyboard. Фикс event.cancel и event.ignore какой-то. Интерпретатор теперь здраво воспринимает ошибки переполнения памяти в сериализаторе. Какой-то TLWY в /bin/tree.lua. Улучшения в vt100 всякие. Код стал ещё уродливее ради уменьшения потребления памяти. Вот такие улучшения.

    Вот как-то так. Отсюда качабельно.
  11. Fingercomp
    Вышла новая версия OpenComputers, в основном с самыми разными фиксами. Что изменилось:
    Моды теперь могут добавлять свои кастомные дискеты, которые можно получить перекрафтом их с ключом. (Vexatos) Две функции дебаг-карты: для отправки сообщения на другую дебаг-карту и отправки текста в буфер обмена какого-либо игрока. Опасная штука. (Vexatos) Когда роботы/дроны выкидывают что-либо в мир, они теперь посылают ивент. (Sangar) Добавлен новый предмет — MFU. Позволяет подключить к адаптеру любой блок, находящийся на удалении нескольких блоков. Это позволяет небольшие билды сделать красивее, а сложные схемы — удобнее. (Vexatos) Обновлён перевод на немецкий. (Vexatos) Обновлены LuaJ и JNLua — заявляется, что теперь всё лучше с UTF-8. (gamax92, Sangar) Обновление OpenOS. Как обычно, много изменений, но здесь опять уменьшение потребление памяти и увеличение производительности. (payonel) Дискета oppm теперь использует современные способы установки в OpenOS. А ещё программу обновили. (Vexatos) Обновление Plan9k. (magik6k) В планшетах не работал слот для карт, если было вставлено улучшение. (Vexatos) Очень труднонаходимый баг с экранами, которые после перезагрузки чанка (причём особенного) зависали, был ликвидирован. (Sangar) Больше не получится много раз потыкать ключом по дрону, чтобы получить большее их количество. (Vexatos) Устранены проблемы с вайлой (очень странная логика у неё) (Sangar) [MC 1.8.9+] При выкидывании предметов роботами или дронами некоторые уничтожались. (Vexatos) [MC 1.8.9+] Краш при использовании функции getName на нанонашинах. (Vexatos) [MC 1.9.4+] Компоненты могли не деинициализироваться, когда чанк с ними выгружался. Это приводило, например, к смене UUID компонентов. (Sangar) [MC 1.9.4+] Починили рендер клавиатуры. (Vexatos) [MC 1.9.4+] Команды ломали /help. (Vexatos) [MC 1.9.4+] В наномашинах не было эффектов зелий. (Vexatos) [MC 1.10.2+] Улучшена интеграция с JEI. (Vexatos)

    Релиз на GitHub.
  12. Fingercomp
    В прошлой части:

    Вы-то прогу скопировать/разархировать и сами можете, вот только если программа зависит от другой, а та — от двух других, и т. д., вам это надоест. Людям надоело. Создали пакетные менеджеры.  
     
     

    Итак, давайте сделаем программу для установки пакетов. Очевидно, что просто так в рандомном порядке пакеты поставить нельзя: нам надо сначала брать пакеты без неразрешённых зависимостей и подниматься вверх.  
     
     

    Итак, у нас есть простая функция, которая составляет список пакетов для последовательной установки без ломаний....
    ...Но время шло, и появилось такое явление как версии. Вот о них мы сегодня и побеседуем.  

    Зачем нужны версии? Нуууу, наверное, чтобы отмечать разные варианты кода.
    Зачем ПМ нужны версии? Хм, чтобы быть уверенным, что при установке пакета, зависимости будут именно такие, которые были при написании кода.
     
    Ну, то есть. Вчера у нас была одна функция сделатьХорошо() и попала в релиз 1.0.0, а сегодня она переименована в сделатьПлохо(), сменили код этой функции, да ещё впридачу накинули ничегоНеСделать(). Всё это в релизе 2.0.0. Но если новый код будет использовать ничегоНеСделать(), то его версия 1.0.0 не устроит — там ведь функции нет. А если нужно будет сделатьХорошо(), то в версии 2.0.0 её уже не будет.
     
    Люди — существа чертовски изобретательные, так что форматы версий у нас тоже всяко-разно изобретательны. Начиная от даты релиза (20161023) и номером билда (1243, она ещё ревизией зовётся), заканчивая полноценным семантическим версионированием. Первые потуги нас интересовать будут не сильно, а вот про SemVer можно поговорить.
     
    Спецификация SemVer прямо говорит: версия задаётся тремя числами, разделённые точкой. Первое число — мажорная версия, увеличивается, когда происходят "ломающие" изменения типа удаления старых функций, второе — минорная версия, которая на новых фичах обычно увеличивается, а третье — патчи, это всякие багфиксы.
     
    Вот сферическая версия в вакууме: 1.2.3.
     
    На самом деле, в описании semver задано несколько правил, например, место пререлиза (например, 1.2.3-dev), метаданных (например, 1.2.3+build-15+20161023+amd64), ну и т.д. Если интересно — можете почитать, ссылочка в конце.
     
    Так вот, здесь попробуем организовать разрешение зависимостей с версиями. Не будем брать пока очень мудрёную систему конфликтов.
     
    Начнём с манифеста. Дополним его указанием версий:
    { "name": "pkg1", "versions": [ { "number": "1.0.0" , "files": [ { "url": "http://example.com/pkg1/1.0.0/file1", "path": "/opt/pkg1/file1" } , { "url": "http://example.com/pkg1/1.0.0file2", "path": "/opt/pkg1/file2" } ] , "depends": [ { "name": "pkg11", "version": "^1" } , { "name": "pkg12", "version": "1.6.2" } ] } ]}
    Ну и по аналогии с другими пакетами. Вот такое чудо у нас должно получиться.



     

    Напомню, чем у нас закончилась прошлая часть:
    def resolveDeps(name, resolved=None, unresolved=None): resolved = resolved or [] unresolved = unresolved or [] if name in unresolved: raise ValueError("circular dependencies detected") if name in resolved: return resolved unresolved.append(name) if not isInstalled(name): manifest = getManifest(name) for dep in manifest["deps"]: resolveDeps(dep, resolved, unresolved) resolved.append(name) del unresolved[unresoved.index(name)] return resolved
    Давайте перепишем эту функцию так, чтобы она работала после наших изменений в манифесты:
    def resolveDeps(name, resolved=None, unresolved=None): resolved = resolved or [] unresolved = unresolved or [] if name in unresolved: raise ValueError("circular dependencies detected") if name in resolved: return resolved unresolved.append(name) if not isInstalled(name): manifest = getManifest(name) version, data = getLatestVersion(manifest) # получаем последнюю версию for dep in latest["deps"]: resolveDeps(dep["name"], resolved, unresolved) resolved.append({"name": name, "version": version) del unresolved[unresoved.index(name)] return resolved
    Всё хорошо и замечательно, вот только толку от того, что мы ввели версии, как-то нет совсем.
     

    А вот далее нам потребуется очень серьёзная либа-парсер семверов. На Python есть semantic_version, которую я ещё портировал на MoonScript — очень доволен. Но это так, будем пока плавать на более высоком уровне абстракции.
     
    Итак, версии. Тот самый граф, ещё раз:



     

    Около стрелочек висят какие-то штуки, ^1, например. Эти штуки, которые мы ещё вписываем в манифесты пакетов, ограничивают варианты версий пакетов, которые можно поставить. ^1 говорит, что можно брать любую версию не менее 1.0.0 и не более следующего мажорного релиза (2.0.0). * говорит, что пофигу абсолютно, какая версия встанет. А точное указание версии, как, например, в случае с 1.6.2, не даёт установиться какой-либо другой версии.
     
    Ну а так как они ограничивают, то и называются они ограничениями (или constriants). Пакетный менеджер — скажем так, классическая задача о соблюдении ограничений. Отнюдь не простая.
     
    Раз есть версии, есть ограничения, нужно эти ограничения, значит, включить в функцию разрешателя. Например, дополнительным аргументом. Давайте так и поступим:
    def resolveDeps(name, vconstraint="*" resolved=None, unresolved=None): resolved = resolved or [] unresolved = unresolved or [] if name in unresolved: raise ValueError("circular dependencies detected") if name in resolved: return resolved unresolved.append(name) # Создаём объект ограничения из строки vconstraint = createSemVerConstraint(vconstraint) if not isInstalled(name): manifest = getManifest(name) version, data = vconstraint.match(manifest) # получаем версию, соответствующую ограничению for dep in data["deps"]: resolveDeps(dep["name"], dep["version"], resolved, unresolved) # и не забываем передавать версию требуемую resolved.append({"name": name, "version": version) del unresolved[unresoved.index(name)] return resolved
    При запуске resolveDeps("pkg1") мы теперь получим
    [ { "name": "pkg1-1-1" , "version": "1.0.1" }, { "name": "pkg1-1" , "version": "1.2.4" }, { "name": "pkg1-2" , "version": "1.6.2" }, { "name": "pkg1" , "version": "1.2.3" }]
    Вот как это на графе будет:



     

    Давайте теперь приспособим функцию install к установке:
    def install(name): depList = resolveDeps(name) for pkg in depList: manifest = getManifest(pkg["name"]) data = getVersion(manifest, pkg["version"]) for file in data["files"]: download(file["url"], file["path"]
    В общем-то, это всё. У нас есть вполне рабочая функция установки пакетов с учётом версии по Semantic Versioning. Однако у неё есть некоторые проблемы.
     

    Ну, во-первых, мы ошибочно считаем, что если пакет установлен, то у него нужная версия. Если у нас уже будет пакет версии 1.12.53, а мы потребуем ^2, то новая версия не поставится. Рискуем попасть на глюки, баги. Кажется, надо просто обновить пакет!..
     
    Но при таком решении невозможно организовать обновление пакетов.
    Вообще. Никак. А почему?
     
    У нас зависимости задаются в версиях. Каждая версия может сменить зависимости. При этом каждая новая версия может не соблюдать ограничения, которые дают зависимые от данного пакеты.
     
    А вот вам адская ситуация:



    Так вот, чтобы обновить выделенный пакет без нарушения всех зависимостей, потребовалось разрешать конфликты версий. Это достаточно сложный алгоритм, и о нём мы поговорим как-нибудь потом. Тем более, мне только предстоит ввести в свой ПМ резолвер конфликтов.
     

    А пока можете почитать спецификацию SemVer.
     
    .
  13. Fingercomp
    Раз уж я тут пишу понемногу свой крутой пакетный манагёр, расскажу о пакетных менеджерах немного.
     
    Пакетный менеджер — штука сложная. Потому что, хотя задача у него, в общем-то, одна — менеджировать пакеты — сюда включается и установка, и удаление, и обновление, и, вообще, много всякого. Но а так как пока сам не напишешь, ПМ не поймёшь, здесь расскажу об установке пакетов и зависимостей с кодом.
     
    Ещё немного предисловий, о зависимостях. Это ключевая фича ПМ: вы-то прогу скопировать/разархировать и сами можете, вот только если программа зависит от другой, а та — от двух других, и т. д., вам это надоест. Людям надоело. Создали пакетные менеджеры. Теперь программы пакуются в пакеты — а рядом со скомпилированными бинарниками лежит ещё кусок информации: имя пакета, версии, зависимости, авторы, изменения и много-много всяких других полей. При установке данные считываются и далее уже делается, что сказано. Зависимости ли ставятся, ещё ли что-нибудь.
     
    А затем пакетов становится много, появляются репозитории полноценные, ну и так далее.
     
    Итак, давайте сделаем программу для установки пакетов. Ну, почти. Именно полезной нагрузки как таковой не будет, будем использовать такую структуру информации о пакете (назовём это манифестом пакета):
    { "name": "имя пакета", "files": [ { "url": "http://example.com/bin-1", "path": "/usr/bin/program1" } , { "url": "http://example.com/library-1.so", "path": "/usr/lib/library1.so" } ]}
    Пока без зависимостей, всё просто.
     

    Вот такой код получим:
    def install(name): # получаем манифест пакета с данным именем manifest = getManifest(name) # проходимся по файлам... for file in manifest["files"]: # ...скачиваем и ставим их в нужные места download(url=file["url"], path=file["path"])
    Ничего примечательного, на самом деле. Получаем манифест, скачиваем файлы и пишем "тадаам".
     

    Давайте сделаем вот такие манифесты:
    { "name": "pkg1" # имя пакета, "deps": # зависимости [ { "name": "pkg1-1" } , { "name": "pkg1-2" } ], "files": [ { "url": "http://example.com/pkg1/file", "path": "/opt/pkg1/file" } ]} { "name": "pkg1-1", "deps": [ { "name": "pkg1-1-1" } ], "files": [ { "url": "http://example.com/pkg1-1/file1", "path": "/opt/pkg1-1/file1" } , { "url": "http://example.com/pkg1-1/file2", "path": "/opt/pkg1-1/file2" } ]} { "name": "pkg1-1-1", "deps": [], "files": [ { "url": "http://example.com/pkg1-1-1/file", "path": "/opt/pkg1-1-1/file" } ] { "name": "pkg1-2", "deps": [], "files": [ { "url": "http://example.com/pkg1-2/file1", "path": "/opt/pkg1-2/file1" } , { "url": "http://example.com/pkg1-2/file2", "path": "/opt/pkg1-2/file2" } ]}
    У нас есть 4 пакета: pkg1, pkg1-1, pkg1-1-1, pkg1-2. Вот граф зависимостей:
     
     
     
     
     
     
     
     
     



     

    Очевидно, что просто так теперь тут в рандомном порядке пакеты поставить нельзя. Так как при установке пакета, например, pkg1-1, он совершенно справедливо считает, что его зависимость, pkg1-1-1, уже установлена.
     
    То есть, по-хорошему, нам надо сначала брать пакеты без неразрешённых зависимостей, и подниматься вверх. Однако, есть идея покруче.
     
    Я сейчас наваяю рекурсивную функцию resolveDeps, которая будет, как ни странно, разрешать зависимости:
    def resolveDeps(name): result = [] # результатирующая последовательность установки пакетов manifest = getManifest(name) for dep in manifest["deps"]: # В Python справедливен код типа `[1, 2, 3] + [4, 5, 6] == [1, 2, 3, 4, 5, 6]`, т.е. склеиваение списков. result = resolveDeps(dep["name"]) + result return result
    Если мы дадим ей манифесты, она выдаст вот такой список: ["pkg1-1-1", "pkg1-1", "pkg1-2", "pkg1"] — от менее сложного к более сложному. То, что нужно. Затем мы ставим просто их:
    for pkg in resolveDeps("pkg1"): install(pkg)
    Давайте улучшим алгоритм. Сделаем проверку на установленность: нам ведь не надо повторно скачивать файлы, которые уже есть.
    def resolveDeps(name): result = [] # Проверяем, установлен ли пакет if not isInstalled(name): manifest = getManifest(name) for dep in manifest["deps"]: result = resolveDeps(dep["name"]) + result return result
    Если у нас уже поставлен pkg1-1, то получим всего лишь ["pkg1-2", "pkg1"]. Круто!
     

    Возьмём другой граф:
     
     
     




    Как видно, от pkg1-1-1 зависят сразу 2 пакета: pkg1-1 и pkg1-2. Проблема в том, что на выходе у нас будет ["pkg1-1-1", "pkg1-1-1", "pkg1-1", "pkg1-2", "pkg1"] — ни разу не то, что мы хотели. Давайте это исправим:
    def resolveDeps(name, resolved=None): resolved = resolved or [] # список уже разрешённых пакетов if name in resolved: # Пакет уже был разрешён, ничего больше не требуется return resolved if not isInstalled(name): manifest = getManifest(name) for dep in manifest["deps"]: resolveDeps(dep["name"], resolved) # Теперь список один на всю рекурсию resolved.append(name) # Без рекурсии сюда попасть можно, если пакет не имеет неустановленных зависимостей return resolved
    Теперь выхлоп у нас ["pkg1-1-1", "pkg1-1", "pkg1-2", "pkg1"] — как и предписывали.
     

    А вот вам ещё граф:
     
     
     




     

    Какая тут засада? А у нас дерево циркулярное — не руки циркуляркой отрезает, а в бесконечную рекурсию вводит. Вот как можно этого избежать:
    def resolveDeps(name, resolved=None, unresolved=None): resolved = resolved or [] unresolved = unresolved or [] # список ещё не разрешённых пакетов if name in unresolved: # Мы попали сюда через рекурсию. Когда-то пакет уже был добавлен в список unresolved, # после чего функция ушла в рекурсивное разрешение зависимостей этого пакета. # Какой-то из зависимостей в итоге опять имеет данный пакет как зависимость. # Это ошибка, такого быть не должно, паникуем. raise ValueError("circular dependencies detected") if name in resolved: # Пакет уже был разрешён, ничего больше не требуется return resolved unresolved.append(name) if not isInstalled(name): manifest = getManifest(name) for dep in manifest["deps"]: resolveDeps(dep["name"], resolved, unresolved) # даём unresolved resolved.append(name) # Не забываем убирать из списка del unresolved[unresoved.index(name)] return resolved
    Теперь у нас в данном графе будет сгенерировано исключение, а потому рекурсии бесконечной не произойдёт.
     

    Итак, у нас есть простая функция, которая составляет список пакетов для последовательной установки без ломаний. Это уже круто, но время шло, и появилось такое явление как версии. Впрочем, об этом поговорим в другой раз. Там есть свои заморочки, с которыми нужно разобраться.
     
    Вот похожая статья, но на английском. Рекомендую ознакомиться.
     
    Лицензия: CreativeCommons Attribution-NonCommercial 4.0 International License

  14. Fingercomp
    Что-то особо нового в последнее время не виднеется, а программы не пишутся. На первый взгляд.
    Но, как известно, перед революцией обычно образуется что-то вроде застоя. Предлагаю окунуться в это болото и глянуть, что интересного происходит с OpenComputers и аддонами.
     
    OpenComputers
    Сэнгар немного прихворал, так что коммитов в последнее время немного. Идёт работа над портом 1.6 под версии MC1.8, делают OpenOS 1.6 (псст, эта игрушка обешает быть очень крутой; больше POSIX и пр.). Низкая активность на баг-трекере, в основном, всякие фич-реквесты.
    В скором будущем расскажу, что именно изменилось в 1.6.
    А пока что здесь можно загрузить на поиграться последнюю версию OC. GitHub.
     
    Computronics
    MOAR FEATURES
    Кхм. Ну, значит, бип-карту на прокачку взяли.
    1 tier: простая beep card; 2 tier: возможность указать одну из четырёх волн (синусоидную, квадратную, треугольную или пилообразную); 3 tier: в разработке, в финальном виде должна позволить создавать собственную волну. В общем, ADSR. Вот это обещает быть бомбочкой.

    GitHub. Dev-версии.
     

    OpenSecurity
    Починены турельки, очередь кейпадов. Добавлены небольшие (7 символов) экранчики на них и возможность менять символы на кнопочках.
    GitHub.
     
    Форумы
    Очень интересная программа: ServerFS. Вкратце: сетевые диски. Подробнее: имеем серв, подключаем к нему RAID и ставим tunnel/modem. На другом же компе свободно подключаемся к серверу. В /srv будут примонтированы все эти диски.
  15. Fingercomp
    ОБНОВЛЕНИЕ OPENCOMPUTERS ДО ВЕРСИИ 1.5.13 PRE 1.


     
    Спустя 20 дней, наконец-то вышла новая версия OC. Изменений немного, но пусть это не смущает Вас...
    ...Ведь в 1.5.13 появляется новая архитектура процессора: Lua 5.3! Подробнее.
     
    В этом пре-релизе появляется, как уже было сказано, новая архитектура: Lua 5.3, что и является причиной для новой версии.
    Если Вы играли с dev-билдами OC 1.5.13, Вам необходимо выставить значение enableLua53 в true. Необходимо такое было, так как новая архитектура была очень нестабильная по сравнению стабильности архитектуры на данный момент.
     
    Как поиграться с этой штуковиной? Возьмите CPU в руки, зажмите [shift] и кликните процессором. В чате появится надпись об изменении архитектуры.
     
    Кроме того, множество мелких изменений прмсутствует в этой версии, чэйнджлог который приедет уже к полному релизу.
     
    --
    Собственно, вот я и перевёл описание релиза с ГитХаба) Кстати, девелоперские версии ОС можно получить с Jenkins: http://ci.cil.li/job/OpenComputers-dev-MC1.7.10/
  16. Fingercomp
    И лучше поздно, чем никогда. Недели две-три назад вышла версия OC 1.6-RC1 (Release Candidate). В основном ничего особенного, только баг-фиксы.
     
    Изменения:
    Фиксы LuaJ с помощью мастера по починке LuaJ. gamax92, если быть точнее. Plan9k теперь будет хотя бы запускаться. Ну замечательный прогресс уже, хотя крашиться всё так же любит. Switch и Access Point были скрыты в NEI. Поддержка энергии RotaryCraft. Обновление мануала под 1.6. Облегчённые рецепты. Из алмазов делаются алмазные кусочки, которые нельзя потом собрать воедино. Опция для отключения эффектов частиц у нанытов. Работа с жидкостными реакторами IC2 через редстоун-порт. Кабели можно красить в инвентаре, они выпадают крашенными. Краска теперь тратится. Обновлён китайский перевод. Обновлён русский перевод. Фикс ачивки про свитч. Свитча-то нет. Команда /oc_sc спаунит компьютеры лицом к игроку. Баг-фиксы в OpenOS. Фикс краша при подключении нескольких серверных компонентов к одной стороне, когда при этом к ней не подключён сервер. install теперь не будет копировать ещё и файлы по символическим ссылкам. Юнит-тесты.

    В целом OC выглядит уже достаточно стабильным для игры. Новую версию можно скачать только здесь. На GitHub её нет.
  17. Fingercomp
    tl;dr: https://gist.github.com/Fingercomp/0773bb0714296c0cb00d70a696d39bb3
     
    Понятия не имею, зачем я сюда об этом пишу, ведь если вы можете этот текст понять, и в оригинале можно прочитать.
     
    В любом случае, получил намёк, что три моих статейки про звуковую карту удовлетворительны в какой-то степени, но они на русском. Видите ли, ситуация с документацией спустя полгода после первого поста не улучшилась никак, так что единственный туториал для неё недоступен для понимания тех, кто не говорит по-русски.
     
    Поэтому я потратил выходные на перевод постов на английский язык. Заняло это отчего-то дольше, чем я ожидал. Результат на гисте.
     
    Все три поста в одном месте. Я там подбросил ещё чутка инфы и терминов и подправил фактические неточности. Мне лень было несколько раз перечитывать один и тот же текст, так что где-то могут остаться очепятки и всякие извороты языковые не к месту.
    Но если понимаете английский, то всё равно должно быть удобнее, чем бегать по трём статьям здесь, в блоге. Ну а мне редактировать проще.
     
    В общем, ссылку я оставил, больше мне сказать нечего.
  18. Fingercomp
    Недавно вышло мелкое обновление OC, которое я пропустил из-за некоторых проблем, и в нём:
    ДобавленоИнтернет-карты посылают событие, когда они получили данные по сокету и можно использовать :read.
    [*]Пофикшено
    Несколько мелких багов.
    [*]OpenOS
    Небольшие фиксы install, /lib/buffer.lua, ls, /lib/package.lua, rc, /lib/sh.lua.



    Вот и всё действительно небольшое обновление. Скачать можно по ссылкам в блоке справа сверху.
  19. Fingercomp
    Обновление OpenComputers до третьей беты 1.6. Сегодня в гостях у нас следующие изменения:
    Добавлено В русский мануал добавлена информация про saveConfiguration (PR #1855 от cyber01). Функция computer.getProgramLocations, которая используется для программы install из OpenOS.
    [*]Пофикшено
    Неожиданный баг с сохранением мира в версиях MC выше 1.8.
    [*]OpenOS
    Команда cat теперь будет читать stdin, если не указан файл. cp: поддержка путей вида /. и более мелкие фиксы. df теперь поддерживает относительные пути. Функция next либы /lib/guid.lua теперь возвращает GUID в корректном формате. head теперь закрывает stdin. install был сильно переработан и теперь с помощью этой программы можно устанавливать файлы с loot-дискет (и не только), мануал в man install. less теперь поддерживает скроллинг, в кои-то веки! Ну и алиас в /etc/profile был, конечно, убран. В mv добавлено несколько проверок: команда будет выдавать теперь ошибку, если путь назначения в режиме только для чтения или путь имени для копирования — точка монтирования. У rm была пофикшена проблема, при которой ссылки на директории не могли быть удалены. Шелл поддерживает экранировку пробелов и может отдавать сигнал SIGPIPE. А ещё позволяет использовать getWorkingDirectory до установки переменной окружения PWD.



    На момент писания этого текста в install был уже обнаружен один баг, который даже пофикшен, остаётся ждать принятия PR.
     
    Github
  20. Fingercomp
    Имеется один проект на Питоне, который потребовал для себя парсер семантического версионирования, семвера, в общем. Ну там такие штуки как парсинг версий человеческий, обработка ввода юзверёв, умение сравнить все эти версии и выбрать из списка по указателю типа ">=1.5.17", ну, думаю, об этом вы слышали.
    К слову, вот тута лежит спецификация SemVer: http://semver.org/, можете почитать.
     
    Ну и нашёл я либу интересную, semantic_version зовётся. Подключил и нарадоваться не мог фичам всяким. И там пирожки, и здесь пэнкейки, в общем, использовалась весело и радостно.
     
    В рамках того же проекта ещё умещался репозиторий на мункрипте, который мункриптил очень важные дела, и ему тоже нужен был парсер. Без промедления открыл файлик того парсера, и спустя два вечера этот парсер был успешно портирован на Мункрипт, при всём при этом он даже работал! D:
    Ну, как минимум, насколько хватило желания протестить.
     
    Так что вот как-то так у нас всё получилось, я по-быстрому ознакомился с лицензией тех ребят, оформил всё более-менее и пихнул в свою репу на OpenPrograms.
     
    Потому если интересно будет когда-нибудь решить вопрос с версиями, то милости просим использовать либу libsemver, для OC её можно скачать с помощью OPPM: oppm install libsemver.
     
    Документации для либы этой именно я не писал, ибо она работает на 99% так же, как и оригинал. Потому вся инфа здесь: https://python-semanticversion.readthedocs.io/en/latest/
     
    А, ну и мой отзыв по поводу мункрипта: язык этот сумасшедший, но норм, писать можно. Ознакомиться с ним лишним явно не будет, так что осаждайте референс языка.
    Удачи!
  21. Fingercomp
    Первым делом, сохраняйте панику. Так интереснее.
    У нас есть группа в ВК, которая, в отличие от параллельных — тупиковых веток эволюции — жива и даёт продукт в виде постов. Очень интересных.
    Не любите ВК? Я тоже. Имеем мы канал в IRC: зайти можно даже с телнета. Но лучше с помощью какого-то клиента: HexChat, WeeChat, Quassel.
    Контактные данные для них:
    Сервер: irc.esper.net Порт: 6697 TLSv1.2 Канал: #cc.ru Впрочем, присутствует и веб-клиент для обитателей двумерного денежно-временного мира.
    Надо сказать, у нас даже дискорд-клуб где-то был.
    Однако не только флуждением занимается Хэш cc.ru. Мы завели организации вот тут:
    На GitHub. На GitLab. В Trello. Под кроватью. А ещё подпольные мудрости тщательно и бережно схороняются на свалку нашего цитатника, так что башорг вам больше не нужен.
    Не забудьте, по пути куда-нибудь находясь, записаться в читателей этого элитного клуба. Потому что здесь мы будем писать. Что-то.
    Отлично. Наши цепкие объятия уже ждут-поджидают вас.

  22. Fingercomp
    Многие игроки здесь видели или хотя бы слышали про огромный дронодом, который построил @Asior в былые времена на сервере RoboCraft. С тем чтобы прояснить происхождение этой хаты и оставить о ней заметку в этом клубе, специально для «Новостей подполья» @Fingercomp обратился к создателю постройки и попросил рассказать про неё. Редакция представляет обработанную версию истории.
     
    История начинается в начале мая 2016 года, когда запустился сервер RoboCraft, на который сразу же хлынули толпы игроков, хотевшие «поскорее стать топовыми игроками, обладателями гор ресурсов и, конечно же, новых идей и программ». Туда попал и герой нашего рассказа. Развитие было довольно сложным. Поначалу он «хотел, как обычно, отстроить бункер и спокойно, потихоньку наращивать силы», но этому воспрепятствовал случай: система автоматического расселения игроков закинула Asior невесть куда — в середину заражённого биома. Очевидно, что герой этому не обрадовался. Ему потому пришлось бегать в поисках нового места.
     
     
    Конечно, Asior таки организовал себе временное убежище и начал стремительное развитие в игре. Но в чате игроки часто оставляли ссылочки на скриншоты своих невероятно красивых палат с невероятно крутых ракурсов.
     
     
    Он перерыл огромное число чертежей домов, замков, статуй — и решил построить дрона. Дрона из OpenComputers. Ведь сервер специально разрабатывался для этого мода. Asior зашёл в сингл и долго, упорно воздвигал новые варианты постройки и безжалостно крушил старые. Наконец, он определился с тем, как именно должно будет выглядеть его будущее жилище. Оставалось лишь воспроизвести это всё на сервере. Но здесь и возникла основная проблема: как добыть такое огромное количество ресурсов для строительства? Разрешена она была путём не самым чистым:
     
     
    Впрочем, и того, что он раздобыл, сполна хватило на постройку основного корпуса дрона. Это потребовало огромного числа строительных лесов и невероятных акробатических способностей и дополнительно осложнялось тем фактом, что полученные вечные блоки не перемещались из хотбара. Но стиснув зубы и получая подкормку от щедрых игроков Asior таки построил дрона.
     

     
     
    Потому пришлось придумать, как расширить жилище. Некоторые предлагали соорудить какое-нибудь здание, к которому был бы «привязан» дрон, но, увы, это не вписывалось в местность.
     
     
    Далее настала очередь внутренней отделки: ставились перегородки, размещалось оборудование. А монументальное сооружение, памятник роботу и дрону, стал пользовался большой популярностью, чему создатель не противился: «я был не против, чтобы все желающие посмотрели, как я живу, уточнили какие-то вопросы или помогли чем-нибудь».
     
    С тех пор сервер RoboCraft давно закрыт, но память о роботе и дроне жива до сих пор. Редакция присоединяется к пожеланию героя остроить то, что поражало бы воображение и отпечаталось в приятных воспоминаниях десятков игроков.
     
    И мы всё так же мы призываем вас оформить подписку на «Новости подполья». Годноты здесь много было, есть — а то ли ещё будет.
  23. Fingercomp
    TL;DR: require("process").info().data.signal = function() end.
     
    С версии OpenOS 1.7.3 интеррапты работают так:
    local interrupting = uptime() - lastInterrupt > 1 and keyboard.isControlDown() and keyboard.isKeyDown(keyboard.keys.c) if interrupting then lastInterrupt = uptime() if keyboard.isAltDown() then require("process").info().data.signal("interrupted", 0) return end event.push("interrupted", lastInterrupt) end Это отрывок из /lib/event.lua. Он говорит, что если зажать Ctrl, Alt и C, то вызовется некоторая функция: require("process").info().data.signal.
     
    Программы в OpenOS запускаются в процессах. У каждого процесса есть свой главный поток (о них я писал где-то там), своё окружение. Каждый процесс следит за тем, какие файлы открыты, чтобы их закрыть при завершении процесса, жонглирует событиями и занимается сложной логикой. А ещё у каждого процесса есть свои данные. Эти данные для текущего процесса как раз возвращает process.info().data.
     
    У процессов есть иерархия. Корневой процесс — это тот, в котором запускается /init.lua. В нём устанавливается переменная signal:
    -- /boot/01_process.lua local init_thread = _coroutine.running() process.list[init_thread] = { path = "/init.lua", command = "init", env = _ENV, data = { vars={}, handles={}, io={}, --init will populate this coroutine_handler = _coroutine, signal = error -- ① }, instances = setmetatable({}, {__mode="v"}) }  
    Другие программы запускаются в дочерних процессах. Они наследуют данные родительского процесса. Поэтому process.info().data.signal, обработчик жёсткого интеррапта, по умолчанию возвращает функцию error. Но данные можно переопределить. Как видно из кода /lib/event.lua, нам достаточно, чтобы новый обработчик не вызывал error.
    require("process").info().data.signal = function(msg, level) print("You've pressed Ctrl-Alt-C!") end Это будет работать для всех потоков внутри текущего процесса, а также для других, запущенных в нём.
     
    Стоит отметить, что потоки знают, к какому процессу они прицеплены, и этот процесс можно менять на другой. thread:detach() — просто лёгкий способ сменить процесс, в котором работает поток, на корневой. А там process.info().data.signal — это функция error. Поэтому после Ctrl-Alt-C поток всё равно получит ошибку и, если она не поймана, завершится. А программа продолжит работать. Поэтому, чтобы быть совсем спокойным, можно отключить Ctrl-Alt-C глобально:
    local process = require("process") local p = process.findProcess() while p.parent do p = p.parent end p.data.signal = function() end Хотя я бы, конечно, не советовал так делать. Очень неудобно потом останавливать другие программы: приходится перезагружать компьютер.
  24. Fingercomp
    Интересные изменения:
    Добавили поддержку Lua 5.4.4. Он не сильно отличается от Lua 5.3, но у него есть атрибуты локальных переменных (<const>, <close>). Последний выглядит очень полезным. Архитектура пока экспериментальна, нужно явно включать в конфиге мода. С остальными либами Lua тоже капитальная переделка. Наконец-то пофиксили инты в методах компонентов (если вам вызов когда-либо говорил invalid key to 'next', это оно). Сами либы обновили до последних версий (например, 5.3.6) и пересобрали с оптимизациями. В том числе под 64-битные армы (линукс, мак). Чтобы не путаться, на текстуре блока redstone i/o точками, как у игральной кости, показывается, какая это сторона: . Теперь рисуются юникод-символы выше U+FFFF. Там, например, всякие емоджи запиханы. Лишь бы в шрифте глифы под них имелись. Патчить шрифт можно ресурс-паками. Причём необязательно собирать глифы для всех символов: если в ресурс-паке глиф не указан, то он берётся из шрифта мода. Интернет-карту переписали на другую HTTP-библиотеку, чтобы она умела слать PATCH-запросы. Ссылка: 1.7.10 / 1.12.2.
×
×
  • Создать...