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

Поиск по сайту

Результаты поиска по тегам 'Lua'.

  • Поиск по тегам

    Введите теги через запятую.
  • Поиск по автору

Тип публикаций


Блоги

  • Робот Байт
  • Fingercomp's Playground
  • 1Ridav' - блог
  • Totoro Cookies
  • Блог cyber01
  • IncluderWorld
  • KelLiN' - блог
  • Крутой блог
  • eutomatic blog
  • Programist135 Soft
  • Сайт в сети OpenNet
  • PieLand
  • Очумелые ручки
  • Блог недоблоггера
  • В мире Майнкрафт
  • LaineBlog
  • Квантовый блог
  • Блог qwertyMAN'а
  • ДубоБлог
  • Дача Игоря

Форумы

  • Программирование
    • Программы
    • База знаний
    • Разработчикам
    • Вопросы
  • Игровой раздел
    • Игровые серверы
    • Предложения по улучшению игрового процесса
    • Моды и плагины
    • Жалобы на игроков
    • Ивенты
  • Общение
    • Вопрос-ответ
    • Беседка программистов
    • Беседка-флудилка
    • Шкатулка
  • Технический раздел
    • Багтрекер
    • Архив

Искать результаты в...

Искать результаты, которые...


Дата создания

  • Начать

    Конец


Последнее обновление

  • Начать

    Конец


Фильтр по количеству...

Зарегистрирован

  • Начать

    Конец


Группа


AIM


MSN


Сайт


ICQ


Yahoo


Jabber


Skype


ВКонтакте


Gtalk


Facebook


Twitter


Город


Интересы

Найдено 170 результатов

  1. Fingercomp

    OpenOS. Потоки

    Потоки — очень полезные штуки, позволяющие исполнять несколько кусков кода. Раньше для их использования приходилось скачивать отдельную библиотеку, работающую через костыли. Начиная с OpenOS 1.6.4, они есть в стандартной поставке ОС — в модуле thread. Давайте посмотрим, из чего она состоит — и в чём её преимущество перед любыми другим библиотеками. Начнём с версий. OpenOS 1.6.4 — версия, включённая в OpenComputers 1.7.0. Если не хотите возиться с обновлением системы вручную, требуется иметь версию выше или равную 1.7.0. Сразу обращаю внимание на самую важную вещь: потоки не могут исполняться одновременно. В один момент времени только один поток может работать. В чём тогда красота тредов? Они автономны, то есть: Начинают исполнение сразу же после создания. Передают исполнение в другие потоки в местах, указанных использователем, — при том или ином вызове computer.pullSignal (os.sleep, event.pull и т. д.). Автоматически продолжают своё исполнение без необходимости самостоятельно их стартовать. Потоки можно убить и приостановить. Они неблокирующие: Вызов computer.pullSignal не блокирует исполнение других потоков. Они отцепляемые: Процесс, в котором был создан поток, называется родительским. При завершении родительского процесса все потоки останавливаются. Поток может отсоединиться от родительского процесса и работать полностью автономно — например, как слушатели событий. Поток может сменить родителя на другого. Поток сам является процессом и потому может создавать дочерние потоки. Работающий поток не даёт завершиться своему родителю. Они независимы при обработке событий: Потоки не наследуют и не передают дочерним свой набор слушателей событий. Все слушатели событий и таймеры принадлежат только конкретному потоку. Как следствие, поток не может изменять их набор в другом. Слушатели и таймеры автоматически удаляются при завершении потока, даже если завершение вызвано ошибкой. Приостановленные потоки игнорирует события. Если несколько потоков вызвали event.pull на одно и то же событие, они оба его получат. Этот набор фич в таком объёме присутствует только в этой библиотеке, и ни одна другая и не даёт столько простоты в работе с ними. Пожалуй, приступим к использованию. Потоки создаются функцией thread.create: первым аргументом передаётся функция, дальше идут аргументы к ней. local thread = require("thread") local t = thread.create(function(a, b) print("В потоке получены аргументы:", a, b) end, 21, 42) Функция возвращает объект потока. Его же может получить сам поток вызовом thread.current() — однако если вызвана не в потоке, то возвращает nil. На всякий случай, основной процесс не является потоком. Объект потока позволяет чудить различные вещи с потоком. t:suspend() приостанавливает поток. Как уже сказано, такой поток не будет получать события и обрабатывать тики таймера. Забавно, что если приостановить поток, когда он ждёт события, то неизвестно, что он получит после его возобновления. t:resume() возобновляет работу ранее приостановленного потока. Так как созданные потоки сразу начинают работу, то обычно этот метод вызывать не придётся. t:kill() убивает поток, то есть завершает его, удаляя всех слушателей и таймеры. Возобновить работу потока после того, как он убит, нельзя. t:status() возвращает строку со статусом потока: "running" — поток работает или блокирован другим. Такой поток не даёт завершиться своему родителю. "suspended" — поток приостановлен. Его дочерние потоки также будут приостановлены. Когда родительский процесс завершается, такой поток автоматически убивается. "dead" — поток мёртв. t:attach() позволяет сменить родителя у потока. Без аргумента поток будет присоединён к текущему процессу. Переданное как аргумент число позволяет указать, к кому присоединить: 0 — текущий процесс, 1 — родитель текущего и т. д. t:detach() отцепляет поток от родителя. Такой поток будет работать до его остановки или перезагрузки компьютера. t:join() останавливает процесс, в котором была вызвана это функция, до завершения потока t. local thread = require("thread") local t = thread.create(function() os.sleep(10) end) t:join() -- остановится на 10 секунд Можно передать первым аргументом этой функции число, которое будет служит таймаутом (в секундах). Тогда, если не успеет завершиться поток за это время, join завершится досрочно. t:join ждёт только одного потока. Для групп потоков есть функции thread.waitForAny и thread.waitForAll — обратите внимание, что это функции библиотеки, а не методы объекта потока. Обе функции первым аргументом требуют таблицу с потоками, а вторым опционально можно задать таймаут. thread.waitForAll ждёт, пока завершатся все потоки из списка. local thread = require("thread") local t1 = thread.create(function() os.sleep(10) end) local t2 = thread.create(function() os.sleep(15) end) thread.waitForAll({t1, t2}) print("Это сообщение будет написано через 15 секунд") thread.waitForAny ждёт, пока завершится хотя бы один поток из списка. local thread = require("thread") local t1 = thread.create(function() os.sleep(10) end) local t2 = thread.create(function() os.sleep(15) end) thread.waitForAny({t1, t2}) print("Это сообщение будет написано через 10 секунд") Что будет, если поток бросает ошибку? При ошибке в потоке она не будет проброшена в родительский процесс. Как и со слушателями, она будет записана в файл /tmp/event.log, но родитель не сможет узнать причину ошибки — и, вообще, успешно ли завершился поток. local thread = require("thread") local t = thread.create(function() os.sleep(3) error("test") end) print(t:status()) --> running t:join() print(t:status()) --> dead Кроме того, событие жёстокого прерывания (Ctrl+Alt+C) не передаётся всем процессам — только одному; причём неизвестно, какому именно: родителю или одному из его потоков. Если вы используете потоки, первым делом сделайте один, который будет ждать события interrupted и подчищать ресурсы. local thread = require("thread") local cleanupThread = thread.create(function() event.pull("interrupted") print("Принял ^C, чищу всякие ресурсы") end) local mainThread = thread.create(function() while true do local input = io.read() if input == "exit" then break end end end) thread.waitForAny({cleanupThread, mainThread}) os.exit(0) Обратите внимание, что в конце программы стоит os.exit. Я уже упоминал не раз, что родительский процесс, достигнув конца программы, не завершится до тех пор, пока работает хотя бы один из его дочерних потоков. Вызов os.exit() позволяет выйти из программы, закрыв все дочерние потоки. Что, безусловно, достаточно удобно. Есть ещё один момент. Допустим, данная программа запускается в роботе: local robot = require("robot") local thread = require("thread") local moveThread = thread.create(function() while true do robot.forward() end end) local inputThread = thread.create(function() while true do local input = io.read() if input == "exit" then break end end end) thread.waitForAny({inputThread, moveThread}) os.exit(0) Если вы запустите эту программу, то должны заметить, что вы ничего не сможете написать в роботе, хотя работает io.read. Дело в том, что функция robot.forward вызывает метод компонента, который блокирует исполнение компьютера. Пока робот двигается, на компьютере не может выполняться ни одна команда. Чтобы хоть что-то можно было вставить в строку, то поставьте после robot.forward какой-нибудь os.sleep(0) — он позволит соседнему потоку принять и обработать события. Тем не менее, строка ввода всё равно будет работать с тормозами. В подобном случае задумайтесь над тем, чтобы использовать вместо строки ввода иное средство коммуникации: редстоун, сеть, интернет-сокет. Несмотря на всё, библиотека действительно облегчает работу с потоками в OpenOS. Кроме того, очень удобно поместить все слушатели событий в один поток, чтобы они все автоматически были удалены после убийства потока. local event = require("event") thread = require("thread") local mainThread = thread.create(function() event.listen("key_down", function(evt, addr, key, code, user) print("A key has been pressed!") end) while true do print("do something") os.sleep(0.5) end end) -- событие interrupted не ловится обработчиками local intThread = thread.create(function() event.pull("interrupted") end) thread.waitForAny({mainThread, intThread}) os.exit(0) Не нужно функции сохранять в переменные и помнить, что нужно ставить event.ignore в конце программы; не требуется ребутать компьютер, если программа завершилась с ошибкой, а до отключения слушателей дело не дошло. В общем, красота.
  2. Fingercomp

    Прокачка стектрейса

    Эта беспрецедентно короткая запись имеет начало своих ног в запросе @Laine_prikol, как-то спросивший в нашей ирке, можно ли стэктрейс сделать не таким тупым. Меня это заинтересовало, и спустя часик выросла очень короткая программка, которая рисует вот такие стэктрейсы: # 0: C field function yield(...) (defined in [C]) # 1: Lua local function f(f=function: 0x559402b83590, a=42, b=24, vararg test, nil):109 (defined in trace.lua at L108) # 2: Lua local function outer(f=function: 0x5594040b2230, g=function: 0x559402b83590, a=42, b=24, <... (1 arg)>):105 (defined in trace.lua at L103) # 3: Lua function <anon>():113 (defined in trace.lua at L102) Заметили что-то необычное? Наконец-то пишется, какие аргументы имеются у функции, потому что это куда информативнее беглому взгляду, чем описание расположения и строки. Код лежит на гисте: https://gist.github.com/Fingercomp/a688d221356cb371d940b947d0ca90a8. Использованы функции debug.getinfo и debug.getlocal. Аргументы должны писаться даже внутри OC, но уже без значений.
  3. @Krutoy когда-то писал про IDE для Lua, но с тех пор, я надеюсь, всё достаточно преобразилось, чтобы снова подошло время задать следующий вопрос: «Какие есть окружения разработки для Lua?» Желательно интегрированные. Иными словами: редактор кода полноценный (само собою); автодополнение (уже никуда без этого); дебаггер; поддержка множества окружений Lua (так, чтобы можно было и OpenOS встроить); неубогий вид; линтер, автоформаттер; статический анализатор кода; инструменты рефакторинга; сборка, запуск, деплой; конфигурируемость и удобность. Неплохими примочками была бы ещё поддержка C, C++ на уровне, но здесь, впрочем, можно и CLion/Eclipse поставить. Если есть опыт использования, интересно было бы услышать его тоже. Например: vim — из списка только 2 пункта есть: первый и последний. Творить лютую жесть можно (для однотипного изменения есть и реплейс по регексу полноценный, и макросы, которыми я довольно часто пользуюсь), к тому же, он легковесный и шустрый очень. Но без остальных пунктов как-то печально писать код.
  4. Зачастую на серверах с техносборками ставится базовая коллекция модов: IndustrialCraft BuildCraft OpenComputers Благодаря моду билдкрафта в мире генерируются озера нефти, особенно огромные они в море. Если у вас хватит терпения его выкачать и переработать в дизельное топливо, то наверняка появится вопрос, куда это топливо девать кроме как как в двигатели внутреннего сгорания. В моде IndustrialCraft есть очень интересный генератор со сложным крафтом - полужидкостный генератор. Его особенность в том, что он может вырабатывать из топлива 32 eu/t, но есть большая проблема, передавать в провода он может только 20 eu/t. Данная проблема проявляется только на сервере, в одиночке все нормально. Возможно это разработчики что-то напутали, или так задумано, или чьи-то кривые ручки не туда тыкнули в настройках сервера, однако с 1 ведра топлива можно легко получить 128000 eu. Если запустить его в автоматическом режиме, то он начнет работать импульсами - зарядка внутреннего буфера, отключение, передача 20 eu в провода, включение, зарядка внутреннего буфера ... и т.д Но при этом топливо будет расходоваться не полностью, а с огромными потерями. По 5 мл на запуск, что не есть хорошо. Поэтому буфер всегда должен быть свободен. А постоянно мониторить и вовремя сливать энергию может обычный компьютер из мода OpenComputers. Итак, представляю вашему вниманию автоматический контроллер полужидкостных генераторов на ОС. Я разделил программу для генераторов на 3 уровня. Везде используются разные программы, но они работают на одном и том же принципе. Выбирайте то, что вам больше по душе и вперед строить! Генератор высокого класса Делается чисто на декор и понты Для тех, у кого туго с ресурсами, предлагаю генератор среднего класса. Он не настолько красивый, графония вообще не имеет, но главное, что он довольно низок по потреблению памяти, а так-же скорость обработки данных в разы шустрее. Из минусов - он нессиметричный, хотя это уже дело вкуса каждого. При желании можете налепить батареек и будет вам симметрия. Ну и последний тип генератора - бюджетный на микроконтроллере. От остальных он отличается крайне дешевыми компонентами, хотя со сборкой придется повозиться. Вот такие интересные получились контроллеры полужидкостных реакторов. Качайте нефть скорее, её не так много во всем мире ...
  5. Как вы уже видели, программа бесполезная. Просто поставьте комп с видеокартой 2 уровня, большой монитор 2 уровня где нибудь на улице, и установите на него OpenOS. Вы можете редактировать текст, изменяя данные в таблице (она в коде, не зря меня Монстрик учил). Ну что, разбираем. http://pastebin.com/PwhkZTb0
  6. Дело было вечером, делать было нечего... И тут я случайно зажал горячую клавишу калькулятора, и меня осенило! А ведь калькулятора то для ОС никто не писал еще! Так появилась идея создания этого калькулятора. Что можно про него сказать? Базовый калькулятор который умеет выполнять стандартные математические операции. Требования к ОС: Видеокарта 2 уровня и выше Монитор 2 уровня и выше Компьютер/сервер любого уровня с установленной OpenOS Управление самое простое - мышкой. При создании программы была взята статья Псевдографические интерфейсы в OpenComputers и на основе кода из неё был создан калькулятор. Установка: version 0.2 pastebin -get PaVaRGcd Calculator.lua version 0.3 pastebin -get ZjCTrj5a Calculator.lua P.S. Выражаю благодарность @Doob за статью. Если найдете какие-то баги, недочеты, или возникнут идеи по улучшению, я всех с радостью выслушаю.
  7. Игра "Determinant" Пилим игру всем форумом на LÖVE. Жанр: top-down шутер в стиле Crimson Land. Сеттинг математический: считаем определители матриц 10х10, бьем врагов знаком интеграла, дифференцируем экспоненту. Предполагается наличие мультиплеера. Графон двухмерный, векторный — рисовать будет @Totoro. @Totoro предложил вести разработку по принципу Git Flow: создаем feature ветку, ревьюим, мержим в dev, затем dev мержим в master и выпускаем релиз. Репа: https://gitlab.com/cc-ru/determinant. Присоединяемся. Обсуждаем в IRC.
  8. Всем здрасти. Скрины: Клиент 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
  9. С новым годом, обитатели computercraft.ru! Сегодня, вашему вниманию я представляю игру "Атака бактерий мутантов v0.2". Предыстория: На космическом корабле проводились опыты, по выращиванию бактерий в агрессивной среде. Но случилась авария и космический корабль постигла страшная участь разгерметизации. И лишь сильнейшие бактерии, на кусочке стекла, остались одни в космосе. Смогут ли они адаптироваться? Смогут ли эволюционировать? Смогут ли выжить в этой агрессивной среде? Решать вам! Концепция: Игра разделена на этапы. На данный момент доступно только 2 этапа. 1 этап - мы управляем синий бактерией которая путём реактивного движения должна набрать нужную массу поглощая других бактерий. (в космосе, потом в воде на планете) 2 этап - бактерии научились ходить (действия происходят на планете, на суши) 3 этап - бактерии напали на местных жителей планеты и управляют их сознанием. Могут ПКМ переселяться из тела в тело. Нужно переселяться от меньшего противника к большему, пока те не перестреляли друг друга. В это время происходит гражданская война и инопланетяне друг друга убивают из бластеров стреляющих антивеществом. 4 этап - планета захвачена, нужно управляя телом инопланетянина участвовать в гражданской войне за звание лидера планеты. 5 этап - отбить атаку других инопланетян. Можно кататься в танке. Можно отдавать приказы и управлять союзниками. В прочем, планы на будущее могут сильно меняться. Вполне возможно что эволюция бактерий будет происходить по другому пути чем задумана сейчас. Проблема недостатка художников может совсем свести все планы на нуль. Начиная с 3 этапа нужно рисовать спрайты персонажей, а это не все могут. Что есть в игре: Реалистичная физика 2 режима игры (будет больше) Несколько тестовых уровней, чтобы проверить работоспособность игры (но можно добавить сколько угодно) Параллакс скроллинг планет на фоне Разноцветные, реалистичные звёзды на фоне Логотип и его анимация Миникарта Режим разработчика Менюшки Рабочие настройки (правда не сохранятся при перезапуске) Лёгкое добавление уровней и изменение их свойств Тестовая консоль Антивещество Зум Горячие клавиши во время игры: i - режим разработчика, включаются всякие индикаторы полезные для тестов m - отключаемая миникарта e - переход на следующий уровень, если набрана нужная масса ` - включить тестовую консоль (используется для выявления багов) Управление: Колесо мыши - зум ЛКМ в первом режиме игры даёт выброс массы (реактивное перемещение) Скрины: Видео обзор: (Видео затянутое. Для просмотра геймплея проматывайте до второй части, 1 минуты) Установка: Распаковываем архив и играем. Ссылка на архив: https://yadi.sk/d/1GBAgr71moH2s От разработчиков: Разработку ведут 2 человека: qwertyMAN и electronic_steve + один художник, предоставивший нам изображения планет. Игра позиционирует себя как клон игр Osmos, Spore и Tasty Planet. Написана на lua, с использованием движка love2d. В игре присутствуют заготовки на будущее: Индикатор прогресса в режиме разработчика, свойство наличия ИИ, которое пока не используется в клетках.
  10. В луа можно обрезать строку? Например мне нужно читать сообщения из чата с помощью чат-бокса, искать в сообщении плохие слова и выдавать куда-то уже сообщения без плохих слов. В библиотеке string ничего не нашёл((
  11. Я видел статью про ООП (Объектно-Ориентированного Программирования), написанную на этом форуме, и вот, что могу сказать, он может быть немного непонятен новичкам в Lua. Я всегда пользовался другим способом создания "классов". Сначала следует разобраться со значениями. Класс - это набор методов (в нашем случае функций), процедур и переменных которые дальше будут наследоваться объектом или другим классом. Объектами называют сущности, обладающие набором свойств и операций над ними. Объект - это производное класса. В Lua классов как таковых нет, но если пофантазировать, то можно представить функцию как класс, а объект как таблицу. Создание простого псевдо-класса Наследование Экономия оперативной памяти Только читаемые свойства Вывод. Этот способ реализации ООП в Lua будет работать и в OC и в СС. "Классы" очень похожи на классы из других языков программирования. В моём варианте нет двоеточия, которое приносит странную возможность обработки одного объекта методом другого. Использовать ООП в игре можно для удобной разметки интерфейса в вашей программе (например для создания кнопок), и для экономии системных ресурсов в вашем компьютере внутри компьютера.
  12. Можно ли в чистой Lua (ну или той которая используется в OC) сделать так чтобы две функции выполнялись ДЕЙСТВИТЕЛЬНО одновременно?
  13. Всем привет! В этой теме я расскажу моей программе ---Удалённом рабочем столе на сети OpenNet и моде OpenComputers. Первым делом расскажу как ей пользоваться. Ввод данных: Всё очень просто=) Жмёте на кнопку на клавиатуре, и её нажатие эмитируется на удалённом компьютере. Для обновления экрана --- F5 Для выхода из программы на удалённом компьютере --- F2 Для выхода из программы на локальном компьютере ---F1 Ну....Вроде всё по управлению=) Запуск,настройка и подключение: Подготовка к запуску удалённого терминала: Установить библиотеку thread: local computer = require("computer") computer.SingleThread = computer.pullSignal local thread = {} local mainThread local timeouts local function MultiThread( _timeout ) if coroutine.running()==mainThread then local mintime = _timeout or math.huge local co=next(timeouts) while co do if coroutine.status( co ) == "dead" then timeouts[co],co=nil,next(timeouts,co) else if timeouts[co] < mintime then mintime=timeouts[co] end co=next(timeouts,co) end end if not next(timeouts) then computer.pullSignal=computer.SingleThread computer.pushSignal("AllThreadsDead") end local event={computer.SingleThread(mintime)} local ok, param for co in pairs(timeouts) do ok, param = coroutine.resume( co, table.unpack(event) ) if not ok then timeouts={} error( param ) else timeouts[co] = param or math.huge end end return table.unpack(event) else return coroutine.yield( _timeout ) end end function thread.init() mainThread=coroutine.running() timeouts={} end function thread.create(f,...) computer.pullSignal=MultiThread local co=coroutine.create(f) timeouts[co]=math.huge local ok, param = coroutine.resume( co, ... ) if not ok then timeouts={} error( param ) else timeouts[co] = param or '' end return co end function thread.kill(co) timeouts[co]=nil end function thread.killAll() timeouts={} computer.pullSignal=computer.SingleThread end function thread.waitForAll() repeat until MultiThread()=="AllThreadsDead" end ------------------------------------------------------------------------------- return thread (Только на сервер,на клиенте она не нужна) Установить OpenNet и находится в зоне его покрытия. Установить на сервер его часть: local event= require("event") local thread= require("thread") local opennet= require("opennet") local computer= require("computer") local gpu= require("component").gpu local unicode= require("unicode") local keyboard= require("component").keyboard.address local IP, dis2serv = opennet.getIP() print("Local IP: "..IP) args={...} if args[1]==nil then print("Использование: openviewerS <opennet_ip>") os.exit() end --[[ _, result, reason = opennet.sendrec(args[1], "connecting...") if result==false then print(reason); os.exit() end if args[1]==IP then print("Невозможно инициализировать удалённый доступ со своим устройством.") os.exit() end ]]-- initial=args[1] local function getScreen() screen="" for y=1, 25 do for x=1, 80 do symbol = gpu.get(x, y) screen=screen..symbol end end return screen end local function sendScreen() opennet.send(initial, getScreen()) end function runShell() os.execute("sh") end function reInitial() thread.killAll() thread.init() thread.create(runShell) thread.create(EmulateSignal) thread.waitForAll() end event.listen("Screen", sendScreen) event.listen("Exit", reInitial) function EmulateSignal() while true do opennetIP, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 = opennet.receive() if opennetIP==initial then computer.pushSignal(arg1, keyboard, tonumber(arg3), tonumber(arg4), arg5) end end end thread.init() thread.create(runShell) thread.create(EmulateSignal) thread.waitForAll() Установить на клиент клиентскую часть: local opennet= require("opennet") local term= require("term") local unicode= require("unicode") local event= require("event") args={...} if args[1]==nil then print("Использование: openviewerC <opennet_ip>") os.exit() end initial=args[1] function getScreen() repeat ip, screenRaw=opennet.receive() until ip==initial for sym=1, #screenRaw-160 do io.write(unicode.sub(screenRaw, sym, sym)) end end term.clear() opennet.send(initial, "Screen") getScreen() while true do arg1, arg2, arg3, arg4, arg5 = event.pull() if arg1=="key_down" and arg3==0 and arg4==63 then term.clear() opennet.send(initial, "Screen") getScreen() elseif arg1=="key_down" and arg3==0 and arg4==59 then os.exit() elseif arg1=="key_down" and arg3==0 and arg4==60 then opennet.send(initial, "Exit") else opennet.send(initial, arg1, arg2, arg3, arg4, arg5) end end Для запуска программы надо написать на сервере: openviewerS <IP Адрес клиента> ВНИМАНИЕ!!! Надо ввести именно IP, а не DNS; Единственное поддерживаемое разрешение - 80x25 На клиенте же пишем: openviewerC <IP Адрес сервера> Вот и всё=) Надеюсь,эта программа вам будет полезна ! Неплохо было-бы попасть в вайт-лист
  14. Перенос статьи Эта тема была перенесена из блока "Статьи". Автор оригинала: Krutoy. Как известно, чем лучше инструмент, тем выше скорость работы. Я программирую на Lua больше года, и перепробовал множество инструментов. В этой статье я покажу, какие есть инструменты для успешного программирования на Lua для двух модов Minecraft'а: ComputerCraft и OpenComputers. 1. Внутриигровой редактор Умеет уйму недостатков и неудобен в работе, за то всегда под рукой. Для ComputerCraft есть программа "LuaIDE", которая входит в состав операционки OneOS (второй скрин) Для OpenComputers пока редакторов кроме стандартного нет. Пара советов для редактора OC: Для быстрого поиска существующего файла в консоли введите первые символы и жмите TAB, например edit i [TAB] --> edit /init.lua Для удаления всей строки нажмите CTRL+DELETE 2. Текстовые редакторы Их несколько: Notepad++ Стандарт скриптовика. Прост и легок в обращении. Плюсы - малый размер, куча плагинов и расширений. Лучшее средство для начинающего программиста Lua. Sublime Text Более продвинутый инструмент. Плюсы - расширенный интерфейс, выбор из разнообразных тем, поддержка плагинов, включая подсветку ошибок при написании кода. Сам пользуюсь этим редактором на компе, расширив плагинами Corona Editor, Lua Love, Sublime Linter - lua SciTE, Atom Для хипстеров. По функционалу такие же как выше. Для удобной работы с компьютерными модами есть несколько приемов: - Через папку сохранения в одиночной игре: В Windows это папка, примерно C:\Users\UserName\AppData\Roaming\.MC\ServerName\saves\Computers\opencomputers\address-address-add-addrs Сохраненные файлы в папке жесткого диска игрового компьютера будут тут же там обновляться. Не забудьте изменить в конфиге \config\OpenComputers.cfg значение bufferChanges на false: - Через Pastebin: Пишете код в редакторе Вставляете его на Pastebin Вписываете код для запуска в игре (заменив XXXXXX на код пасты): pastebin get XXXXXX name - Через облачное хранилище с прямыми ссылками: Сохраняйте и работайте с файлами прямо в папке облачного хранилища, с возможностью доступа по прямым ссылкам. Например, в дропбоксе это папка Public (в новых аккаунтах ее нет) Загружайте обновленные файлы на ОС компьютер через интернет-плату программой wget, получив прямую ссылку на файл, например: wget -f https://dl.dropboxusercontent.com/u/12345678/file.lua Для удобства вы можете написать короткую программу, которая при нажатии клавиши, например F5, будет выполнять такую загрузку автоматически 3. IDE IDE - Интегрированная среда разработки. Это мощное средство редактирования и отладки кода. Сильно упрощает работу с большими проектами, но более сложен в освоении. Основное преимущество IDE - отладка кода посредством точек останова и отображения значений переменных при работе программы. Рассмотрим по отдельности: ZeroBrane Studio Суперлегкая (у меня занимает 17мб оперативки) и быстрая кроссплатформенная IDE. Визуальные темы, мониторинг переменных, выделение локальных и глобальных переменных, проверка на неиспользуемые переменные и прочие ништяки. Lua Development Tools Преимуществ от ZeroBrane практически нет, скорее минусы в роде отсутствие темной темы и требовательности к оперативке. Cloud 9 Облачное браузерное IDE. По стандарту отсутствует отладка. Ее нужно устанавливать в проект самостоятельно. Плюс - вам не нужно ничего устанавливать на компьютер. Но самое приятное, что к каждому файлу в этой IDE можно обратиться по постоянной прямой ссылке, что крайне упрощает заливку файла в игру. Так же, вы можете раздавать ссылку на проект другим и совместно редактировать код. Сам я использую Sublime для быстрого редактирования файлов, LDT для больших проектов на стадии написания кода, Cloud9 для совместных проектов с другими программистами, и для отладки текущих проектов в игре. О ZeroBrane Studio узнал совсем недавно, поэтому планирую перейти на нее в ближайшее время, что и другим советую.
  15. Сделал кнопку через библиотеку forms.lua. Врубаю прогу, всё появляется, но программа почему-то не продолжает свою работу, а выключается сразу после отрисовки всех компонентов. addButton делал по инструкции
  16. Я предлагаю запилить экспериментальный проект. Кодовое название - "Цитадель". Кавайная заставочка - сверху. Суть вкратце такова. Необходимо полностью развиться в Minecraft, с нуля, используя ТОЛЬКО роботов и дронов из OpenComputers. Делать что либо руками запрещается. (Если кто-то читает мою группу в ВК, там мелькал пост одного чувака, который снимает серию летсплеев с похожей идеей.) Для проекта берём сервер в сингле (например). Ставим несложную сборку - например Minecraft 1.12 + OpenComputers 1.7 + какой-нибудь тех. мод с хорошей OC-интеграцией, например - Mekanism. Далее генерим мир. Игрок будет обитать на спавне - в стартовой базе. У него в наличии будет: * закрытый ангар, в котором он живёт (выходить из него игроку нельзя), * вечный источник энергии, * компьютер третьего тира с беспроводной картой и интернет-платой, * пять доков с роботами (док - это ячейка с зарядником и люком наружу, где стоит робот), * пять доков с дронами, * небольшой запас провизии на первое время. Конфигурация дронов и роботов - тир три, с вайфай-картами и чанклодерами. На компы и роботов установлена OpenOS последней версии. Дроны прошиты нет-флашем. Основные задачи проекта: * наладить поставку провизии игроку * наладить добычу и хранение важных ресурсов * развернуть репликацию роботов и дронов Условие поражения: * потеряны все роботы и не выполнены основные задачи Сюжетный обоснуй: Игрок не совсем удачно десантировался с орбиты. У него мало ресурсов, но сохранился рабочий комплект робототехники и ядерный энергогенератор с ресурсом в тысячу лет бесперебойной работы. Атмосфера планеты непригодна для жизни человека. Что думаете по поводу идеи? Какие моды должны войти в состав сборки? Какие технические препятствия видите? Какие поправки стоит внести в стартовые условия? Какие действия по вашему стоит предпринять игроку первым делом?
  17. Программка написанная на love2D рисует фракталы, ставя новую точку проходя определённое расстояние от предыдущей точки до случайно выбранной вершины предварительно нарисованной фигуры. Подробнее в этом видео. Как использовать: Запускаем, ставим мышью несколько точек, выбираем расстояние, которое будет проходить точка (начальная ставится случайно), пробел - пошагово, А - автоматически рисуем. Ну там в окошке есть инфо по управлению. По умолчанию расстояние 1/2, идеально для треугольника, для фигур с большим количеством точек лучше уменьшить. В общем играйтесь кому интересно, скачать скомпилированный вариант можно с гугл диска.
  18. Сколько вы можете придумать способов напечатать фразу "Hello World!" десять раз, при помощи Луа? Мой вклад в копилку: 1) Рекурсией function hello(times) if times > 0 then print "Hello World!"; hello(times-1) end end hello(10) 2) Заменой local source = " " local hello = source:gsub(" ", "Hello World!\n") print(hello)
  19. Кнопки, это самый распространенный элемент интерфейса, и не потому, что их полно в каждой графической программе. Функционал кнопки наследует большинство средство ввода, например: ссылки, переключатели, ползунки, менюшки и т. д. Сейчас, огромные возможности для создания других, более подходящих ситуации способов ввода, но традиционно используются кнопки, которые появились в первых электронных устройствах, т. к. они просты и интуитивно понятны. Внешний вид. Обычная кнопка имеет прямоугольный вид, это позволяет не заморачиваться с алгоритмом взаимодействия, удобно отображать на ней текст/изображения, но если необходимо, ее можно сделать какой угодно формы. Самое главное в кнопке это ее интерактивность, т. е. она должна не только выполнять функцию, для которой назначена, но и сигнализировать свой статус (иметь обратную связь). Например, при нажатии на кнопку, она меняет цвет/визуально проваливается/издает звук, все это вместе или по-отдельности дает пользователю знать, что она активирована, а цветом или звуком можно даже передать состояние выполнения задачи, выполняемой этой кнопкой. А вот если пользователь нажимает на кнопку и ничего не происходит, то он может клацнуть по ней еще много раз, пока кнопка будет выполнять задачу. В большинстве случаев это довольно опасно - накликают беду, а винят программиста. Поэтому, если в текущей ситуации кнопка неактивна, надо это подчеркнуть, например, обесцветив ее или частично слив с фоном, можно дополнить специальным звуком. Все это очевидно, поэтому не стоит об этом забывать. Внутреннее устройство. В графическом интерфейсе, кнопка это определенно обозначенное место на экране, в которое нужно тыкнуть, чтобы получить определенный результат, обозначенный на кнопке в виде текста/изображения или понимаемый из контекста. Как это реализовать в OpenComputers? Нам доступен вывод информации на монитор, посредством компонента GPU. Пока рассмотрим функции назначения цветов и вывода символов. Работа с видеокартой. Список методов видеокарты можно посмотреть на вики. Для назначения цвета текста используется метод setForeground. А чтобы задать цвет фона, есть метод setBackground. Чтобы проверить, как это работает обратимся к компьютеру с установленной OpenOS. Запустим компьютер. Вводим команду edit gpu_test.lua, так мы запускаем текстовый редактор OpenOS, указывая, что нужно редактировать файл gpu_test.lua. Пока этого файла нет, но когда в редакторе нажмем Ctrl+S он сохранится. Чтобы мы могли обратится к компоненту gpu, нам надо загрузить обертку для компонентов, предоставляемую OpenOS, она немного облегчает работу. Для этого, в самом начале программы пишем local component = require('component'), так, что это за письмена? Эта строка создает локальную переменную (указываем словом local перед именем переменной), далее указываем имя переменной. Знак равенства указывает, что в переменной теперь будет хранится то, что дает функция require, в данном случае мы задали этой функции передать переменной component возможности обертки, которая тоже называется component. Так будет удобней понимать, к чему мы обращаемся. На следующей строке пишем local gpu = component.gpu Это мы назначили переменной gpu все методы видеокарты, т. е. теперь можем обращаться к ней через эту переменную. При загрузке, OpenOS сделала несколько скрытых операций: определила основную видеокарту, подключила ее к монитору и добавила их к остальным компонентам, чтобы можно было обратиться по имени компонента и получить готовый интерфейс. Итак, видеокарта готова к работе, теперь опишем, что она должна сделать. Создаем переменные, содержащие информацию о цветах и тексте, с которыми мы будем работать. local color1, color2, text = 0xff00ff, 0x0000ff, 'Hello, OpenComputers!' При помощи параллельного присваивания мы задали две переменные с числовыми значениями цветов и переменную с текстом. Теперь создадим простой цикл, в котором выведем текст на экран, назначая цвет текста и цвет фона. for i = 1, 10 do gpu.setForeground(color1) gpu.setBackground(color2) gpu.set(10, 5, text) color1, color2 = color2, color1 os.sleep(0.5) end Сам код назначает тексту цвет, указанный в color1, а фону color2, затем выводит текст, содержащийся в переменной text на монитор, указывая координаты первого символа (от левого верхнего угла 10 символов в право, 5 символов вниз). Далее, параллельным присваиванием, меняем значения переменных местами, чтобы при следующем выполнении кода, цвета фона и текста поменялись. В конце цикла ставим задержку в пол-секунды, используя системную функцию sleep. Цикл готов, теперь, в конце программы стоит добавить восстановление цветов текста и фона, т. к. по завершению ее работы, цвета останутся такими, которые были назначены в последний раз. Готовый алгоритм будет примерно такой: Нажимаем Ctrl+S, чтобы сохранить файл, затем Ctrl+W, чтобы закрыть редактор. Теперь мы снова попали в шелл. Вызываем только-что созданную программу по имени: gpu_test, и наблюдаем ее выполнение. Так как координаты вывода жестко заданы, мы видим, что текст как-бы мигает. Чтобы увидеть эволюцию работы цикла, можно к координатам вывода добавить значения шага цикла. Для этого откроем файл edit gpu_test.lua, в функции gpu.set к каждому числу прибавим переменную-итератор. Теперь вызов функции gpu.set выглядит вот так: gpu.set(10+i, 5+i, text), сохраним изменения (Ctrl+S), закроем (Ctrl+W), и опять запустим тестовую программу gpu_test Работа с вводом. Со способом вывода информации более-менее разобрались, теперь разберемся с вводом, т. к. мы хотим создать графический интерфейс, хоть и 'псевдо', мы будем использовать возможность сенсорного ввода, клавиатуру поставим для других задач. Монитор I уровня это только средство вывода, а мониторы второго и третьего уровня могут работать и как средство ввода. Когда игрок прикасается к экрану, генерируется сигнал touch, содержащий в себе адрес монитора, координаты касания, код кнопки мыши и ник игрока. Нам остается отследить это событие и соответсвующим образом на него отреагировать. Для демонстрации работы напишем небольшую тестовую программу, которая будет ловить события касания экрана, отображать место и числовые координаты. Создаем файл edit click_test.lua Первым делом подключаем управление видеокартой local gpu = require('component').gpu Затем, подключим мониторинг событий, который предоставляет OpenOS. local pull_e = require('event').pull Общая документация тут, мы воспользуемся только одной функцией. Теперь позаботимся о пользователе, чтобы при завершении программы цвет фона остался такими же, как и перед запуском, мы его сохраним в переменную: local b_color = gpu.getBackground() Эта функция сообщает цвет фона, который сейчас используется, для цвета текста есть getForeground, но в данном тесте мы будем управлять только цветом фона. Так как у мыши две кнопки, в событии touch указывается код кнопки: ЛКМ = 1, ПКМ = 0 Чтобы визуально различать касания, создадим таблицу с цветами для каждой кнопки. В качестве индекса будет использоваться код кнопки. local color = {[0] = 0x00ff00, 0x0000ff} т. е. ЛКМ будет обозначаться синим, ПКМ - зеленым. Теперь создадим цикл, в котором будем ловить и обрабатывать события. while true do Как следует из описания функции event.pull, можно фильтровать ненужное, передав в функцию название интересующего нас события. Так как возвращается довольно много переменных, будем создавать из них таблицу, для большего удобства. local tEvent = {pull_e('touch')} Теперь все события типа touch будут пересоздавать таблицу tEvent, в которой будет заключена информация об этом событии. Обратиться к интересующей информации можно, указав номер, в той же последовательности, как это описано в документации по сигналам Для начала добавим условие выхода из программы, т. к. цикл бесконечный и прервать его можно только грубо нарушив выполнение программы. if tEvent[3] == 1 and tEvent[4] == 1 then Если клик произошел по координатам (1, 1), выполнить следующий код: gpu.setBackground(b_color) - вернем фону его первоначальное значение, полученное при запуске программы. os.exit() - вызовем системную функцию выхода из программы. Закроем условие: end А теперь опишем сам процесс отклика на касание. Присваиваем фону цвет, исходя из полученного кода кнопки мыщи: gpu.setBackground(color[tEvent[5]]) Устанавливаем по полученным координатам символ пробела, чтобы подсветить фон: gpu.set(tEvent[3], tEvent[4], ' ') Затем, по координатм (1, 1) показываем информацию о событии: gpu.set(1, 1, 'x: '..tEvent[3]..' y: '..tEvent[4]..'\t\t') В конце добавляется пустое место, чтобы не заморачиваться с затиранием предыдущих значений. Закрываем цикл end В итоге получается такой код: Сохраним и запустим программу. Кликая мышкой по монитору мы видим, как она оставляет следы и обновляется информация в левом верхнем углу. Кликнув в левый верхний угол мы завершаем работу программы. Значит, мы между делом создали кнопку, хоть и невидимую. Принцип работы очень прост - пользователь кликнул по экрану, а программа сравнила координаты клика с координатами кнопки, если они совпали, то выполняется код, назначенный для этой кнопки. Теперь создадим нормальные кнопки, с более удобной конфигурацией. Все кнопки будут находиться в таблице, при каждом клике будем в цикле обходить таблицу, проверяя координаты. Дополнительно напишем пару функций - одна будет подсвечивать нажатую кнопку, другая переключать видимость. Каждая кнопка будет содержать следующие параметры: статус отображения (т. е. активна кнопка или нет), координаты, размер, цвет фона кнопки, цвет текста, текст и исполняемую функцию. { visible = boolean, X = number, Y = number, W = number, H = number, color = number, textColor = number, text = string, action = function } Загрузим видеокарту и захват событий. local gpu = require('component').gpu local pull_e = require('event').pull Для того, чтобы очистить экран при запуске и поставить кнопку выхода в угол, нам понадобится узнать и сохранить текущее разрешение. local W, H = gpu.getResolution() Сохраняем цвета фона и текста, чтобы вернуть их при завершении программы. local b_color, f_color = gpu.getBackground(), gpu.getForeground() Создаем таблицу tButtons, в ней мы будем хранить все кнопки. Добавляем кнопку выхода из программы: Изначальное состояние кнопки: visible = false, Устанавливаем кнопку в правый верхний угол, задаем размер в один символ: X = W, Y = 1, W = 1, H = 1, Устанавливаем цвета: color = 0xff0000, textColor = 0xffffff, Задаем символ: text = 'X', Функция завершения программы немного изменилась - устанавливаются первоначальные цвета, очищается экран и вызывается функция выхода. action = function() gpu.setBackground(b_color) gpu.setForeground(f_color) gpu.fill(1, 1, W, H, ' ') os.exit() end Опишем функцию рисования кнопки, в которую будет передаваться индекс кнопки. local function drawButton(n) задаем цвет кнопки gpu.setBackground(tButtons[n].color) задаем цвет текста gpu.setForeground(tButtons[n].textColor) заливаем прямоугольник, который занимает кнопка (в данном случае, берем координаты и размер кнопки из ее таблицы) gpu.fill(tButtons[n].X, tButtons[n].Y, tButtons[n].W, tButtons[n].H, ' ') для большей красоты отцентрируем текст по границам кнопки, для этого вычислим половину высоты и половину ширины кнопки, прибавим их к координатам кнопки, а у ширины еще отберем половину длинны текста gpu.set(tButtons[n].X+(tButtons[n].W/2)-(#tButtons[n].text/2), tButtons[n].Y+(tButtons[n].H/2), tButtons[n].text) закрываем функцию end Добавим переключение видимости кнопки. local function toggleVisible(n) if tButtons[n].visible then если кнопка видима, то изменим статус tButtons[n].visible = false установим цвет фона на тот, который был при запуске gpu.setBackground(b_color) зальем прямоугольник фоновым цветом gpu.fill(tButtons[n].X, tButtons[n].Y, tButtons[n].W, tButtons[n].H, ' ') else иначе: изменим статус tButtons[n].visible = true вызовем отрисовку этой кнопки drawButton(n) закроем условие и функцию end end Чтобы кнопка подмигивала при активации, создадим функцию меняющую цвет фона и текста, как в первом примере. Для получения и назначения цветов обратимся к параметрам кнопки по индексу, как и в прошлых функциях. меняем цвета tButtons[n].color, tButtons[n].textColor = tButtons[n].textColor, tButtons[n].color рисуем кнопку drawButton(n) делаем задержку os.sleep(0.09) возвращаем цвета tButtons[n].color, tButtons[n].textColor = tButtons[n].textColor, tButtons[n].color заново рисуем кнопку, с номальными цветами drawButton(n) Функции описаны, теперь напишем саму программу. При запуске очистим экран gpu.fill(1, 1, W, H, ' ') Можно вынести ее в отдельную функцию, но в данном примере очистка вызвается только два раза - при запуске и при выходе. Теперь активируем все нужные кнопки. В данном примере можно запустить все кнопки, поэтому пройдем в цикле по таблице с кнопками и для каждой вызовем переключатель видимости. for i = 1, #tButtons do toggleVisible(i) end И опишем главный цикл. while true do ловим событие в таблицу tEvent local tEvent = {pull_e('touch')} перебираем все кнопки for i = 1, #tButtons do если кнопка видима if tButtons.visible then сравниваем координаты клика с прямоугольником кнопки if tEvent[3] >= tButtons.X and tEvent[3] <= tButtons.X+tButtons.W and tEvent[4] >= tButtons.Y and tEvent[4] <= tButtons.Y+tButtons.H then если клик попал по этой кнопке, заставляем ее мигнуть blink(i) выполняем функцию, которая назначена для нее tButtons.action() прерываем цикл проверки кнопок break закрываем циклы и условия end end end end На этом все, программа готова, в готовом примере я добавил три кнопки - 'set' выводит строку, а 'del' стирает и бибикает спикером, 'reboot' перезагружает компьютер.
  20. Недавно видел в какой-то теме про сворачивание блоков кода, которые завернуты в do ... end Попробовал то же в своем sublime и увидел как оно работает. Захотелось бОльшего Немого поковырявшись в гугле разобрался как в sublime 3 добавить подобную свертку для любого синтаксиса. Включая Lua С помощью PackageControl устанавливаем SyntaxFold Идём в Preferences -> Package Settings -> SyntaxFold -> Settings - User Добавляем такую запись для сворачивания функций и таблиц: { "scope": "source.lua", "startMarker": "local function, function, {", "endMarker":"end, end, }" }, По аналогии можно добавить более специфичные маркеры после чего перезапустить редактор Теперь по Control+Shift+[ , Control+Shift+] , Control+K, Control+Цифра а также командами в меню Edit -> Code Folding можно сворачивать и разворачивать блоки внутри назначенных маркеров. Если тут есть еще любители саблайма кроме меня, новые полезности и удобности для луа - приветствуются
  21. На этом. Язык компилируется в Lua (поддерживаются версии 5.1, 5.2, 5.3 и даже возможно JIT). Предупреждаю — этот язык является диалектом Lisp. Если ваш дед не оставил в кладовке пачку скобок, возможно у вас не получится на нем писать. Из фич: pattern matching, прикольные циклы, фреймворк для тестов, красивые сообщения об ошибках. Hello world на Urn: (print! "Hello, world!") Работает также арифметика в стиле лиспа: (+ 2 (* 4 5)) Можно создавать функции: (defun times-two (x) (* x 2)) (print! (times-two 2)) (print! (times-two 3)) и макросы: (defmacro show (x) (print! "Compile-time" (pretty x)) `(progn (print! "Run-time" ,(pretty x)) (print! "Value" ,x))) ------------------------------------ > (show (+ 2 3)) Compile-time (+ 2 3) Run-time (+ 2 3) Value 5 Можно использовать библиотеки из Lua: (define bit32 :hidden (require "bit32")) (define & (.> bit32 :band)) (define ~ (.> bit32 :bnot)) и таблицы из Lua: > { :foo 1 . :bar 2 } out = {"bar" 2 "foo" 1} Компилятор языка написан на Lua UPD: компилятор написан на Urn и скомпилирован в Lua; предлагаю энтузиастам поиграться с ним в OpenComputers и сделать отчет. А я пойду дальше употреблять вещества.
  22. Вопрос такой можно ли перехватывать сообщения из чата? Пример: Человек написал слово в чат, если оно совпадает с переменной то сообщение в чат не отправляется и пишет что он к примеру победил, а если не совпадает то сообщение отправляется в чат.
  23. Эта кoпалка не требует для рабoты лишних деталей, т. к. кoд запиcываетcя на EEPROM. При cбoрке рoбoта, вмеcтo ЖД, мoнитoра и клавиатуры мoжнo дoбавить чтo-тo дейcтвительнo нужнoе, например раcширение инвентаря или аккумулятoра. Требoвания: Инвентарь (чем бoльше - тем лучше) Кoнтрoллер инвентаря. Геocканер. Инcтрумент, врoде алмазнoгo или иридиевoгo бура. Хoвер-апгрейд (еcли неoбхoдимo) При cбoрке мoжнo дoбавить: Апгрейд-верcтак. (пoзвoляет экoнoмить меcтo) Чанклoадер. Генератoр. (при наличии чанклoадера реже будет неoбхoдимocть ездить к заряднику) Беcпрoвoдную cетевую карту. (пoзвoлит рoбoту oтправлять cтатуcные cooбщения) Пример минимальнoй и пoчти макcимальнoй cбoрки (при желании, мoжнo дoбавить раcширения) Иcпoльзoвать oчень прocтo: В кoмпьютер c интернет-платoй вcтавить EEPROM. Запуcтить кoманду pastebin get eFkAZP0u b && edit b && flash b -q && rm b Пo желанию, редактирoвать параметры - первые переменные этo кoличеcтвo нoд, минимальная плoтнocть, макcимальная плoтнocть, выcoта (неoбхoдимo указывать для мирoв, в кoтoрых нет бедрoка), пoрт, cпиcoк oтхoдoв. Сoхранить/закрыть файл. Дocтать EEPROM из кoмпьютера и вcтавить в рoбoта. Выдвинутьcя на меcтo дoбычи. Пocтавить рoбoта. Дать рoбoту бур. Пocтавить вoзле негo кoнтейнер и включенный зарядник. Включить рoбoта и ждать завершения рабoты. Функциoнал: Рoбoт cканирует квадраты x8 блoкoв пo гoризoнтали, пocтепеннo oпуcкаяcь вниз. Дoбывает блoки из заданнoгo диапазoна плoтнocтей. Дoйдя дo бедрoка, рoбoт пoднимаетcя на cтартoвую выcoту и перехoдит к cледующей кoлoнне. При низкoм урoвне заряда аккумулятoра, пытаетcя заправить генератoр (еcли имеетcя), в прoтивнoм cлучае или при низкoм урoвне заряда инcтрумента, oтправляетcя на cтартoвую пoзицию, к заряднику. Так же, при запoлнении инвентаря, cбраcывает муcoр, при наличии верcтака упакoвывает реcурcы в блoки и еcли меcта вcе-равнo малo, тo cледует к кoнтейнеру, cбраcывает лут и вoзвращаетcя к рабoте. Еcли имеетcя чанклoадер, тo при начале рабoты oн включаетcя, а при завершении выключаетcя. Еcли имеетcя беcпрoвoднoй мoдем, тo рoбoт пocылает cтатуcные cooбщения: 0 - неразрушимый блок (скорее всего - приват) 1 - контейнер заполнен 2 - контейнер отсутствует 3 - зарядка инструмента 4 - заправка генератора 5 - конец работы
  24. Я вас категорически приветствую! Сегодня я хочу представить вам новый формат для изображений для OpenComputers! Данный формат был придумал в соавторстве с @@Alexc. Начну я с того, как устроен процесс конвертации картинки (ну и самого формата тоже): Определяются базовые цвета картинки (пара цветов -baseFore, baseBack - которые чаще всего встречаются на исходном изображении), преобразуются в цвета opencomputers и записываются в файл вместе с размерами картинки. Сканируется картинка по паре пикселей по координатам x y * 2 - 1 и x y * 2, чтобы получилась пара цветов (fore и back). Из них формируются "цепочки" вида : { [back] = { [fore] = {x,y,str} } где back и fore - цвета "верхнего" и "нижнего" пикселей, а {x,y,str} - сама цепочка. Пример из 1 картинки: [6712704]={ -- Преобразованный в целочисленное значение цвет для background [7895160]={ -- Преобразованный в целочисленное значение цвет для foreground {70,31,"▄"} -- Сама цепочка, которая будет отрисована. } ,[13816530]={ {65,41,"▄▄"} } ,[2960685]={ {95,43,"▄"} },[12829635]={ {95,42,"▄"} } } (Разумеется все это хранится в байткоде, а не в таком виде ) Плюсы и минусы: Плюсы: Достаточно быстрая скорость отрисовки картинок. Достаточно небольшой размер конечных файлов (По сравнению с оригиналом в .png - .pix занимает в разы меньше места, а по сравнению с .jpg - больше ) Минусы: При конвертации и отрисовке используются только 4 символа Юникода: "▄" , "▀" , "█" , " ". Максимальное разрешение исходной картинки 160х100 пикселей в форматах: .png, .jpg, .bmp. Нет поддержки шрифтов Брайля (см. пункт 1 ). Установка: Скачать сам конвертор, написанный на Kotlin (Спасибо @@Totoro =) ) https://github.com/cc-ru/pix/releases Или же скачать lua версию : pastebin get SYfcHuhr PIXconv.lua Запускать таким образом: PIXconv file Файл будет сохранен в ту же папку, с тем же названием, но с расширением .pix Так же вместе с конвертором будет скачана программа для отрисовки под названием PIXdraw.lua. Если же вы хотите ее скачать отдельно, то: pastebin get Bm0JUJnj PIXdraw.lua Запускать таким образом: PIXdraw file.pix Скриншоты (как это выглядит в OCEmu и майнкрафте): https://clip2net.com/s/3Ug8qrb https://clip2net.com/s/3Ug88vV
×
×
  • Создать...