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

eu_tomat

Модераторы
  • Публикации

    2 666
  • Зарегистрирован

  • Посещение

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

    331

Сообщения, опубликованные пользователем eu_tomat


  1. 28 минут назад, WheatComp сказал:

    @eu_tomat а нельзя ли обойтись без сложностей? Нельзя ли захардкоджить и получить доступ к значениям внутренних таблиц при помощи индекса цикла for и простого доступа вроде table[1][1][key] или table[1.1.key] или table[1][1].key? Мы же знаем, что внутри внешней таблицы - таблица?

    Если мы собираемся работать с конкретной таблицей с неизменной структурой, можно и захардкодить. Конструкции вида table[key1][key2] и table.key1.key2 позволяют это сделать.


  2. 1 минуту назад, WheatComp сказал:

    @eu_tomat понимаю, что проще всего сериализацией вывести, насчет for-а стало интересно ради понимания Lua.

    Да, можно. Пишем функцию, выводящую таблицу в цикле for k,v in pairs(table). Добавляем условие. Если очередное поле оказалось таблицей, то рекурсивно вызываем эту же функцию уже для вложенной таблицы. В противном случае печатаем поле как обычно. Это самый простой способ. Если требуется наглядность, можем добавить параметр функции, задающий размер отступа для вложенных элементов.


  3. 1 час назад, WheatComp сказал:

    Там пишется, что нужно нажимать ПКМ 1 секунду, но у меня почему-то не пищит, и информацию не дает, ни в терминал планшета, ни в интерпретатор. Пробовал component.geolyzer.analyze(3), но показывает воздух.

    Там написано, что при нажатии генерируется событие. Соответственно, чтобы получить информацию, надо это событие обработать. Например, запустив в интерпретаторе Lua такой код:

    while true do print(serialization.serialize({event.pull()}))end

     

    • Нравится 1
    • Спасибо 1

  4. 17 минут назад, WheatComp сказал:

    Значит, дело в беспроводной карте хоста? Если беспроводная карта не primary, то она не отсылает сообщение.

    Зависит от кода программы. Если выбирать сетевую карту кодом modem = component.modem, то будет выбран именно главный компонент. И если им является проводная карта, то сообщение по беспроводному каналу не будет послано.

     

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

     

    @WheatComp Кстати, я думаю, что в описанной задаче вообще не нужна проводная плата, т.к. и беспроводная точно также обеспечивает передачу по проводам. Если требуется заблокировать передачу по воздуху, можно уменьшить до минимума мощность передатчика кодом modem.setStrength(0). Или можно использовать разные номера портов для передачи по проводам и по воздуху.

    • Нравится 2
    • Спасибо 1

  5. 11 минуту назад, WheatComp сказал:

    Он должен быть получить сообщение, потому что modem.broadcast же выполняется на всех двух картах?

    Широковещательное сообщение может быть принято любой сетевой платой с открытым портом-адресатом при наличии среды передачи (либо при подключении кабелем, либо нахождении в зоне действия беспроводного сигнала).

     

    15 минут назад, WheatComp сказал:

    аже если сделать broadcast во время, когда в primary хоста стоит беспроводная карта, не-хост все равно получает сообщение, и показывает адрес беспроводной карты (в поле, где указан адрес карты-отправителя), хотя у него не установлена беспроводная карта!

    Беспроводную сетевую плату можно рассматривать как улучшенный вариант обычной проводной платы, т.к. она сохраняет возможность проводной связи.

     

    18 минут назад, WheatComp сказал:

    не совсем ясно, для чего именно служит Primary модемов, в документации об этом мало сказано.

    Главный компонент нужен лишь для упрощения подключения компонента. Если главный компонент назначен, то для его подключения достаточно лишь выполнить что-то вроде modem = component.modem. В противном случае приходится использовать более длинный вариант кода с component.list("modem").

     

    22 минуты назад, WheatComp сказал:

    можно через invoke

    Нет принципиальной разницы в работе с компонентами через component.invoke или component.proxy.

    component.proxy удобнее для программиста, и является высокоуровневым API для component.invoke.

    component.invokeчуть меньше нагружает компьютер, а также доступен из EEPROM, т.к. является низкоуровневым интерфейсом.

     

    • Нравится 2

  6. 53 минуты назад, WheatComp сказал:

    было бы, кстати, любопытно посмотреть, где устанавливается такая пауза

    В этом месте: https://github.com/MightyPirates/OpenComputers/blob/af2db43c53b9690fceabfb813987572bf2258db5/src/main/resources/assets/opencomputers/loot/openos/boot/04_component.lua#L104-L108

    function component.setPrimary(componentType, address)
      ...
            timer=event.timer(0.1, function()
              adding[componentType] = nil
              primaries[componentType] = primary
              computer.pushSignal("component_available", componentType)
            end)

     

    В 21.05.2023 в 19:45, WheatComp сказал:

    В одном компьютере установлены 1 проводной и 1 беспроводной модемы. Через проводной данные принимаются, а через беспроводной отсылаются данные рою из роботов. Каждый модем работает в разное время, с разными программами. Сначала запускаю программу для принятия данных через проводной. Закрываю, запускаю программу для беспроводной. В этот момент вылетает ошибка (фото). Каждый модем устанавливается своей отдельной программой как первичный через component.setPrimary("modem", "адрес модема").

    Предлагаю рассмотреть другой вариант решения задачи. Так как сетевых плат всего две, а их типы различны, то можно отказаться не только от манипуляций с главным компонентом, но и от запоминания адресов. Например, так:

    local component = require"component"
    
    local wireless_modem_required = true
    local modem
    
    for addr in component.list"modem" do
      if component.invoke(addr,"isWireless") == wireless_modem_required then
        modem = component.proxy( addr )
        break
      end
    end
    
    if modem then
      print( modem.address )
      modem.broadcast( 1, "success" )
    end

    Значение переменной wireless_modem_requiredв этом коде задаёт тип сетевой платы: проводной или беспроводной.

     

    • Нравится 1
    • В шоке 1

  7. 5 часов назад, WheatComp сказал:

    И при таком коде выдает то же самое (после закрытия программы для проводной карты), при повторном запуске этой же программы для беспроводной карты без изменений работает нормально:

    При изучении функции component.setPrimary можно заметить, что главный компонент устанавливается не сразу, а по истечении таймера в 0.1 секунду. Соответственно, если программа переопределяет главный компонент, то перед его использованием следует выполнить задержку не менее 0.1 секунды. Например, так: os.sleep(0.1)

     

    И ещё возникает вопрос: а зачем вообще переопределять главный компонент? Адрес нужного компонента уже известен, поэтому можно сразу обращаться к нему, не дёргая лишний раз API и не выдерживая паузу.


  8. В 20.05.2023 в 15:19, WheatComp сказал:

    Не совсем понял эту фразу. Во время игры пользоваться внеигровыми символьными ссылками? Чтобы программа робота обращалась к папке вне корневой папки Майнкрафта? Так мне это и требовалось.

    Что именно требовалось, мне до сих пор не особо понятно. Для примера опишу свой подход.

     

    Я использую символические ссылки для тестовых целей в творческом режиме. Мои файлы с программами и конфигами обычно находятся в удобном для разработки месте, вне игрового каталога.

     

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

     

    При последующих экспериментах я создаю ссылки на нужные мне файлы и каталоги, используя комбинацию клавиш C-x s в Midnight Commander.

     

    Иногда я подменяю ссылками каталоги самих дисков OC. Получаются как бы клонированные диски. С точки зрения игры эти диски не являются клонами, но по факту они ссылаются на общее хранилище.

     

    Если требуется провести масштабный эксперимент с десятками роботов, то я беру их из креатива. В момент установки роботов в мир появляются каталоги, соответствующие их дискам. Для массовой подмены каталогов я использую скрипт, подменяющий только пустые каталоги с подходящими именами:

    #!/bin/bash
    # Подмена каталогов жёстких дисков OpenComputers ссылками на каталог-источник 
    # Параметры запуска: каталог-источник, каталог OpenComputers сохранения игры
    
    dirSource=$1
    dirTarget=$2
    
    for dir in $dirTarget/*; do
      # обрабатывать только каталоги
      if [ ! -d "$dir" ]
        then continue; fi
      # обрабатывать только каталоги с подходящими именами
      if ! (basename "$dir" | egrep -q \
        '^[0-9,a-f]{8}-[0-9,a-f]{4}-[0-9,a-f]{4}-[0-9,a-f]{4}-[0-9,a-f]{12}$') \
        then continue; fi
      # обрабатывать только пустые каталоги
      if [ -n "$(ls -A ""$dir"")" ]
        then continue; fi
      # подмена каталога ссылкой на источник
      rm -r "$dir"
      ln -s "$dirSource" "$dir"
    done

     

    • Нравится 1

  9. 40 минут назад, WheatComp сказал:

    Вы тоже имели в виду роботы с eeprom? Или, может, UMFAL AtomicScience-а?

    Не обязательно именно EEPROM. Эти идеи хорошо работают и в среде OpenOS, да и вообще универсальны.

     

    К сказанному @ECS добавлю возможность получить файл с сервера в интернет, коим может быть и домашний компьютер. То есть, можно получить файл, находящийся не только в другом каталоге, но и на другом компьютере. Единственное, мне не нравятся сетевые задержки, особенно при запросе файлов через интернет. Поэтому в игре я предпочитаю использовать инсталляторы, единожды скачивающие все необходимые файлы на локальный диск робота, а общение по сети сводить к минимуму. Но конечное решение всё равно зависит от конкретных игровых условий и личных целей в игре.

     

    Дюп дисков хотя и является читерским, но тоже позволяет решить задачу внутриигровым способом. Законность дюпа устанавливает администрация конкретного игрового сервера. Можно считать это серой игровой механикой.

     

    Другие игровые механики сейчас мне на ум не пришли. А за пределами игры можно воспользоваться всей мощью хостовой операционной системы. Например, для тестирования программ в локальной игре очень удобны символические ссылки. Но их использование в выживании является ещё большим читерством чем дюп дисков.

    • Нравится 1

  10. 1 час назад, WheatComp сказал:

    Пытаюсь сделать так, чтобы программа использовала функции в модуле из папки вне корневой папки Майнкрафт-а, а из папки

    А какова цель этого трюка? Как выше уже ответил @ECS , получить доступ к файлу за пределами каталога сохранения с помощью package  невозможно. Но можно сделать что-то похожее на это.


  11. 10 часов назад, IceFox сказал:

    @eu_tomat а какую программу лучше использовать и как для большого количества форм? мне их 1000 штук сделать надо
    можно просто кликер на определенное изображение?

    Я не анализировал, какая из программ лучше. Обычно использую то, что имеется под рукой. А под руку чаще всего попадает xdotool. Анализировать изображение на экране я не пытался. Вместо этого я запоминаю координаты нужных мне кнопок, их положение статично.

     

    Есть разные варианты автоматизации.

     

    В простейшем варианте пишем bash-скрипт, который на стороне клиента с некоторым интервалом вслепую выполняет клики мышью по заданному набору координат, а по окончании работы делает паузу, чтобы на стороне сервера транспозер мог выполнить необходимые действия: поменять заготовку, резец, убрать стружку. Скрипты на сервере и клиенте не могут обмениваться информацией, а потому результат не гарантирован. Но транспозер может отсортировать брак, анализируя поле damage заготовки.

     

    В более сложном варианте можно синхронизировать работу скриптов с помощью интернет-платы. Тогда программа на сервере может анализировать состояние заготовки и высылать клиентскому скрипту задание. В случае пропуска кликов может быть выслано корректирующие задание для доработки детали.

     

    Можно усложнить схему, комбинируя оба варианта. Если сервер не перегружен, а пакеты при передаче между клиентом и сервером не теряются, обмен информацией можно выполнять изредка, по необходимости, не теряя времени на ожидание ответа. Например, дали клиенту задание прокликать 1000 заготовок по определённой схеме и с каким-то интервалом, а дальше только меняем расходники и вынимаем стружку. Количество и тип брака учитываем. Для исправления однотипного брака также формируем массовое задание.

     

    Но можно упростить скрипты ещё сильнее. Например, на клиенте запускаем скрипт, бесконечно кликающий по кнопке первого положения резца. Серверный скрипт транспозером проверяет состояние заготовки и в случае завершения текущей стадии её обработки заменяет её на новую, пока имеются необработанные заготовки. А потом мы вручную перезапускаем скрипты сервера и клиента с другим положением резца, повторяя операцию для всех заготовок, прошедших первый этап обработки. И так далее.

     

    Вариантов автоматизации множество. При особом желании массовую токарку можно сделать быстрой и надёжной.

     

    • Одобряю 1

  12. В 15.04.2023 в 11:32, Kotik8012 сказал:

    name у них одинаковый ic2:te,а label меняется если менять язык игры(да и к имени привязываться как-то не очень).

    Блоки IC2 для Minecraft 1.12.2 можно различать по полю damage.

    У блока реактора оно имеет значение 22, а для реакторной камеры — 24.


  13. 11 час назад, Bumer_32 сказал:

    никогда такой штуки не было хотя всегда чищу компрессором

    Иногда бывает достаточно перенести старый системник в другое место, чтобы вызвать проблемы. То есть, тут и чистка, возможно, не при чём. Ещё некоторые рассказывают о том, что большим давлением можно сдуть мелкие элементы с платы, но сам я с этим не сталкивался, хотя чищу компы именно компрессором.

     

    @surovyural Слишком мало информации для ответа на этот вопрос. Я в подобных случаях полностью разбираю компьютер, проверяю, нет ли оторванных элементов на платах или чего-то лишнего вроде металлических скрепок, залетевших под радиаторы. Затем собираю и тестирую систему на столе, без сборки в корпусе. Затем обратно собираю в корпус и тестирую. Бывает иногда, проблемы проявляют себя именно в корпусе.


  14. 3 часа назад, hohserg сказал:

    А насколько сложно найти RAT на своем компудахтере?

    Насколько я понял из мутного описания, RAT не является вирусом. Это лишь способ спрятать произвольный код в одном из файлов. Он может как являться вирусом, так и не быть им.

     

    Сложность обнаружения модификации всецело зависит от конкретного кода. Если внедрённый код перехватывает системные вызовы, то его обнаружение может стать практически невозможным в скомпрометированной системе. С другой стороны, проверка скомпрометированных носителей на чистой системе способна однозначно обнаружить любую модификацию. Это если говорить о чисто системных файлах.

     

    Найти же зловредный участок кода в пользовательских программах и библиотеках, не имея эталона файлов, вряд ли возможно, т.к. эталон зачастую  отсутствует. Максимум, можно формировать эталон динамически для каждого отдельно взятого компьютера или группы компьютеров. Но сложность тут снова в том, что проверку на соответствие эталону имеет смысл проводить лишь на гарантированно чистой системе.

     

    3 часа назад, hohserg сказал:

    Предлагаю провести исследование и разработать методы сокрытия кода на компе ОС

    В любом случае я предпочитаю считать скомпрометированным любой компьютер, на котором кто-либо мог запускать произвольный код или извлекать компоненты в моё отсутствие. Все носители такого компьютера следует тестировать в гарантированно чистой среде.

    • Нравится 2

  15. 23 минуты назад, Oleshe сказал:

    Вообще это Filesystem API.

    Ага, вот в чём дело.

     

    В общем, есть компонент filesystem, и его метод list действительно возвращает массив.

    А есть библиотека filesystem, и её метод list возвращает итератор.

    И если требуется на основе этого итератора сформировать массив, то без костылей это делается, например, так:

    files={}
    for file in filesystem.list("/") do
      files[#files+1]=file
    end

     

     

    • Нравится 1

  16. В 09.09.2022 в 15:12, Krutoy сказал:

    Вопрос такой - как узнать все доступные в наковальне символы? Не все символы можно вставлять в название, например

    §

    Очень интересно получается:

    • Через наковальню знак параграфа нельзя добавить, зато можно через компьютер.
    • Через наковальню можно задать имя робота длиной максимум 30 символов, а через компьютер — больше мегабайта. И это, скорее всего, не предел, просто для вызова функции rep не хватило оперативной памяти. Ограничение EEPROM в 4096 байт с этого момента потеряло свою актуальность.

     

    Upd:

     

    Обсудили этот трюк в дискорде:

    • Я заметил, что видимое имя робота обрезается по модулю 64 KiB. Например, при длине имени 64*1024+1 видимое имя будет состоять из одного символа, по крайней мере, при использовании стандартных ASCII-символов.
    • @ProgramCrafter сделал прогноз, что имя длиннее 32KiB не переживёт перезагрузки сервера. Так и вышло: сохранился лишь огрызок из 32769 символов. Формат NBT не позволяет сохранить больше.
    • Нравится 1
×
×
  • Создать...