Перейти к публикации

Таблица лидеров


Популярные публикации

Отображаются публикации с наибольшей репутацией начиная с 25.02.2019 во всех областях

  1. 6 баллов
    Представляю вам опять программу для робота, которая позволяет добывать руду, не лазая по пещерам. Робот, используя геолизер, может самостоятельно находить и добывать руду. Реализованы еще не все возможности, поэтому прошу тестировать и сообщать мне о багах. Требования: Корпус компьютера (уровень II или III) Апгрейд инвентарь (больше - лучше) Апгрейд контроллер инвентаря Жесткий диск EEPROM с прошитым Lua BIOS Геосканер Память (уровень I или выше) Процессор (любой) Апгрейд полета (I уровень) Алмазная кирка или аналогичный инструмент. Опционально: Апгрейд верстак Беспроводная сетевая карта Апгрейд батарея Апгрейд опыта Апгрейд чанклоадер Апгрейд генератор Эндерсундук из мода EnderStorage Установка: Скачать и сохранить файл как init.lua wget https://raw.githubusercontent.com/DOOBW/geominer/master/miner.lua init.lua Закинуть этот файл в корень диска. Добавить диск при сборке робота. Установить робота на платформу из твердых блоков. Дать роботу кирку. Поставить возле робота контейнер и зарядник. Нажать кнопку питания и наслаждаться процессом.
  2. 5 баллов
    Не так давно решил я немного нафармить обсидиана, но прыгать по озерам лавы, тушить её водой, а потом долго и нудно собирать как-то не то. Хотелось автоматизировать этот процесс. Да есть специальные генераторы обсидиана, но там требуются расходники в виде красной пыли или другого горючего материала, что для меня было неприемлимо. Поэтому был собран первый прототип генератора обсидиана. Портатип генератора обсидианта Version 1.0 В комплект к роботу требуется некая емкость для которая будет хранить лаву (я использовал барабан на 256 литров из мода Extra Utilities) и ведро охладителя (обычная вода). В робота необходимо вставить: Системный блок Т-2 Монитор Т-1 Клавиатура Видеокарта Т-1 ЦП Т-1 Память Т-2.5 (2 штуки) EEPROM (Lua BIOS) Жесткий диск Т-1 (OpenOS) Улучшение "Инвентарь" Бак для жидкостей" Улучшение "Контроллер бака" Так же не забываем про бур/молот который может выбирать сразу территорию 3х3. Для работы необходима постройка как на скрине. Ставим как на скрине сундук и зарядку, выдаем роботу в 1 слот охладитель, во второй бочку с лавой. Рекомендую заменить дно этой установки на какой то материал прочнее обсидиана, на крайняк обсидианом, причем в 2 слоя. Дело в том, что иногда происходит сбой в буре (зачастую из за ошибок сервера), из за чего он вскапывает не только по горизонтали но и по вертикали. Вы же не хотите в один прекрасный день обнаружить что от вашего генератора растекается лава по всему домику. Устанавливаем следующую программу: --1 слот ведро воды --2 слот бочка лавы --апгрейды: контроллер бочки, бочка, инвентарь local com = require("component") local r = require("robot") local tc = com.tank_controller local function go() while not r.forward() do os.sleep(0) end end local function goUp() while not r.up() do os.sleep(0) end end local function goDown() while not r.down() do os.sleep(0) end end local function dropFluid(slot) r.select(slot) if tc.drain() then --1000 мл r.fillDown() else if slot == 1 then r.select(2) else r.select(1) end tc.fill() dropFluid(slot) end end goDown() r.swingDown(0) repeat r.fillDown() print('обнуление!') until r.tankLevel() == 0 while true do go() r.turnLeft() dropFluid(2) go() r.turnLeft() dropFluid(2) go() dropFluid(2) go() r.turnLeft() dropFluid(2) go() dropFluid(2) go() r.turnLeft() dropFluid(2) go() dropFluid(2) go() r.turnLeft() dropFluid(2) go() r.turnLeft() go() r.turnAround() dropFluid(2) goUp() os.sleep(1) r.select(1) dropFluid(1) os.sleep(1) r.drainDown() tc.fill() goDown() r.swingDown(0) if r.count(3) == 64 then print('опустошаю инвентарь') goUp() for i=3, r.inventorySize() do if r.count(i) > 0 then r.select(i) r.dropUp(64) end end os.sleep(5) goDown() end if r.durability() < 0.1 then os.exit() end end ВНИМАНИЕ! Для тех кто копирует, внимательно после вставки проглядите код, там могут встретиться такие символы "?" из за этого программа не запустится (тапки кидать в кривой html код) Запускаем программу и наслаждаемся результатом. Прогон на время с разными бурами (Синий бур из Graviation Suite и Бур из Immersive Engineering) показал слабый результат, стак обсидиана за 2 минуты и 30~35 секунд. Меня такой результат вполне устраивал, но потом мне @Romanok2805 показал свою версию похожего генератора. Описывать его я не буду, поясню что смысл работы того генератора, он черпает ведром лаву из бочки, выливает её рядом с источником воды, меняет ведро на бур и разрушает обсидиан. И так по кругу. Генератор обсидианта Version 2.0 Немного подумав и внеся пару раз изменения в программу, добились нереального результата: стак обсидиана за 14~16 секунд! Итак, конфигурация робота: Системный блок Т-1 Монитор Т-1 Клавиатура Видеокарта Т-1 ЦП Т-1 Память Т-1.5 (2 штуки) EEPROM (Lua BIOS) Жесткий диск Т-1 (OpenOS) Улучшение "Инвентарь" Контейнер для улучшения Т-1 (в него устанавливается Бак для жидкостей) Код программы: --обсидиановый майнер с внешней бочкой --скоростной! local r = require("component").robot local slots = r.inventorySize() local function drop() for i=1, slots do if r.count(i) > 0 then r.select(i) r.drop(1) end end r.select(1) end while r.drain(0) do r.fill(3) r.swing(3) if r.count(slots) > 0 then drop() end end drop() Установка: Под роботом разместите бочку, над роботом сундук. Сзади можно установить зарядку. Сбоку рядом с роботом разлить воду, а рядом с местом где будет ставиться лава убрать 1 блок, чтобы вода туда стекала. Роботу вручите самую быструю кирку, желательно с чарами на эффективность. При желании можете напихать в робота прокачанных апгрейдов опыта, чтобы увеличить скорость разрушения блоков, но тут уже конфигурацию робота и как апгрейды прокачать, сами продумаете. Генератор обсидиана Version 2.1 Данная установка красиво выглядит, но довольно большая и бочка бросается в глаза сильно. Можно избавиться от бочки, забирая лаву из неё напрямую из инвентаря робота, но тогда сложность робота повысится и программа изменится. Итак, конфигурация робота точно такая же как у первого генератора. Код программы: --обсидиановый майнер с внутренней бочкой --скоростной! local r = require("component").robot local tc = require("component").tank_controller local slots = r.inventorySize() local function drop() for i=2, slots do if r.count(i) > 0 then r.select(i) r.drop(1) end end r.select(1) end while tc.drain() do r.fill(3) r.swing(3) if r.count(slots) > 0 then drop() end end drop() Установка: Все так же как и в предыдущем варианте, только бочку необходимо в 1 слот положить. Кстати такая структура фермы позволяет одновременно активировать 2 робота. Собственно такие вот получились варианты сборки фермы обсидиана, я конечно хз зачем вам столько его потребуется, но, коль уж есть программа почему бы ею не воспользоваться. Всем удачи, копайте обсидиант быстрее, чем вам сосед P.S. Большое спасибо за демонстрацию и помощь в написании программы @Romanok2805
  3. 5 баллов
    И снова доброго времени суток! Написал и недавно допили прогу по упровлению светом с помощью RedLogic! Команда для скачивания: pastebin get -f uZFEL62c light.lua Вот код: component = require("component"); side = require("sides"); color = require("colors"); rs = component.redstone; --funcs------------------------------------------------------------------------------------------------------------- function hlp() os.execute('clear'); check(); print('\n-------------------------------------------------', '\nlight_1_on - to switсh on a light_1;', '\nlight_1_off - to switсh off a light_1;', '\nlight_2_on - to switсh on a light_2;', '\nlight_2_off - to switсh of a light_2;', '\nall_on - switсh on all light;', '\nall_off - to switсh off all light;', '\n-------------------------------------------------\n'); end -- function check() local component = require('component'); local light_1 = component.redstone.getBundledInput(2, 14); local light_2 = component.redstone.getBundledInput(2, 4); if light_1 <= 255 and light_1 > 15 then print('Light_1 \x1b[32m++\x1b[0m '); elseif light_1 >= 0 and light_1 < 15 then print('Light_1 \x1b[31m--\x1b[0m '); end if light_2 <= 255 and light_2 > 15 then print('Light_2 \x1b[32m++\x1b[0m'); elseif light_2 >= 0 and light_2 < 15 then print('Light_2 \x1b[31m--\x1b[0m'); end end -- function _light_1_on() rs.setBundledOutput(2, 14, 255); os.execute('clear'); check(); end -- function _light_1_off() rs.setBundledOutput(2, 14, 0); os.execute('clear'); check(); end -- function _light_2_on() rs.setBundledOutput(2, 4, 255); os.execute('clear'); check(); end -- function _light_2_off() rs.setBundledOutput(2, 4, 0); os.execute('clear'); check(); end -- function _all_off() rs.setBundledOutput(2, 4, 0); rs.setBundledOutput(2, 14, 0); os.execute('clear'); check(); end -- function _all_on() rs.setBundledOutput(2, 4, 255); rs.setBundledOutput(2, 14, 255); os.execute('clear'); check(); end --main-------------------------------------------------------------------------------------------------------------- os.execute('clear'); print('Enter \'help\''); local cmds = { light_1_on = _light_1_on, light_1_off = _light_1_off, light_2_on = _light_2_on, light_2_off = _light_2_off, all_on = _all_on, all_off = _all_off, help = hlp } local term = require("term"); while true do term.write('> '); cmd = term.read(); if cmd == false then print("Exiting!") os.exit() end cmd, _ = cmd:gsub("\n",""); if type(cmds[cmd]) == "function" then cmds[cmd](); else print("No such command: " .. cmd); end end (На лампе №1 нет контакта, но и так понятно что всё работает) Если преодолею лень и перестану тупить то возможно у этой проги появится GUI!
  4. 4 балла
    Еще одно обновление. Удалил из TODO свайпы - слишком сложно и бесполезно. Добавил в TODO QR-коды для ссылок - очень просто (нашел либу и научился ей пользоваться) и полезно - с сервиса_нейм ко мне в соцсеть_нейм и в мессенджер_нейм будут (надеюсь) быстрее перетекать юзеры и писать багрепорты, которые я сам не обнаруживаю. Фиксы: Ассоциации файлов не работали вообще Теперь "низкий уровень свободной памяти" - 64 килобайта. При меньших значениях возникали проблемы. Всплывающие окна теперь располагаются правильно. Добавлено: Подсказки пользователю о некоторых аспектах работы с системой (решил перевести все на нормальный фреймворк вместо однотипных кусков кода по всей оболочке). Кнопка "Продолжить" у поля ввода. Кнопка удаления уведомления, а так же при клике по самому уведомлению оно откроется полностью. У файлов в "Все программы" появилось контекстное меню. Изменения: Полный рефакторинг системы обновлений. Внимание: вам придет два обновления. Одно обновление обновит оболочку, а второе - инициализирует систему обновлений.
  5. 4 балла
    В процессе подгонки всех функций программа очень быстро разрослась. Дам краткий обзор всех новинок. Минимальная и максимальная плотность были вынесены в начало программы к остальным переменным. + переменная port, для модема. + переменные steps и turns, вначале для отладки. steps пригодилась для подсчета шагов, чтобы каждые 32 шага проверять состояние инструмента и батареи. + функция arr2a_arr() - преобразование списков в ассоциативный массив для быстрого доступа к элементам. Массивы tails, fragments преобразуются этой функцией, функции работающие с ними, адаптированны соответствующим образом. + функция report(), позволяющая передавать пользователю статусные сообщения посредством модема или связанной карты. В данный момент еще пикает и выводит сообщения на экран. Также завершает работу программы, при получении соответствующего параметра. remove_point() отделилась от функций, удаляющих метки из таблицы. Функция check() отделилась от функции step(). Каждые 32 шага или по принуждению вычисляет расстояние до стартовой точки, сохраняет текущие координаты. Если уровень энергии или инструмента не хватает на дорогу до дома + 64 шага, совершается переход домой, потом возврат к работе. Если есть генератор, происходит попытка заправки. Каждый шаг проверяются точки вокруг робота и удаляются, если робот может их достать. Функция calibration() объединилась с калибровкой компаса. Происходит проверка компонентов: геосканер, контроллер инвентаря, инструмент и наличие блока под роботом, в случае не обнаружения - программа завершается. Настраиваются модем или связанная карта. sorter() упростилась и ускорилась. + функция home() перемещает робота на точку старта, запускает сортировку и упаковку предметов, ищет сундук (требует, в случае не обнаружения). Складывает добычу в сундук, в случае переполнения ждет, когда освободится место. Достает из сундука неупакованные предметы и переупаковывает. Забирает из сундука стак с углем, при наличии генератора. Кроме перехода к точке старта, ищет в инвентаре эндерсундук из EnderStorage и сгружает ресурсы в него. Пытается найти более новый инструмент в сундуке, либо ищет зарядник и пробует засунуть в него и зарядить. На точке старта ждет, пока уровень энергии не достигнет 99% потом возвращается к работе. + функция main() - основной цикл сканирования и добычи. Робот сканирует весь чанк, в цикле перебирает все метки, выбирает ближайшую и перемещается к ней, пока не пройдет по всем. Ну и цикл перехода по спирали от чанка к чанку. Запускает функцию main(), по завершении вычисляет координаты следующего чанка, перемещает к нему, запускает main() и т. д., пока не дойдет до последнего, потом вызывает функуию home() и завершает работу. Осталось добавить возвращение по хлебным крошкам при аварии. И правильную работу с инструментами, имеющими нестандартную механику износа - энергетические и магические кирки/буры из модов. Еще можно заставить робота таскать с собой генератор из какого-нибудь мода и зарядник, тогда ему не нужно будет возвращаться на точку старта для подзарядки (а с эндерсундуком вообще на надо будет возвращаться) Бета-версию можно посмотреть и скачать тут - https://pastebin.com/hXWLDKre
  6. 3 балла
    Давным-давно делал модный файловый менеджер с графическим интерфейсом для опенкомпов. Переходы по папкам, запуск файлов, распаковака tarball'ов и просмотр картинок в одной программе, к тому же фичи в виде листания свайпами, экранной клавиатуры и горстки настроек. И все это добро занимало меньше килобайта. Но развивать идею не стал, код удалил и осталась только одна картинка тестовой версии. Недавно решил это дело возродить, без зависимостей и лишних свистоплясок. Для начала напишем функции, которые добавят дополнительные возможности для пользователя. Когда игрок тыкает в экран, создаются два события - touch и drop. Когда зажимает и тащит - touch, потом куча drag и в конце drop. Из имеющихся событий, можно развить дополнительные события - клик, двойной клик и свайп. Можно даже добавить сложные жесты, но пока не понятно, как они могут пригодиться. На все нужные события повесим слушателей и будем сохранять результат в переменную. Слушатель для события touch будет проверять, было ли предыдущее событие drop. Затем сравнит с временем от последнего клика, вычислит расстояние между точками, в которых произошло событие. При совпадении координат и заданным временем между кликами пошлет событие double_click. Для события drop надо проверить, было ли предыдущим touch и по тому же параметру скорости проверять время между событиями, чтобы не захватывать долгие нажатия. Если предыдущим событием было drag, то надо определить расстояние между началом и концом действия, вычислить угол и послать это все в виде события swipe. В итоге получится примерно такой код: local computer = require('computer') -- подгрузить обертку для uptime & pushSignal local event = require('event') -- подгрузить библиотеку событий local lastEvent = nil -- последнее действие local lastTouch = nil -- последнее касание local eventTime = nil -- время от последнего события local clickSpeed = 0.5 -- время, за которое совершается клик и дабл-клик event.listen('drag', function(...) lastEvent = {...} -- просто сохранить событие end) event.listen('touch', function(...) local e = {...} -- сохранить событие в таблицу if e[5] == 0 and lastEvent and lastEvent[1] == 'drop' then -- если нажата ЛКМ и предыдущее было drop if eventTime and computer.uptime()-eventTime < clickSpeed then -- если прошло меньше времени, чем задано if lastTouch and lastTouch[3]-e[3]+lastTouch[4]-e[4] == 0 then -- если координаты событий не отличаются computer.pushSignal('double_click', e[2], e[3], e[4], e[6]) -- послать дабл-клик с координатами end end lastTouch = e -- сохранить последнее касание end eventTime = computer.uptime() -- обновить таймштамп события lastEvent = e -- сохранить событие end) event.listen('drop', function(...) local e = {...} -- сохранить событие в таблицу if e[5] == 0 and lastEvent then -- если нажата ЛКМ if lastEvent[1] == 'touch' then -- если предыдущее событие было касанием if eventTime and computer.uptime()-eventTime < clickSpeed then -- если прошло меньше времени, чем задано computer.pushSignal('click', e[2], e[3], e[4], e[6]) -- послать клик с координатами end elseif lastEvent[1] == 'drag' then -- если предыдущее было тасканием local dx, dy = lastTouch[3]-e[3], lastTouch[4]-e[4] -- найти дельту до координат касания computer.pushSignal('swipe', e[2], dx, dy, math.floor(math.deg(math.atan(dx/dy))), e[6]) -- послать свайп с дельтой и углом end end eventTime = computer.uptime() -- обновить таймштамп события lastEvent = e -- сохранить событие end) Пока он ничего не делает, только создает события, когда будет готов функционал отрисовки и взаимодействия с файловой системой, добавим к этим слушателям управляющие функции.
  7. 2 балла
    Чтобы было куда кликать, надо на экране разметить места для иконок, еще и иконки нарисовать. Для иконок возьмем формат PPM, а конкретно, цветную бинарную версию P6. Формат ультра-примитивный, иконки можно будет без лишних заморочек рисовать в любом нормальном растровом редакторе, в опенкомпах, а при наличии нужного скрипта - прямо в консоли. Но в этом формате будем хранить иконки на диске. Внутри программы они будут преобразовываться в таблицу, хранящую цвет каждого пикселя. Например, создадим иконку, которая будет рисоваться для всех типов файлов по умолчанию. (Будет отображаться, если подходящая иконка не загружена) local icons = {} -- создать массив с иконками local icons.unknown = {x = 10} -- создать таблицу для иконки, указать ширину в пикселях for i = 1, 100 do -- цикл заполнения таблицы 10x10 if i%3 == 0 then -- если номер пикселя делится на 3 icons.unknown[i] = 3394611 -- сделать пиксель зеленым else -- иначе icons.unknown[i] = 3355443 -- сделать серым end end С внутренним представлением определились, теперь напишем функцию отрисовки. Создадим счетчики для индексов, горизонтальной и вертикальной координаты. Запустим цикл, с условием: пока индекс меньше или равен (количество пикселей - ширина изображения). Установим для символа цвет текущего пикселя, а для фона получим пиксель через текущий индекс + ширина изображения. И выведем полученные пиксели одним символом u+2580. Если счетчик по горизонтали досчитал до ширины изображения - сбросить в начало, к счетчику по вертикали добавить 1, а к индексу прибавить ширину. Получим пропуск строки, т. к. она уже была отрисована в текущей итерации. local function draw_icon(name, X, Y) -- получить название и координаты if not icons[name] then return false end -- прервать, если нет такой иконки local x, y, index = 1, 1, 1 -- создать счетчики while index <= #icons[name]-icons[name].x do -- пройти по индексам gpu.setForeground(icons[name][index]) -- установить цвет верхнего пикселя gpu.setBackground(icons[name][index+icons[name].x]) -- цвет нижнего gpu.set(x+X-1, y+Y-1, quad) -- вывести на экран if x == icons[name].x then -- если достигнута ширина изображения x, y, index = 1, y + 1, index + icons[name].x+1 -- обновить все счетчики else -- простая итерация x, index = x + 1, index + 1 -- обновить счетчик горизонтали и индекса end end end Одна иконка уже сгенерирована, чтобы вывести ее в углу экрана, вызовем ее по имени - draw_icon('unknown', 1, 1) В итоге, на экране получим такое изображение: Чтобы загрузить иконки и конвертировать в удобный вид, создадим такую функцию: Перебрать все файлы в папке, получив их список через filesystem API. Прочитать файл построчно в таблицу, попутно удалив строки с комментариями. Если заголовок файла равен , получить ширину картинки, информацию о пикселях объединить в одну строку. В цикле пройти по пикселям, конвертируя бинарное значение пикселя в число. Тут надо помнить, что значение одного пикселя хранится в трех символах (по одному на канал), поэтому цикл будет скакать через 3. Первый символ конвертируем в число, умножаем на 65536, второй на 256 и складываем. Полученное число добавляем в массив пикселей текущей иконки. Получаем примерно такую реализацию: local function load_icons(path) -- получить путь к папке с иконками local multiplier, path = {65536, 256, 1}, path or '' -- создать таблицу множителей for name in fs.list(path) do -- получить имя файла в папке local file = io.open(path..name, 'r') -- открыть файл if not file then break end -- если файла нет, прервать цикл name = name:gsub('%..+', '') -- обрезать название файла до первой точки local raw_img = {} -- создать массив для сырых данных for line in file:lines() do -- в цикле пройти по строкам if line and line:sub(1,1) ~= '#' then -- если строка не закоментированна table.insert(raw_img, line) -- добавить в таблицу end end file:close() -- закрыть файл if raw_img[1] == 'P6' then -- если заголовок совпадает local _ = raw_img[2]:find(' ') -- проверить наличие пробела на второй строке if _ then -- если размеры на одной строке _, raw_img[2] = raw_img[2]:sub(_+1), raw_img[2]:sub(1,_-1) -- разделить table.insert(raw_img, 3, _) -- перенести высоту на другую строку end raw_img[2] = tonumber(raw_img[2]) -- преобразовать ширину изображения в число icons[name] = {x = raw_img[2]} -- создать пустую таблицу для пикселей local current = '' -- создать переменную с сырой информацией о пикселях for i = 5, #raw_img do -- пройти до конца файла current = current..raw_img[i]..'\n' -- объединить данные в одну строку end local color, n for i = 1, #current-1, 3 do -- пройти по каждому третьему символу, исключая последний перевод строки n, color = 1, 0 -- сбросить счетчик для таблицы множителей и цвет for j = i, i+2 do -- перебрать три символа color = color+current:sub(j,j):byte()*multiplier[n] -- преобразовать символ в число и добавить к значению цвета n = n + 1 -- обновить счетчик end table.insert(icons[name], color) -- добавить цвет пикселя к остальным end end end end Реализация очень примитивная, но главное, что иконки будут загружаться. Можно было бы сотворить свой формат, который быстрей распаковывается и занимает меньше места, но плодить сущностей очень вредно. Для проверки, осталось нарисовать иконки, сложить их в папку /home/icons/, например. И запустить весь код: local fs = require('filesystem') local gpu = require('component').gpu local quad = require('unicode').char(0x2580) local icons = {unknown = {x = 10}} for i = 1, 100 do if i%3 == 0 then icons.unknown[i] = 3394611 else icons.unknown[i] = 3355443 end end local function load_icons(path) local multiplier, path = {65536, 256, 1}, path or '' for name in fs.list(path) do local file = io.open(path..name, 'r') if not file then break end name = name:gsub('%..+', '') local raw_img = {} for line in file:lines() do if line and line:sub(1,1) ~= '#' then table.insert(raw_img, line) end end file:close() if raw_img[1] == 'P6' then local _ = raw_img[2]:find(' ') if _ then _, raw_img[2] = raw_img[2]:sub(_+1), raw_img[2]:sub(1,_-1) table.insert(raw_img, 3, _) end raw_img[2] = tonumber(raw_img[2]) icons[name] = {x = raw_img[2]} local current = '' for i = 5, #raw_img do current = current..raw_img[i]..'\n' end local n, color for i = 1, #current-1, 3 do n, color = 1, 0 for j = i, i+2 do color = color+current:sub(j,j):byte()*multiplier[n] n = n+1 end table.insert(icons[name], color) end end end end local function draw_icon(name, X, Y) if not icons[name] then return false end local x, y, index = 1, 1, 1 while index <= #icons[name]-icons[name].x do gpu.setForeground(icons[name][index]) gpu.setBackground(icons[name][index+icons[name].x]) gpu.set(x+X-1, y+Y-1, quad) if x == icons[name].x then x, y, index = 1, y + 1, index + icons[name].x+1 else x, index = x + 1, index + 1 end end end load_icons('/home/icons/') local n = 1 for name in pairs(icons) do draw_icon(name, (n*11)-10, 1) n = n + 1 end Получаем:
  8. 2 балла
    Опечатка тут: gpu.setForeground(cf) аргумент приходит cF Вообще, при ошибке выводится название проблемной функции, а на скрине только аргумент. Но это тоже может помочь - рассмотреть или переписать строку, указанную в ошибке.
  9. 2 балла
    https://www.youtube.com/watch?v=AQE4V0J47bk
  10. 2 балла
    Компонент crystal, это прозрачный сундук из мода ironchest, подключается модом OpenPeripheral. Нумерация начинается с единицы, cry.getStackInSlot(i) возвращает таблицу с описанием содержимого слота или nil, если слот пустой. Код из стартового поста выглядит работоспособным, и я пока не вижу проблему. @Teen_Romance можешь выложить код не скриношотом, чтобы я его запустил у себя? А ещё нужны версии ironchest и OpenPeripheral.
  11. 2 балла
    Мяу, ну написали же русским языком, что getStackInSlot(номер слота) возвращает таблицу с информацией о предмете, если таковой имеется в слоте - либо nil в том случае, если слот пустой, для чего и нужна проверка на "пустотность". Шаг 1. Получил инфу о предмете в слоте stack = getStackInSlot(i) Шаг 2. Убедился, что в слоте есть предмет if stack then Шаг 3. Обработал информацию о предмете в слоте так, как требуется. НЕ НУЖНО вызывать getStackInSlot() еще раз. Переменная stack уже хранит результат вызова getStackInSlot() if stack.id == 8 then Конкретно в твоем случае ошибка происходит по той причине, что getStackInSlot возвращает nil, а ты пытаешься получить поле от возвращаемых данных по ключу id - вот и получаешь ошибку attempt to index a nil value. Слот пустой, id не существует. Делай проверку разово - и работай с переменной stack. Также я не совсем понимаю, почему ты используешь два цикла for i = 1, 10 / for j = 1, 10, когда число предметов в ME-сети явно может превышать 100. Наверняка там должен иметься метод getInventorySize, или getItemCount, или еще какой-то схожий - используй его. И еще: для сравнения id предметов с таблицей pe4 также придется делать отдельную логику. Что-то наподобие: local pe4 = { [1] = "камушек", [8] = "доски" } ... stack = cry.getStackInSlot(i) if stack and pe4[stack.id] then print("рассматривается валидный предмет") end Кроме того, как заметил @Asior, мы понятия не имеем, что это за компонент такой под названием "crystal". Так что если выяснится, что информация о его stack'ах вообще не содержит никаких id, либо его id является строковым наподобие "minecraft:stone" - то тут уж ты сам виноват. ПоДуМоЙ
  12. 2 балла
    Что такое crystal ? Все перебрал в МЭ так и не нашел этой штуки. И вообще покажи что за установка, чтобы можно было воссаздать и протестировать. А то так долго можно перебирать и предполагать "а если ..."
  13. 2 балла
    В сотрудничестве с @Zer0Galaxy мы доработали целочисленную библиотеку metaint. Итак, встречайте: RSA Криптосистема с открытым ключом Теперь на "отечественной" библиотеке metaint Доработаны алгоритмы поиска простых чисел - засчет уменьшения скорости шанс прохождения составного числа как простого уменьшен (на самом деле я просто сделал 8 тестов ферма на число) Поддерживаются ключи с кастомным количеством бит А так же полная оптимизация генерации ключей. Осталось лишь оптимизировать поиск простых чисел и ключи в 2048 бит в ваших руках. Установка pastebin run 1xudmTa7 - выберите RSA и установите. С hpm проблемы( Использование Библиотека возвращает класс. Для получения инстанса - просто require("RSA")(<params>): RSA_instance Аргументом (он один) конструктора класса может быть: строка - путь к файлу собственной структуры. В нем обязательно должен быть публичный ключ. число (битовая длина ключа, не менее 16 - иначе будет недоступно шифрование текста. Да и не выйдет меньше 16) таблица. В ней нужно 2 поля - private_key и public_key, структура как у файла ключа библиотеки. Так же должен быть публичный ключ. Методы инстанса RSA RSA:save(filepath: string) - сохранить ключ в файл RSA:encrypt(number:number) - зашифровать число RSA:decrypt(cryptedNum: number) - расшифровать число. Кинет ошибку, если нет приватного ключа RSA:sign(number: number) - подписать число. Кинет ошибку, если нет приватного ключа. RSA:verify(number:number, signedNumber: number): boolean - проверить подпись. Вернет true, если подпись верна. Работа с текстом. Очень медленно, битовая длина ключа - минимум 16 бит (StrToInt возвращает число в 32 бит, 16 бит*16 бит = 32 бит. Ограничение из-за использования остатка от деления). RSA:textEncrypt(text: string[,salt: string]):table[metaint] - шифрует текст поблочно, перемешивая блоки - защита от DPI. Блок равен 32 бита. Соль - строка, которая будет добавлена к тексту ради сокрытия первого блока текста (с ним не происходит ничего, он просто шифруется). RSA:textDecrypt(text: string[, saltLen: number]): string - расшифровывает текст с учетом длины соли, если она указана. Применяет обратное преобразование текста для расшифровки - защита от DPI, все дела. RSA:textSign(text:string): table[metaint] - поблочно подписывает текст, перемешивая блоки. RSA:textVerify(text:string, signedBlocks: table[metaint]): boolean - проверяет подпись текста. Работа с текстом проверялась на 32 битном ключе и юникоде (достаточно длинном). Ошибок алгоритма быть не должно. Более полная документация с описанием алгоритмов.
  14. 2 балла
    Я тоже такую оболочку делал, но идея себя быстро исчерпала.
  15. 1 балл
    Если задаваться вопросами о смысле, то какой смысл и в функции __index, если наличие элемента в таблице легко проверяется обычным обращением к самому элементу? Чем это удобнее уже обсуждённой конструкции if tbl[idx] then?
  16. 1 балл
    Вот я о чем: local knowns = {"A","B","C"} local indexer = { __index = function(self, key) return "unknown" end } setmetatable(knowns, indexer) for i=1,5 do print(knowns[i]) end результат: A B C unknown unknown т..е. __index стреляет только для тех элементов, которые отсутствуют в таблице knowns.
  17. 1 балл
    Сомнение в том, что __index вызывается только при отсутствии элемента в таблице.
  18. 1 балл
    @FelixBanan Дык это, а папки-то у него в каком виде вообще отображаются? Опеносовский ls? Или он хочет софтину для листинга с нуля написать? НиПаНЯяяТна
  19. 1 балл
    Ну как где? "pe4[stack.id]" - тут и сравнивает. Если таблица pe4 содержит элемент с ключом, эквивалентным значению поля id таблицы stack, то результатом будет значение элемента таблицы pe4 по требуемому ключу. Да, для того, чтобы ветвь if выполнилась, все условные элементы должны отличаться от nil. И нет, первая часть условия далеко не всегда будет истинна: если требуемый слот не содержит предметов, то переменная stack будет иметь значение nil. Для работы программы нужно банально пробежаться по всем слотам сундука, проверить, есть ли что-либо в слоте - и если есть, то проверить, является ли id предмета в слоте валидным (т.е. содержится ли он в таблице pe4). По крайней мере, я именно так понял условие задачи.
  20. 1 балл
    @Teen_Romance, local stack for i = 1, 10 do stack = cry.getStackInSlot(i) if stack then -- Делай чо надобно end end
  21. 1 балл
    Что значит "не может дать индекс"? Как выглядит ошибка? Какая версия OpenComputers?
  22. 1 балл
    Скорее всего, cry.getStackInSlot(j) для пустого слота возвращает пустую таблицу. Избежать исключения можно, проверив наличие поля cry.getStackInSlot(j).id.
  23. 1 балл
    Например: https://minecraft-ru.gamepedia.com/OpenComputers/GPU_API https://minecraft-ru.gamepedia.com/OpenComputers/Event_API
  24. 1 балл
    Хотел сегодня провести сногсшибательное обновление с полной оптимизацией всего и вся. Не вышло. Собственно, появилась оптимизация теста ферма, при первом непрохождении числа возвращает false. Это ускоряет тест для составных чисел (не всех) в 8 раз, но оставляет точность теста нетронутой. Так же после создания ключа он проверяется шифрованием какого-нибудь простого числа (оно само выбирается). Из нереализованного, но закомментированного: расширенный алгоритм евклида :C Прошу помочь с оптимизацией и фиксом уже его (xD), ибо например 64-битный ключ мне так и не удалось на нем сделать - постоянно отбраковывает ключ (с 8ю битами с раза 2-3 делает). Хотя ускоряет создание ключа реально сильно. https://github.com/HeroBrine1st/RSA/blob/master/RSA/RSAB.lua UPD: я почти разобрался с этим алгоритмом евклида и понял, что какого-то хрена алгоритм обрезает число до семи знаков)) Вот и вся проблема UPD2: Выход за пределы натуральных чисел - вычитание большего из меньшего. Передлываю алгоритм под натуральные числа.
  25. 1 балл
    io.lines хочет путь к файлу, а в коде даётся сразу хендл на него. Вот и ругается. for line in io.lines("f.txt") do print(line) end
  26. 1 балл
    В канале Experimental появились эти QR коды. Удалите файл /TabletOS/Settings.bin и переустановите систему с каналом Experimental, затем пройдите Setup Wizard и найдите в настройках уведомление "Добро пожаловать в графическую оболочку TabletOS" (это и есть те самые инструкции для юзера). Слова перед "кликабельно" вроде как кликаются. Вроде как, потому что не знаешь, как работать с этой луа, например у меня сегодня один и тот же код в разных функциях давал разный результат)) отличие было в цвете текста. Пока это в канале Experimental, могу послушать рекомендации по изменению вида этого QR-кода, ибо я не знаю. как убрать эту черную область (черный на зеленый не сменить - считыватель не видит тогда код) Использовал костыль от ECS (unicode.find из ECSAPI), либу qr кодов с гугла и braile bicycle с этого форума, модифицировав под даблбуфер. (Спасибо всем, что почти ничего не пришлось писать самому ) + свайпы таки могут появиться, я решил просто убрать анимацию, что позволит В РАЗЫ уменьшить количество кода. Что забыл сказать при обновлении вчера. Все необновившиеся до 1.0.6 потеряют доступ к обновлениям перед обновлением 1.0.7. Связано оно с тем, что в системе обновлений есть автоматическая подчистка файлов, которых уже нет в файллисте, а я как раз в 1.0.7 удаляю /lib/TabletOSGraphics.lua и переделываю ее в папку - будет несовместимость. Переустановить систему, к сожалению, не поможет :C Надеюсь с помощью installerScript исправить это
  27. 1 балл
    Уже вроде как сбрасывал кому то такую штуку, но повторю еще раз. --https://i.imgur.com/9aw0a6E.gifv --блоки руды сверху в сундук закидывать --сыпуху вниз будет скидывать --перед роботом не забудьте поставить подставку, так будет точнее ставить --в руку бур/кирку с максимальными чарами на удачу local r = require('robot') while true do r.select(1) if r.suckUp(64) then local rep = r.count(1) for i=1,rep do r.place() while not r.swing() do os.sleep(0) end end for i=1, r.inventorySize() do if r.count(i) > 0 then r.select(i) r.dropDown(64) end end else os.sleep(15) end end
  28. 1 балл
    краш в строке на 1.7.10 471 if item[slot].name == tool.name and item[slot].damage < tool.damage then Видно часть ошибки: (field '?') getAllStacks и getAllStacks().getAll() по-разному работают на разных версиях MC На 1.7.10: индексация массива из getAllStacks().getAll() начинается с 0, а не с 1. getAllStacks().getAll()[slot] для пустого слота возвращает пустую таблицу, а не таблицу с «воздухом» getAllStacks()[slot] для пустого слота возвращает nil, а не таблицу с «воздухом»
  29. 1 балл
    Идея отличная! Молодец! Главное не забрось идею, и если сможешь, зделай, пожалуйста, интерпритатор python!
  30. 1 балл
    Еще можно виртуальную клавиатуру, чтобы не ставить клаву, коль ОС тут на сенсор рассчитана
  31. 1 балл
    Нужен мод на рендер и генерацию. Разделить платформу на две части, свернуть перпендикулярно самой себе. Надо только понять, как рендерить место склейки платформ и скрыть переходы. Локальная система координат никак не изменится.
  32. 1 балл
    Есть такое, OpenPython называется. Но клепает его один человек, поэтому похвастать нечем. Работает кое-как, даже стабильной версии нет, годится только для микроконтроллеров. Где-то еще встречал упоминания о питоно-подобном процессоре для опенкомпов, но сейчас найти не могу.
  33. 1 балл
    Эта беспрецедентно короткая запись имеет начало своих ног в запросе @Laine_prikol, как-то спросивший в нашей ирке, можно ли стэктрейс сделать не таким тупым. Меня это заинтересовало, и спустя часик выросла очень короткая программка, которая рисует вот такие стэктрейсы: # 0: C field function yield(...) (defined in [C]) # 1: Lua local function f(f=function: 0x55bea5785ef0, a=42, b=24, ...):79 (defined in trace.lua at L78) # 2: Lua local function outer(f=function: 0x55bea608c900, g=function: 0x55bea5785ef0, a=42, b=24):75 (defined in trace.lua at L73) # 3: Lua function <anon>:83 (defined in trace.lua at L72) Заметили что-то необычное? Наконец-то пишется, какие аргументы имеются у функции, потому что это куда информативнее беглому взгляду, чем описание расположения и строки. Код лежит на гисте: https://gist.github.com/Fingercomp/a688d221356cb371d940b947d0ca90a8. Использованы функции debug.getinfo и debug.getlocal. Аргументы должны писаться даже внутри OC, но уже без значений.
  34. 1 балл
  35. 1 балл
    Да, название уже придумано 😃
  36. 1 балл
    О, самая сложная часть уже осилена? Ну, что сказать, все кактусы это взрывает напрочь. Буду следить — но не беспокойтесь: дальше этой темы слежку проводить не стану.
  37. 1 балл
    Билдкрафт бесполезен. Если уже добавлять ради труб то Термал. И помоему задумка евила в том что б автоматизировать все компом. А также здесь есть големы что носят вещи) А если ради карьера то чем тебе не нрав карьер из ик?
  38. 1 балл
    Билда не будет, можете не заказывать. Сборка стабильная, никаких модификаций пока вносить всеравно не будут. Да и куда еще вносить то, и так майн уже 3 гига памяти кушает, а у многих кто играет техника чуть сложнее калькулятора. Труб нет, но есть трасвекторы 2 типов, дроны, транспозеры, роботы или на крайняк 4 типа воронок, или раздатчики с импульсными генераторами редстоуна, пространственные сундуки и цисцерны, бочки из тинкерса. Так что автоматизации выше крыши. Почти все моды управляются через Opencomputers, ну кроме магических, но это и понятно. О каком карьере вы говорите? Ни одному карьеру и не снилось, что может сделать 1 робот. А если хорошо владеете программированием, то можно подчистую вынести весь мир. Недавно вот на сервере тестировал программу, около 15 минут работы робота и чанка уже не существует, а все ресы упакованы красиво в сундучки. Кому интересно попрыгайте по болоту на спавне, там только верхний слой земли остался. Вот что действительно надо, так это обновить мир Evil, где ресурсы добываются. А то там как кроты прошлись, дырки и вдоль и поперек.
  39. 1 балл
    Ой, забыл xD Спойлеры делать не умею. так что как-то так пока. Возможно на скриншоты слишком новые и из разрабатываемой версии.
  40. 1 балл
    А я все понять не мог про что вы говорите, теперь вспомнил как кошак материл квертика за приват его ямы.
  41. 1 балл
    Я всегда думал, что шрифт OpenComputers моноширинный. При просмотре этой таблицы полной неожиданностью для меня стало то, что символы в дипазоне FF00-FF5F и еще некоторые имеют двойную ширину.
  42. 1 балл
    UPD #1 - Добавлена смена инструментов (инструкция ниже!) UPD #2 - Прикручена система координат (пока ни как не используется) Робот который копает карьер, как бы не было банально, но он копает его максимально экономно! Характеристики робота: корпус 1 ур. 1шт, процессор 1 ур. 1шт, оперативная память 1ур. 1шт, улучшение инвентаря минимум 1шт (чем больше тем лучше) Для авто-смены инструментов нужно добавить контроллер инвентаря 1шт Для работы дать роботу кирку как минимум железную, а лучше всего электро-бур В программе есть настройки: Настройки задаются в исходном коде программы! trashSlots - количество слотов инвентаря под фильтры, и мусор который робот будет выкидывать по мере продвижения (в эти слоты желательно класть: камень, землю, гравий, песок, ... , булыжник (он ложится в последний слот, что-бы не тормозить функцию проверки блоков) предметы в слотах располагаются по мере их количества в предполагаемом месте работы (самые часто встречаемые, должны лежать в начале, что-бы не тормозить работу) !!! Все слоты-фильтры должны быть заполнены !!! lengh - Длинна карьера width - Ширина карьера (вводите четные числа, если введенное число не будет четным, от него отнимется 1) deepM - Высота карьера (вводите числа кратные 3, если число не будет кратное 3, от него отнимутся значения пока оно не будет кратное 3) Для авто-смены инструментов: -------------------------------------------------------------------------------------- toolSwich - смена инструментов роботом true - да / false - нет (если нет контроллера инвентаря оставить выключенным) tool1 - 1 слот для инструмента tool2 - последний слот для инструмента !!! Все отмеченные слоты должны быть заняты !!! -------------------------------------------------------------------------------------- Примечание!!! ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- Устанавливайте высоту карьера на 10 блоков меньше чем высота установки робота, во избежание застревания оного ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- Принцип работы: Робот опускается под землю, и идет змейкой в заданных параметрах проверяя блок под собой и над собой на совпадение в слотах-фильтрах. Если робот не нашел совпадение, то добывает блок, если совпадение найдено, движется дальше. После выкапывания всего, робот возвращается на поверхность и на место дыры под собой ставит блок из последнего слота-фильтра. Пример работы робота: https://www.dropbox.com/s/be9l5rnday5s7ej/2016-08-25_01.40.42.png?dl=0 https://www.dropbox.com/s/vxm0kmklyhpngud/2016-08-25_01.40.51.png?dl=0 Комплектация робота: https://www.dropbox.com/s/vqpn5uei5sjjmes/2016-08-25_02.19.47.png?dl=0 Настройки программы: https://www.dropbox.com/s/nww84qssk4vqa8z/2016-08-25_02.21.21.png?dl=0 Загрузка робота: https://www.dropbox.com/s/jbeuoudovdg63rf/2016-08-25_02.24.45.png?dl=0 Накопанные ресурсы за 1ч:10м: https://www.dropbox.com/s/vfg78en1hw1alx8/2016-08-25_03.41.41.png?dl=0 Робот прошел вниз 36 блоков. У него сломалась кирка и почти сел аккумулятор, так что ставьте глубину не больше 30 - 33 Исходный код: http://pastebin.com/fEa4Qxef https://gist.github.com/L3rok1/17e9265bc33032a9230d5feefe29165a
  43. 1 балл
  44. 1 балл
    А OpenNet между тем медленно но уверенно развивается. Начал свою работу чат-сервер "chatroom". Для подключения к серверу Вам понадобится компьютер или планшет, подключенный к ON, библиотечка thread и конечно же программа чат-клиент. В качестве параметра клиенту нужно указать ip или dns-имя чат-сервера Пример запуска клиента: chat chatroom А вот результат работы:
Таблица лидеров находится в часовом поясе Москва/GMT+03:00
  • Рассылка

    Хотите узнавать о наших последних новостях и информации?

    Подписаться
×