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

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

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

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

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

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


Блоги

  • Робот Байт
  • 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


Город


Интересы

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

  1. Мне нужно присвоить переменной grow значение метадаты блока из таблицы geolyzer.analyze(), но не знаю как это сделать. То что должно содержатся в grow выделено зелёным прямоугольником на изображении. Немного переборщил с размером изображения.
  2. 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 в конце программы; не требуется ребутать компьютер, если программа завершилась с ошибкой, а до отключения слушателей дело не дошло. В общем, красота.
  3. Я решил попробовать написать софт для OpenComputers и написал небольшую софтину для получения информации о системе. Текущая версия: 2.1 Изменения в 2.1 (от 31.06.2019): Исправлена проблема с роботами Мелкие графические улучшения Изменения в 2.0 (от 21.12.2018): Появились некоторая дополнительная информация о роботах В конце вместо противного писка звук 1000 длиной 0.1 секунду и 1500 длиной в 0.15 секунд Во всех значениях пропали числа после запятой Изменения в 1.01 (от 20.12.2018): ОЗУ теперь в КБ Исходный код v 2.0: https://pastebin.com/6Nte3GZa Скачать v. 2.1 (нужна интернет карта): pastebin get 6Nte3GZa /bin/status.lua Исходный код v 1.01: https://pastebin.com/HtrMUj5p Скачать v 1.01 (нужна интернет карта): pastebin get HtrMUj5p /bin/status.lua Для запуска введите команду 'status' Скриншоты на ПК и роботе:
  4. Totoro

    3D-Принтер

    Трехмерная печать в Minecraft (инструкции для самых маленьких) Начиная с версии 1.5.4, в OpenComputers появляется интересный девайс - трехмерный принтер. Он дает возможность печатать декоративные блоки любой формы и цвета. Причем не только статичные блоки, но и двери/люки, кнопки и рычаги! Давайте рассмотрим, для чего он может пригодиться, и как именно с ним работать. 1. Цель Как и в предыдущих гайдах, первым делом поставим себе цель. Мы будем создавать стенную плитку со сквозным орнаментом, в виде морды крипера. Я не буду приводить в этом гайде рецепты предметов, так как их легко найти в NEI, или в статьях на gamepedia. 2. Обзор принтера 3D-принтер - это периферическое устройство, которое должно быть подключено к работающему компьютеру. Оно представляет собой блок, с двумя внутренними слотами: Верхний слот предназначен для специальной печатной массы (изготовляется из редстоуна, гравия, древесного угля и воды). Принтер вмещает два стека печатной массы (256 000 ед). Нижний слот занимает картридж с красителями. Объем внутреннего хранилища - два картриджа краски (100 000 ед). По команде от компьютера, принтер берет немного печатной массы и краски и "распечатывает" в крайний правый слот запрограммированную модель. На модель из этого гайда, состоящую из 21 фигуры, принтер потратил 424 единицы массы и 314 единиц краски. 3. Отпечатанный блок Модель для печати задается в виде списка "фигур" - параллелепипедов. Каждая фигура отмечена координатами противоположных углов. Она имеет свою текстуру, цвет оттенка (если необходимо) а также состояние (true/false). Максимальное количество фигур в модели - 24, по умолчанию. Координаты блока тремя числами (X, Y, Z) в пределах от 0 до 16. Блок может переключать свое состояние, когда игрок кликает по нему правой кнопкой мыши, или на блок подается сигнал редстоуна. По умолчанию блок имеет форму, заданную блоками с состоянием false, и сменяет ее на форму из блоков с состоянием true, при активации. Кроме того блок имеет несколько дополнительных общих флагов, которые определяют его название, описание и некоторые другие параметры. 4. Программирование принтера Есть два способа распечатать свою модель. Через компонент принтера и прямое управление, либо при помощи стардартной программки print3d от Сангара. 4.1 Компонент принтера Подключение принтера ничем не отличается от подключения любого другого устройства: local com = require('component')local printer = com.printer3d Компонент предоставляет набор функций для управления: reset() - сброс настроек и остановка печати setLabel(value:string) - задаем название будущего блока getLabel():string - получаем текущее название setTooltip(value:string) - задаем описание блока getTooltip():string - получаем описание setRedstoneEmitter(value:boolean) - определяет, излучает ли блок сигнал редстоуна в активированном состоянии isRedstoneEmitter():boolean - возвращает true, если блок излучает сигнал в активном состоянии setButtonMode(value:boolean) - определяем поведение блока при активации. Если true, то блок автоматически возвращается в неактивное состояние через несколько секунд после активации (как кнопка) isButtonMode():boolean - возвращает true, если блок находится в режиме "кнопки" addShape(minX:number, minY:number, minZ:number, maxX:number, maxY:number, maxZ:number, texture:string[, state:boolean=false][,tint:number]) - добавляет новую "фигуру" к форме блока. Фигура задана координатами. texture - название текстуры, state - для какого состояния фигура предназначена, tint - цвет оттенка фигуры getShapeCount():number - возвращает количество фигур в модели getMaxShapeCount():number - возвращает максимально возможное количество фигур commit([count:number]) - посылает принтеру текущую конфигурацию и начинает печать (count - количество копий, если не задано - равно 1) status(): string, number or boolean - возвращает состояние принтера - "buzy" и процент готовности, или "idle" и готовность предмета (true/false). 4.2 Программа print3d Код программы не включен в мод по умолчанию, поэтому его надо скачать из интернета. Последнюю версию можно найти на ГитХабе автора: https://github.com/OpenPrograms/Sangar-Programs/blob/master/print3d.lua Либо скачать с Pastebin: http://pastebin.com/b5rD8KcY (поставьте интернет-плату, и наберите в консоли компьютера команду pastebin get b5rD8KcY print3d) Эта программа по сути, читает параметры модели из текстового файла и передает принтеру. Формат вызова программы: print3d FILE [count] Где FILE - название файла с моделью, а необязательный параметр count - количество копий модели. Модели имеют простой формат - все параметры записываются в таблицу, по аналогии с Луа. Вот образец файла с моделью. { -- Это - название модели. Т.е. название будущего блока, которое будет видно -- в инвентаре и подсказке Waila. Название по умолчанию - "3D Print" label = "Example Model", -- Это описание предмета, такое, как будет видно в инвентаре. Если не задано, -- предмет не будет иметь описания tooltip = "Это демонстрационная модель, показывающая все возможности", emitRedstone = false, --[[ Если этот параметр равен false, блок работает как дверь, сменяя свое состояние при сигнале редстоуна. Если параметр равен true, блок работает как кнопка или рычаг - излучая сигнал при смене состояния. При этом блок не реагирует на сторонний сигнал. По умолчанию параметр равен false. ]] buttonMode = false, --[[ Если этот параметр равен false, модель работает как дверь или рычаг - то есть остается в том состоянии, в которое установлен игроком. Если параметр равен true, модель автоматически возвращается в неактивное состояние через несколько секунд после активации. По умолчанию параметр равен false. ]] -- Это список фигур модели, которые определяют, как она выглядит. -- Модель должна содержать как минимум одну фигуру (параллелепипед) -- в неактивном состоянии. -- Фигуры не могут быть "плоскими" т.е. не иметь объема. -- Каждая фигура задана шестью числами: minX, minY, minZ, maxX, maxY, maxZ. -- (Координаты двух противоположных углов.) -- Если смотреть спереди, ось X направлена вправо, ось Y - вверх и ось Z - вглубь. -- Дополнительно, каждая фигура длолжна обладать текстурой. Для того чтобы -- определить название текстуры, вы можете воспользоваться Определителем Текстуры -- (Texture Picker), кликнув им по нужному блоку. -- -- Модель имеет два состояния - неактивное (false, состояние по-умолчанию) -- и активное (true, состояние после активации блока). shapes = { -- Фигура идет от точки <0, 0, 0> (левый нижний угол) до <8, 8, 8> (середина), -- и имеет текстуру блока лазурита. { 0, 0, 0, 8, 8, 8, texture = "lapis_block" }, -- Фигура идет из точки <8, 8, 8> (середина) в <16, 16, 16> (правый верхний угол), -- и закрашена текстурой дубовой листвы. Фигура принадлежит активному состоянию -- модели и имеет светло-зеленый оттенок. { 8, 8, 8, 16, 16, 16, texture = "leaves_oak", state = true, tint = 0x48B518 } }} Т.е. описание модели просто содержит перечень всех тех параметров, которые задаются при помощи компонента, и список фигур из которых модель состоит. Набор тестовых моделей для изучения, можно найти здесь: https://github.com/OpenPrograms/Sangar-Programs/tree/master/models 5. Проектирование модели Разобьем мысленно рисунок запланированной модели на параллелепипеды. Она будет представлять собой тонкую плитку посередине блока, наподобие стекла или решетки. Руководствуясь сеткой координат и образцом выше, составим описание модели для текстового файла: { label = "Плитка 'Морда крипера'", emitRedstone = true, buttonMode = false, tooltip = "Секретный рычаг в виде головы крипера" shapes={ {0,14,7, 16,16,9, texture="quartz_block_side", tint=0x8eb200}, {0,2,7, 2,14,9, texture="quartz_block_side", tint=0x8eb200}, {6,10,7, 10,14,9, texture="quartz_block_side", tint=0x8eb200}, {14,2,7, 16,14,9, texture="quartz_block_side", tint=0x8eb200}, {2,2,7, 4,10,9, texture="quartz_block_side", tint=0x8eb200}, {4,8,7, 6,10,9, texture="quartz_block_side", tint=0x8eb200}, {10,8,7, 12,10,9, texture="quartz_block_side", tint=0x8eb200}, {12,2,7, 14,10,9, texture="quartz_block_side", tint=0x8eb200}, {6,2,7, 10,4,9, texture="quartz_block_side", tint=0x8eb200}, {0,0,7, 16,2,9, texture="quartz_block_side", tint=0x8eb200}, {0,14,7, 16,16,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {0,2,7, 2,14,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {6,10,7, 10,14,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {14,2,7, 16,14,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {2,2,7, 4,10,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {4,8,7, 6,10,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {10,8,7, 12,10,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {12,2,7, 14,10,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {6,2,7, 10,4,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {0,0,7, 16,2,9, texture="quartz_block_side", tint=0x8eb200, state=true}, {2,2,8, 14,14,9, texture="quartz_block_side", tint=0xe0301e, state=true}}} Итак, наша плитка имеет двойной набор фигур - для двух состояний, окрашенных в текстуру кварца с зеленым оттенком. Кнопка будет работать как рычаг, испуская сигнал в активном состоянии. Откройте файл командой open creeper. Скопируйте код плитки выше и вставьте в файл кнопкой [insert]. Затем сохраните ([Ctrl]+) и покиньте редактор ([Ctrl]+[W]). 6. Печать Все готово, принтер заправлен, модель спроектирована. Отправляем ее на печать! print3d creeper 7. Итоги Enjoy!
  5. Всем привет! Я написал программу для дистанционного управления дроном (например, с планшета). Плюсы программы: Плюсы При запуске дрона требуется ввести случайный код (т.е. дрона никто не угонит). Можно изменять цвет подсветки дрона, надпись на его экране, скорость дрона. Доступен ввод своих комманд (например, для работы с лассо) Относительно нормальное управление дроном Скрины и мини инструкция для работы с программой Установка прог: Для пульта: pastebin get JTY87AiR control Для дрона: На компьютер скачиваем прошивку для дрона: pastebin get up53MtPM drone Вставляем в системник чистый EEPROM Вводим flash drone eeprom Пихаем в дрона полученную прошивку (eeprom) Включаем дрона!
  6. Новости по аддону. Тут принимаются идеи, баги, помощь. github: https://github.com/Avaja/OpenTechnology
  7. Дело было вечером, делать было нечего... И тут я случайно зажал горячую клавишу калькулятора, и меня осенило! А ведь калькулятора то для ОС никто не писал еще! Так появилась идея создания этого калькулятора. Что можно про него сказать? Базовый калькулятор который умеет выполнять стандартные математические операции. Требования к ОС: Видеокарта 2 уровня и выше Монитор 2 уровня и выше Компьютер/сервер любого уровня с установленной OpenOS Управление самое простое - мышкой. При создании программы была взята статья Псевдографические интерфейсы в OpenComputers и на основе кода из неё был создан калькулятор. Установка: version 0.2 pastebin -get PaVaRGcd Calculator.lua version 0.3 pastebin -get ZjCTrj5a Calculator.lua P.S. Выражаю благодарность @Doob за статью. Если найдете какие-то баги, недочеты, или возникнут идеи по улучшению, я всех с радостью выслушаю.
  8. - Запустил я Norton Commander. Вижу слева диск С и справа диск С. Думаю, нафига мне два диска С. Взял и грохнул один. (Старый-старый анекдот) Для людей, не привыкших работать с командной строкой, создан файловый менеджер Midday Commander. Разработчики: МС поддерживает работу с экранами разного разрешения и цветовой гаммой Возможно даже его удастся запустить на роботе. За основу внешнего вида взят известный линуксовский ФМ Midnight Commander, а также незабвенный Norton Commander. Кто постарше, тот помнит, поэтому проблем с интерфейсом быть не должно. Экран МС делится на две панели, в которых размещаются списки каталогов и файлов, имеющихся на дисковых устройствах компьютера. Каталоги помечены символом "/" и сгруппированы вначале списка. Ниже панелей находятся командная строка и меню основных операций, которые вызываются нажатием соответствующей функциональной клавиши. Навигация по панелям осуществляется клавишами Вверх/Вниз. Клавиша Tab переводит курсор на соседнюю панель. Для запуска программы или смены директории наведите курсор на программу или директорию и нажмите Enter. Чтобы запустить программу с параметрами, нажмите клавишу Enter, удерживая Ctrl. При этом имя программы переместится в командную строку. Введите параметры и нажмите Enter. F1 - выдает помощь по работе с МС F4 - открывает выбранный файл на редактирование. В качестве редактора используется стандартный редактор edit.lua. Чтобы создать новый файл, нажмите Shift+F4 и в открывшемся окошке "File name:" введите имя создаваемого файла и нажмите Enter. Для выбора пункта Cancel используйте кнопку Tab. F5 - копирует выбранный файл в директорию, открытую на соседней панели. В окошке "Copy file:" можно указать новое имя, под которым файл будет скопирован. F6 - перемещает файл. F7 - создает новую директорию F8 - удаляет файл или директорию. Перед удалением будет выдано предупреждение: Для выбора пункта Cancel используйте кнопку Tab. F10 - выход из МС Для поиска файла или директории на дисках компьютера нажмите Alt+F7 и в открывшемся окне "Find file/dir:" введите искомое имя. Результат поиска будет отображен в окне "Find:" Выбор какого либо из результатов в окне "Find:" приведет к перемещению в соответствующую директорию. При поиске файла можно использовать спецсимволы "?" и "*". ? - замещает собой любой символ; * - замещает любую последовательность символов. Например, для поиска всех файлов, начинающихся с буквы m, введите строку поиска "m*" Скачать Midday Commander можно, выполнив команду: pastebin get kE3jp6nD bin/mc.lua Планы на будущее: 1. русификация 2. поддержка мыши.
  9. Данная программа позволяет осуществлять сбор любой ванильной и ваниллаподобной культуры (не проверялось на кактусах, у тростника рекомендуется собирать только верхнюю часть). Под ваниллаподобной культурой следует понимать культуру, сбор которой укладывается в алгоритм: [проверить блок] - (проверить метадату) - [если проверки пройдены, собрать культуру ЛКМ/ПКМ] - (высадить блок ПКМ), где [] - обязательный пункт, а () - необязательный. Жердочки из IC частично поддерживаются (все, кроме резинового тростника и веномилии). Одним роботом может обслуживаться неограниченное (вернее, ограниченное вместимостью инвентаря робота и его ОЗУ) количество полей разных культур. Системные требования: Процессор второго уровня (рекомендуется) Две планки ОЗУ второго уровня (рекомендуется) Жесткий диск первого уровня Геолайзер Улучшения "Инвентарь" и "Продвинутый контроллер инвентаря" Улучшение "Притягивающий луч" как выяснилось, не требуется Видеокарта, монитор, клавиатура (крайне рекомендуется) Пример робота: http://i.imgur.com/q027ast.png Как использовать робота: Первым делом надо определить место установки робота. Программу можно будет запускать только с этого места! Место установки включает в себя координаты по всем трем осям и ориентацию (posx, negx, posz, negz). Под этим местом необходимо разместить воронку для выгрузки собранных айтемов. Также, если робот будет заряжаться, зарядник следует разместить так, чтобы не мешать проходу робота, например, в стене. После этого следует убедиться, что между всеми полями существует свободный проход и что над растениями свободен минимум один блок. Робот не имеет алгоритма поиска пути и будет идти "напролом", а значит, ему нельзя преграждать путь. Крайне рекомендуется располагать все поля в прямоугольной области, а также на одной высоте. Затем следует открыть исходный код и отредактировать переменные c четвертой строки по тринадцатую. Назначение переменных прокомментировано в самом коде. Изменив значения переменных, не листайте дальше, чтобы не увидеть велосипеды на костылях. Далее следует создать текстовый файл по адресу /fields.txt, в котором описать все поля, предназначенные к сбору роботом. После этого робот готов к работе. Установите робота на его место установки и запускайте программу. Cтруктура файла fields.txt: Каждое поле описывается одной строкой, поля идут в порядке сбора. Строка поля должна быть вида: startPosX,startPosZ,anotherPosX,anotherPosZ,fieldY,blockToTake,itemToPlant,fullGrownState,isRight startPosX и startPosZ это координаты начальной точки поля. С этой точки робот будет начинать сбор. anotherPosX и anotherPosZ это координаты противоположной точки (как точки, выделяемые при привате территории). Это не точка, где сбор будет заканчиваться. fieldY это координата, на которой располагаются растения. Робот будет летать на блок выше этой координаты, так, чтобы находиться над растениями. Если растение многоблочное, следует указать координату самой верхней части. blockToTake это name блока, который требуется собирать. Например, minecraft:carrots для моркови или minecraft:melon_block для арбузов. itemToPlant это name айтема, который требуется высаживать. Если после сбора ничего высаживать не требуется, следует написать nil. Можно написать и другое несуществующее name, но тогда робот будет все время пытаться найти ваш айтем (и, следовательно, работать медленнее). fullGrownState это metadata созревшего растения. Если metadata проверять не требуется, следует написать -1. isRight это необязательный флаг, указывающий, что культуру следует собирать ПКМ. По умолчанию стоит в false. Пример файла fields.txt: http://pastebin.com/H10k6QkV Ферма, соответствующая этому файлу: http://i.imgur.com/wP5gAaa.png Скачать: http://pastebin.com/K4DU8d3n Дополнительно: Просьба к играющим на МТ проверить работу робота с тамошними ваниллаподобными культурами, если такие там есть. Автор выражает благодарности: Totoro, который ответил на несколько моих глупых вопросов. AlexCC, который запретил сборщик урожая и тем самым побудил меня написать данную программу. Fingercomp, который натолкнул меня на мысль добавить поддержку сбора культуры ПКМ. UPD: Добавлена поддержка сбора культуры ПКМ. Это открывает возможности для частичной поддержки жердочек из IC - их состояние невозможно узнать, но большинство из них собираются только на последней стадии, так что с ними все-таки можно работать.
  10. Как пользоваться функцией scan? Итак, в этой функции можно задать два параметра, это относительные координаты по горизонтали (относительно блока геосканера/планшета или робота с геосканером), возвращаемое значение - таблица. Таблица содержит список плотностей блоков по вертикали. Чем дальше по вертикали находится блок (относительно геосканера), тем больше помех дает геосканер. Уровень помех можно настроить в конфиге мода. Ну тут вроде-как все понятно, разберемся с вертикальными координатами. При сканировании, геосканер возвращает таблицу, которая представляет собой столб из блоков. Кроме плотности ничего узнать нельзя. Возьмем, к примеру, scan(0, 0) это будет столб, выстой 64 блока, в котором находится устройство (геосканер/робот/планшет) В стандартнои конфиге радиус действия геосканера = 32 блока, следовательно можно просканировать кубоид 65x65x64 блока. Геосканер у нас находится на уровне 33 (индекс таблицы), на этом уровне при сканировании устройстрво почти не дает шумов, т. е. по горизонтали можно легко узнать истинную плотность блока. Индексы в таблице возрастают с высотой, т. е. блок с индексом 1 это -32 блок относительно устройства, 2 это -31 ... 33 это 0 и т. д. Теперь разберемся с горизонтальными координатами. Горизонтальные координаты хоть и относительные, но они не зависят от положения устройства в пространстве, т. е. отсчет идет по сторонам света. scan(1, 0) это столб на один блок на восток от устройства, следовательно, scan(-1, 0) - на запад. scan(0, 1) это южный столб, scan(0, -1) - северный. Для примера возьмем двойной цикл, который будет сканировать столбы и заносить их в таблицу. local tbl = {} for x = -32, 32 do for y = -32, 32 do if not tbl[x] then tbl[x] = {} end tbl[x][y] = geolyzer.scan(x, y) end end Он у нас будет сканировать с северо-запада на юго-восток, т. е. будет захватывать всю доступную зону. К примеру, нам надо сканировать определенный квадрат, стоящий по-диагонали от геосканера, обозначим их вот так: NE - северо-восточный, NW - северо-западный, SE - юго-восточный, SW - юго-западный. local function scan(d, r) -- направление, дальность if d == 'NE' then x1, x2, y1, y2 = 1, r, -r, -1 elseif d == 'NW' then x1, x2, y1, y2 = -r, -1, -r, -1 elseif d == 'SE' then x1, x2, y1, y2 = 1, r, 1, r elseif d == 'SW' then x1, x2, y1, y2 = -r, -1, 1, r end for x = x1, x2 do for y = y1, y2 do geolyzer.scan(x, y) -- тут должна быть фунция обработки или сохранения результатов сканирования end end end Чтобы просканировать квадрат со стороной 20 блоков, находящийся на юго-восток от геосканера надо запустить scan('SE', 20) Вроде-бы все очевидно. Функция analyze() намного проще, она возвращает таблицу с информацией о блоке, стоящем вплотную к устройству. Индексы таблицы не числовые, например, чтобы узнать плотность блока вводим analyze(сторона).hardness Чтобы задать сторону можно использовать sides API, либо просто задать цифрой. ...Будет дополняться...
  11. Часто необходимо писать программы для серверов. Это могут быть сервера для чатов, или файловые облака или что то еще, но всегда приходится писать велосипеды. Подумав об этом я решил написать программу для сервера. Программа работает просто. Подгружает модули из папки проекта, а потом начинает слушать все event'ы и обрабатывать. Представляю вам саму программу: Servercore v0.2.1 Исходный код: http://pastebin.com/NASX9sX0 Использование: Создаем папку проекта Создаем в этой папке файл .servercore Запускаем servercore указывая первым аргументом папку которую мы создали. Если не указывать аргумент то servercore запустится в рабочей директории. Наслаждаемся рабочим сервером, который пока ничего не делает. Любые файлы (кроме .servercore) которые находятся в папке проекта будут загружены как модули. Если модуль содержит ошибку наш сервер не полетит, а просто выведет тест ошибки на экран. При создании модулей можно использовать специальные функции, которые находятся в _G.sc. Описание этих функций: sc.info(info_type:string, message:string) - выводит информацию со временем и раскрашивает как на скринах. Принимает тип информации и само сообщение. Типов информации всего 4: ok,err,warn и info. sc.getTime() - возвращает время в формате unix timestamp. sc.on(event_name:string,handler:function) - добавляет слушателя на сигнал. Циклом слушаются все сигналы а потом запускают функцию обработчик для того сигнала который пришел. Пример простейшего модуля: sc.on("touch",function (e) sc.info("info","you touched!")end) Изменения в версии: Патч 1: убрана обязательная поддержка модемов. Старые версии: Произведение «Servercore» созданное автором по имени LeshaInc, публикуется на условиях лицензии Creative Commons «Attribution-NonCommercial-NoDerivatives» («Атрибуция — Некоммерческое использование — Без производных произведений») 4.0 Всемирная. PS: Название проги звучит как поджанр метала)))
  12. HeroBrine1st

    Lua Promise

    Для создания асихнронных библиотек по типу vk-fast-longpoll у nodejs. pastebin get 4Lh9ALEY /lib/Promise.lua Методы библиотеки: all(iterable: table) - создает промис, который ждет завершения всех переданных промисов (в виде таблицы) и в resolve шлет таблицу со всеми их значениями. Если хоть один завершится с ошибкой, вызовет reject с этой ошибкой race(iterable: table) - создает промис, который ждет первого завершения любого промиса, и проксифицирует его результат на себя (т.е. ошибку или результат перекидывает через себя, не обрабатывая) resolve(value:any) - создает промис, который успешно завершился с параметром value reject(value:any) - создает промис, который завершился с ошибкой value Магия ООП начинается с магии метатаблиц - вызывайте библиотеку как функцию. Просто Promise(...). Аргумент один - функция, принимающая 2 аргумента - resolve и reject. Если промис завершает работу успешно, он вызывает функцию resolve с одним (!) аргументом, а та передает его обработчикам. Если с ошибкой - вызывает reject, либо он вызывается автоматически при синхронной ошибке (attempt to call a nil value, error(...) и все подобное). Возвращает класс. У него 3 метода: next(onResolve:function,onReject:function): self: object (__name=Promise) - аналог then в NodeJS. catch(onReject): self: object (__name=Promise) - думаю понятно. await - ждет завершения промиса и возвращает его результат. Поддерживается чейнинг, но паралельные обработчики не добавить, и я не знаю, как это исправить :C Если во время чейнинга из обработчика вернуть промис, библиотека будет ждать его завершения и передаст результат в следующий обработчик. Если на уже выполненный промис навесить обработчик, он выполнится синхронно. На выполняющийся - асинхронно после завершения. Обьяснил возможно непонятно, обьяснение на learn.javascript.ru. Примеры кода: local Promise = require("Promise") local p = Promise(function(resolve,reject) print(123) os.sleep(5) print(234) resolve(5) end) --123 p:next(function(result) print(result) return 8 end) os.sleep(5) --234 --5 print(p.result) --8 a=Promise(function(a,b) os.sleep(5) a(1) end) b=Promise(function(a,b) os.sleep(1) a(2) end) c = Promise.all({a,b}) c:onResolve(function(values) print(serialization.serialize(values)) end) d = Promise.race({a,b}) d:onResolve(function(values) print(values) end) os.sleep(10) --2 --{2,1} Чистый исходный код на MoonScript Если туда не засовывать os.sleep, то промис заблокирует остальные потоки, как и если в основную программу не вставить os.sleep, она заблокирует промис. Учтите.
  13. Нужна прога для вывода на экран людей состоящих в привате и их статус(онлайн/офлайн)
  14. В луа можно обрезать строку? Например мне нужно читать сообщения из чата с помощью чат-бокса, искать в сообщении плохие слова и выдавать куда-то уже сообщения без плохих слов. В библиотеке string ничего не нашёл((
  15. Ничего сложного в этой программе нет, однако выкладываю код ради оценки его исполнения. https://pastebin.com/Mw88qQvr Последовательность запуска этой системы: Ставим N-ое кол-во узелстабов; Рядом с ними ставим таблички с номерами от 1 до N; Под ними ставим редстоун-контроллеры; Подключаем их все к компу; На комп ставим программу: pastebin get Mw88qQvr /home/bfnode.lua Запускаем программу с ключом -i для присвоения номеров адресам; После присвоения номеров программа продолжит свою работу в консольном режиме. Доступные команды: on off Аргументы к этим командам: Номер ноды all (т.е. запуск команды для всех нод) Пример:
  16. По этой теме уже существует отлаженный софт, успешно используемый многими игроками. Однако на днях я заметил забавную особенность местных видеокарт, позволяющую выставлять разрешение большее, нежели получаемое через gpu.maxResolution(). К примеру, если maxResolution для видеокарты третьего уровня вернет числа 160 и 50, то никто не мешает установить разрешение, скажем, в 20x158 пикселей. При этом при проверке валидности устанавливаемого разрешения соблюдается два правила: Результирующее разрешение по числу пикселей не должно превышать результат умножения чисел, возвращаемых maxResolution. То есть для T3 GPU не более 160 * 50 = 8000. Каждый параметр разрешения, будь то ширина или высота, не должен численно превышать значение возвращаемой ширины. То есть для T3 GPU не более 160. Не знаю, баг это или фича, однако подобное грех не использовать в своих целях. К примеру, старая версия программы при вертикально-удлиненном расположении мониторов позволяла выставить разрешение лишь в 30х50 (1500 пикселей в итоге), заполняя тем самым "черные полосы". В то же время обновленная софтина, учитывающая описанные выше особенности, выдает 69x114 (7866 пикселей), максимально приближаясь к предельной отметке в 8000: Согласитесь, лишние пиксели на дороге не валяются, и, думаю, кому-то будет интересно узнать про реализацию подобного софта. Прежде всего нам требуется определить точную пропорцию мультиблочного монитора: то, как относится его ширина к высоте. Взглянем на текстуру блока: она явно состоит из мелких "квадратиков" в количестве 16 штук, причем лицевая часть монитора имеет рамку толщиной в 2 "квадратика" с каждой стороны: Эти "квадратики" мы и будем использовать для расчета пропорции, так как они позволяют идеально точно получить размеры отображающей части монитора в игровом мире. А размеры "в квадратиках" можно посчитать по формуле: число_блоков_монитора * 16 - 4 Следовательно, пропорция монитора будет считается следующим образом: local gpu = component.gpu local screen = component.proxy(gpu.getScreen()) local blockCountByWidth, blockCountByHeight = component.screen.getAspectRatio() local proportion = (blockCountByWidth * 16 - 4) / (blockCountByHeight * 16 - 4) Также не забываем, что высота каждого псевдографического пикселя при отображении в 2 раза больше его ширины, поэтому формула пропорции слегка меняется. Заодно произведем некоторые сокращения, чтобы избавиться от лишних математических операций. Все три варианта эквивалентны: local proportion = 2 * (blockCountByWidth * 16 - 4) / (blockCountByHeight * 16 - 4) local proportion = (blockCountByWidth * 16 - 4) / (blockCountByHeight * 8 - 2) local proportion = (blockCountByWidth * 2 - 0.5) / (blockCountByHeight - 0.25) После вычисления пропорции монитора можно приступить к написанию программной логики. Для начала получим максимальное разрешение видеокарты: local maxWidth, maxHeight = gpu.maxResolution() Обладая этими данными, а также взглянув на условия, описанные в начале поста, мы можем составить систему неравенств для получения итогового идеального разрешения: Помним также, что ширину мы вполне можем выразить через высоту и пропорцию монитора: width = proportion * height Подставим этот вариант в систему: Оставим высоту в левой части неравенств: Подставляем имеющиеся переменные в каждое неравенство, рисуем числовую прямую и выбираем высоту, удовлетворяющую условиям неравенства для конкретного случая. Разумеется, в программировании никаких числовых прямых нет, зато есть любимые math.min() и math.max(): local height = math.min( maxWidth / proportion, maxWidth, math.sqrt(maxWidth * maxHeight / proportion) ) -- Выражаем ширину через пропорцию local width = height * proportion Все. Разумеется, полученные значения ширины и высоты нужно округлить в меньшую сторону, дабы не кормить видеокарту дробями. Заодно добавим поддержку масштабирования, чтобы выставлять половинное или, скажем, четвертичное от идеального разрешение. Сократив код, избавившись от лишних переменных, мы получаем следующее: local component = require("component") -- Получаем масштаб в качестве первого аргумента скрипта и корректируем его значение local scale = tonumber(select(1, ...) or 1) if not scale or scale > 1 then scale = 1 elseif scale < 0.1 then scale = 0.1 end local gpu = component.gpu local blockCountByWidth, blockCountByHeight = component.proxy(gpu.getScreen()).getAspectRatio() local maxWidth, maxHeight = gpu.maxResolution() local proportion = (blockCountByWidth * 2 - 0.5) / (blockCountByHeight - 0.25) local height = scale * math.min( maxWidth / proportion, maxWidth, math.sqrt(maxWidth * maxHeight / proportion) ) -- Выставляем полученное разрешение gpu.setResolution(math.floor(height * proportion), math.floor(height)) Надеюсь, это микро-знание кому-то было полезно. Лично я очень доволен, что могу наконец запилить графонистый интерфейс для контроля реакторов на вертикальных мониках без осваивания профессии "глиномес", да и соответствующая либа для автопобора разрешения в оське пригодится.
  17. Давненько не было автокрафтеров тут. Может, кому-то пригодится моя версия. Предназначена в первую очередь для крафта всяких часто необходимых мелочей со сложными крафтами (например, компоненты OpenComputers) из примитивных исходных ресурсов (например, процессор из слитков золота и железа, тростника и редстоуна), которые у пользователя отнимают кучу времени на поиск всех транзисторов и крафт недостающих. Рассчитана на использовании робота и двух сундуков, один из которых - основное хранилище (может быть покрупнее), а другой предназначен для резервирования компонентов при крафте. Ссылка: https://pastebin.com/1gqtWLub Необходимая конфигурация робота: Проверялась работа на компонентах (корпус, память, процессор, жёсткий диск) второго уровня. Screen, Keyboard Crafting Upgrade Inventory Upgrade и Inventory Controller Видеокарта и экран первого уровня Для дальнейших потенциальных расширений: Беспроводная карта Upgrade Container Конфигурация установки: Перед роботом - контейнер ресурсов (любой из возможных инвентарей достаточного размера) Под роботом - контейнер-буфер (можно обычный сундук) Рядом желательно поставить зарядник Возможности: Рекурсивный крафт сложных рецептов. Ресурсов расходуется, по результатам практических испытаний, ровно столько, сколько необходимо. Каталог рецептов для крафта, разбитый на страницы по 10 предметов для более удобного пролистывания на маленьком экране робота. Портативность - требуется только робот, два сундука и исходные ресурсы. Желателен также источник энергии Сообщения о том, каких конкретно исходных ресурсов не хватает для крафта (исходные ресурсы - те, для которых не найдено рецепта) Процесс крафта подробно отображается на экране, чтоб за ним было не так скучно и одиноко следить (см. недостатки) Об окончании крафта робот сообщит приветливым писком. Равно как и о неудаче. Недостатки и известные недочёты: Скорость..... Крафт занимает значительное время. Например, изготовление процессора 3го уровня из примитивных ресурсов (тростник, красный камень, алмазы, дерево для резаков, слитки золота, железа) занимает около 5 минут. Стоит отметить что количество изготавливаемых предметов не сильно влияет на время (2 процессора, скорее всего, будут делаться те же примерно 5 минут). Не умеет работать с альтернативными ресурсами. Возможно, когда-нибудь исправлю. Не умеет работать с инструментами (имеются ввиду многоразовые, как молот ИК2). Возможно, так же когда-нибудь исправлю. Не умеет работать с количествами предметов более стака, а также не гарантируется корректная работа с предметами, не складывающимися в стак. Постараюсь исправить в ближайшее время. Нет поиска по именам компонентов (то есть, либо задаёте название компонента целиком, либо задаёте крафт через каталог). Когда-нибудь поправлю Проверок на наличие контейнеров не делается, так как программа писалась "для себя" и находится в разработке. В дальнейшем будут введены. Также не везде гарантируется наличие защиты от "Количество предметов: Привет". Особенности: Шаблоны содержатся в одном файле, что облегчает переносимость, но приносит определённые неудобства всвязи с размерами файла (12 строк на предмет). Буду думать, как лучше сделать (разбить на разные файлы?). Файл имеющихся шаблонов могу выложить при необходимости (на разных сборках эти шаблоны могут отличаться) Дальнейшее развитие (no promises!): Исправление имеющихся недочётов Поддержка работы по сети (заказ компонентов, сообщение о готовности - дистанционно). Работа с более сложными инвентарями - сборщики, и т.д. Работа с машинами-обработчиками ресурсов - когда-нибудь в отдалённом будущем, скорее всего. Управление: Интерфейс текстовый. Посмотреть команды главного меню можно, нажав "Enter" (оставив поле ввода пустым).
  18. Представляю вам свою первую более-менее серьезную программу для openComputers. Ее единственная функция - проиграть указанный музыкальный файл. Файл формата nbs, это трекерная музыка с майнкрафтовской спецификой (т.е. написана для музыкальных блоков) Для создания и редактирования файлов в этом формате используется программа Minecraft Note Block Studio, ссылка на тему на майнкрафтфоруме: http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-tools/1260747-minecraft-note-block-studio Там же можно найти уже готовые музыкальные треки. Большую часть их программа сможет воспроизвести, проблемы будут с треками, содержащими нестандартные музыкальные инструменты и использующие диапазон шире двух октав. Но даже их можно проиграть, предварительно поправив в редакторе, он делает это автоматически. Ссылка на программу: http://pastebin.com/yrtLYBhz Использование очень простое, параметр всего один - относительный путь до файла (с расширением).Да, и помимо собственно компьютера вам понадобятся железные музыкальные блоки из Computronics, подключенные к нему. Штук восемь, можно больше или меньше, если их будет меньше, чем того требует трек, программа помрет, если больше - запас, как говорится, карман не тянет. В планах упаковать программу в библиотечку, сделав возможность включать плеер из других программ. Например, для саундтрека в играх. Еще хотелось бы решить проблему со сбивающимся ритмом, если подскажете способ создавать задержки точнее, чем через pullSignal и os.sleep, буду очень благодарен. Видео работы:
  19. Ходя по интернету, я не встречал более удобную программу для редактирования воксельных моделей чем MagicaVoxel. Я уже использовал ее для крутых черепах, и теперь она пригодится нам всем и для принтов. Я сделал конвертер для переноса бинарного формата .vox в текстовый. Использование: 1 https://ephtracy.github.io/ Скачайте и установите MagicaVoxel. Сделайте модель своей мечты. Не забудьте следить за размерами в правом верхнем углу - размер одного печатного блока 16х16х16. Можно превысить размеры - конвертер просто сделает список больше чем из одного блока. 2 http://codepen.io/Krutoy242/full/xGOgJG/ Сохраните и откройте модель в моем модном конвертере. Настройки такие же как в принте - название, подсказка, пару флагов и свечение. Так же, после загрузки модели можно будет выбрать текстурки и цвета каждого типа блоков. Флажек "Split to states" разделит вашу модель пополам по оси X что бы из второй части сделать изменение модели при нажатии\подаче редстоун сигнала. Например, для калитки вам нужно в MagicaVoxel задать размер 32 16 16, в одном квадратике нарисовать закрытую калитку, а во втором - открытую. Вот и всё! Полученный текст можно вставить в файлик и отпечатать по гайду Тоторо. Позже добавлю программу, позволяющую печатать по очереди сразу несколько моделей. Конвертер написан на JavaScript. Он читает бинарный файл и объединяет воксели в группы. Программа в какой то степени оптимизирована. Например эти стержни конвертировались автоматически со 100% эффективностью. Но в некоторых случаях, конечно, при создании модели человеком можно будет сэкономить 2-3 шейпа из 23х максимальных. Пишите свои отзывы и пожелания по улучшению конвертера.
  20. Всем привет! В этой теме я расскажу моей программе ---Удалённом рабочем столе на сети 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 Адрес сервера> Вот и всё=) Надеюсь,эта программа вам будет полезна ! Неплохо было-бы попасть в вайт-лист
  21. Как извлечь дискету программой на дискете из того дисковода, в который она была вставлена игроком?
  22. Представляю Вашему вниманию RedOS, ОСь предназначенную для первоуровневых компьютеров. Версия 1.1 Особенности: 1. Интуитивный и минималистичный интерфейс 2. Возможность копировать, удалять и переименовывать файлы и папки 3. Установка через дискету* 4. Буферизация графики 5. Низкие системные требования Интерфейс очень простой и понятный, снизу рабочая папка и страница, слева - названия файлов и папок, в центре - тип, справа - размер. Очень удобный курсор, который сразу дает понять, где и с чем именно ТЫ будешь работать, также есть защита в случае, если случайно нажмете на удаление или еще чего) Расширенный набор функций удовлетворит любого пользователя MAC своими возможностями Поддержка установки как через Pastebin, так и через дискету Гайд по созданию установочной дискеты: 1. Установить ОС через pastebin 2. Вставить дискету 3. Скопировать все из "/ISO" на дискету 4. Использовать ее как установочную для Бабушкиного ведра)) И наконец, системные требования: Жесткий диск : 40 Кбайт для версии с дискеты и 88 для версии с Pastebin Видеокарта: должна присутствовать Процессор: смотри на видеокарту Оперативная память: 256 Кбайт Дополнительная периферия: Дисковод или Интернет карта, монитор, клавиатура, bios Установка производится после установки OpenComputers Ссылка на скачивание через Pastebin: XRGVrufj Просто напишите в консоли pastebin run XRGVrufj)) Ссылка на исходники на Github
  23. Многие игроки здесь видели или хотя бы слышали про огромный дронодом, который построил @Asior в былые времена на сервере RoboCraft. С тем чтобы прояснить происхождение этой хаты и оставить о ней заметку в этом клубе, специально для «Новостей подполья» @Fingercomp обратился к создателю постройки и попросил рассказать про неё. Редакция представляет обработанную версию истории. История начинается в начале мая 2016 года, когда запустился сервер RoboCraft, на который сразу же хлынули толпы игроков, хотевшие «поскорее стать топовыми игроками, обладателями гор ресурсов и, конечно же, новых идей и программ». Туда попал и герой нашего рассказа. Развитие было довольно сложным. «Поначалу я хотел, как обычно, отстроить бункер и спокойно, потихоньку наращивать силы», но этому воспрепятствовал случай: система автоматического расселения игроков закинула Asior невесть куда — в середину заражённого биома. Очевидно, что герой этому не обрадовался. Ему потому пришлось бегать в поисках нового места. Конечно, Asior таки организовал себе временное убежище и начал стремительное развитие в игре. Но в чате игроки часто оставляли ссылочки на скриншоты своих невероятно красивых палат с невероятно крутых ракурсов. Он перерыл огромное число чертежей домов, замков, статуй — и решил построить дрона. Дрона из OpenComputers. Ведь сервер специально разрабатывался для этого мода. Asior зашёл в сингл и долго, упорно воздвигал новые варианты постройки и безжалостно крушил старые. Наконец, он определился с тем, как именно должно будет выглядеть его будущее жилище. Оставалось лишь воспроизвести это всё на сервере. Но здесь и возникла основная проблема: как добыть такое огромное количество ресурсов для строительства? Разрешена она была путём не самым чистым: Впрочем, и того, что он раздобыл, сполна хватило на постройку основного корпуса дрона. Это потребовало огромного числа строительных лесов и невероятных акробатических способностей и дополнительно осложнялось тем фактом, что полученные вечные блоки не перемещались из хотбара. Но стиснув зубы и получая подкормку от щедрых игроков Asior таки построил дрона. Потому пришлось придумать, как расширить жилище. Некоторые предлагали соорудить какое-нибудь здание, к которому был бы «привязан» дрон, но, увы, это не вписывалось в местность. Далее настала очередь внутренней отделки: ставились перегородки, размещалось оборудование. А монументальное сооружение, памятник роботу и дрону, стал пользовался большой популярностью, чему создатель не противился: «я был не против, чтобы все желающие посмотрели, как я живу, уточнили какие-то вопросы или помогли чем-нибудь». С тех пор сервер RoboCraft давно закрыт, но память о роботе и дроне жива до сих пор. Редакция присоединяется к пожеланию героя остроить то, что поражало бы воображение и отпечаталось в приятных воспоминаниях десятков игроков. И мы всё так же мы призываем вас оформить подписку на «Новости подполья». Годноты здесь много было, есть — а то ли ещё будет.
  24. Автокрафт на роботе. Программа не имет GUI. Всё управление осуществляется через командную строку. Для работы вам потребуется робот и сундук. Сундук должен стоять перед роботом. Робот должен иметь следующие улучшения: Улучшение «Контроллер инвентаря» Улучшение «Инвентарь» Улучшение «Создание» Улучшение «База данных (1-ый уровень)» Процессор уровня 2 и выше. Необходимый объём памяти и жёсткого диска зависит от количества предметов в сундуке и сложности рецепта. При тестировании использовался робот со следующими характеристиками: см. скриншот. Базу данных программа сохраняет в текущем каталоге. Поэтому для работы программы нужно создать отдельный каталог. Недостатки. Предварительный подсчёт достаточности ресурсов для выполнения сложного крафта не выполняется. Планируется исправить в будущих версиях. Инструкция с картинками. Man Скачать Версия 0.10.8 Старая версия
  25. Здрассьте, господа, у нас тут превесёлая вещь случилась: спустя полгода разработки (причём круглым числом; 28 мая стартанули) у нас отрелизился репозиторий! Обозвали мы его Hel. В репозитории мы собрали и воплотили в жизнь все хорошие идеи и концепции, которые обсуждались здесь, чтобы получился максимально кавайный способ дистрибуции пакетов. Пользоваться репозиторием не сложнее, чем ставить программы с Pastebin. Для этого нужно знать только название пакета. Одна команда: $ hpm install <нужный пакет> И вуаля! Он уже установлен в нужную папку, все нужные библиотеки загружены и распиханы по системе. Можно запускать и работать. Но по сравнению с OPPM или Pastebin, hel несравненно удобнее. Он легковесный. Простой. Не требует регистрации. И СМС. Чем мы гордимся, безусловно. Установка программ производится с помощью одного легкого клиента (как у Pastebin), но в то же самое время, вам не нужно волноваться о библиотеках или версиях программы. Вы всегда можете найти и установить самую свежую версию (и даже не самую свежую), зная только название пакета (как в OPPM). Кстати, раз уж мы заговорили про OPPM. У нас клиент получился настолько охренительным, что вы можете теперь выкинуть oppm в помойку, наконец-то! В стандартный комплект поставки включён oppm-модуль с кэшированием (иными словами, вам не нужно будет ждать пару минут, пока пробрутфорсятся репозитории, сразу всё качается). Всё быстро, чётко, ясно. Юзается оно так: $ hpm oppm:install <имя пакета> Об остальных фичах читайте уже в мануале hpm, там всё есть.
×
×
  • Создать...