Перейти к публикации
Форум - ComputerCraft

Блоги

Рекомендованные записи

  • Krutoy

    Пишу браузер-арбузер

    Автор: Krutoy

    Новости! Теперь мой браузер будет называться "Арбузер", и будет выполнен в зеленоватых тонах.
    Zer0Galaxy мне помогает, и уже набросал парсинг и поиск по самым простым селекторам в CSS. Думаю, ему для полной работы с CSS нужно будет написать еще разов в 6 больше кода.
    Готовы первые наброски самого браузера без страниц. Закладки, навигация, строка пути.
    Кстати, вы можете посмотреть эмулятор экрана компьютера из OC, который можно открыть в браузере и даже посмотреть исходный код.     Ядро написано примерно на 15% пока что. В следующий раз буду отрисовывать элементы страниц, подгружая их стили.
    • 18 комментариев
    • 3 010 просмотров
  • SDV

    Основы защиты построек от робогрифа

    Автор: SDV

    Данная статья написана в целях защиты от робогриферства, а также рассказаны основы строительства безопасного жилища.
    Под спойлером находится скриншот на котором изображено типичное примитивное строение, в простонародье называемое "коробка".

    На изображении указаны самые основные уязвимые места, которые используют гриферы для осуществления робогрифа.
    Обо всех этих местах и способах защиты я расскажу ниже.       Ветрогенератор
    Наверное самый ненадежный и уязвимый механизм (после солн.панели), которого можно лишиться в один счет.
    Уязвимость связана с тем, что данный блок невозможно никак скрыть от робота.
    При попытке обложить его любыми блоками, ветрогенератор автоматически отказывается работать с ошибкой "Нет места для ротора".
    То есть даже если вы полностью его закроете блоками он работать не будет, для него самое главное это лицевая часть где ротор, а она как известно самое открытое и уязвимое место.
    Робот без труда может подлететь к нему и ключом из IC2 спокойно снять. При желании гриферы также снимают с проводов и кинетические генераторы к ним.
    Способы защиты от грифа: к сожалению нет ничего. как вариант использовать альтернативу в виде солн.панели. Под это же правило входит и гидрогенератор и другие механизмы, которые можно снять ключом из IC2.       Солнечная панель
    Более защищенный генератор энергии, чем ветрогенератор. Но при условии того, что солн.панель должна быть прикрыта сверху (и с других сторон тоже каким-нибудь блоком) стеклом.
    Напомню механику ванильного майнкрафта: стекло является прозрачным блоком, а следовательно при установке его поверх солн.панели он пропускает через себя весь свет, как если бы солн.панель просто стояла неприкрытой к небу.
    А следовательно солн.панель будет получать полный уровень освещенности, не теряя ни 1 единицы с блоком стекла наверху.
    А для робота уже будет проблематично снять такую солн.панель, т.к. для него является препятствием блок стекла и политикой плагина привата робот, как и человек не может сломать в чужом привате никакие блоки.
    Способы защиты от грифа: установка поверх панели блока стекла (любого цвета можно даже), а также солн.панель не должна иметь с сбоков (или снизу) пустого пространства (пустых блоков), в который может переместиться робот и спокойно снять панель.       Дырки в оконных проемах
    Самая распространенная ошибка при строительстве у игроков. т.к. если даже оставить в стене даже одну дырку (1 блок), то робот может беспрепятственно в нее уместиться и посетить ваше жилище.
    А это чревато тем, что робот может "обчистить" ваши сундуки, а также открыть дверь и впустить внутрь грифера, чтобы ему было удобнее управлять роботом.
    Способы защиты от грифа: ВСЕГДА закрывать дырки и проходы, если нет на данный момент нужного материала (стекла,прутья и т.п.), то нужно хотя бы эти дырки залатать обычными плитами (деревянными, из булыжника, камня и т.п.).
    Тем самым дырка будет уже не равна 1 блоку, а 0,5, а это уже мало для прохода роботу.       Ванильные двери
    Как я уже сказал ранее, если в постройке есть дырки, то робот может спокойно заехать в жилище и открыть дверь.
    НО, если будет установлена дверь не из ванильного майнкрафта (не деревянная ID 324 и не железная ID 330), а например дверь из мода OpenSecurity.
    То обычным сигналом редстоуна ее не открыть (необходим контроллер двери), а как известно роботы не могут взаимодействовать с внешними компонентами, поэтому "подключиться" к контроллеру двери он не сможет никаким образом.
    Но если у вас нет пока ресурсов на такую дверь и контроллер, то не переживайте, просто робот не сможет проехать в проем двери, даже если стоит 2 двери. Т.к. двери (предмет) даже открытыми являются 1 блоком, то в этот блок робот не может пройти.
    Способы защиты от грифа: желательно не ставить ванильные двери (дверь из IC2 тоже открывается на редстоун сигнал), по возможности использовать дверь из мода OpenSecurity.
    Но даже если и стоит обычная дверь, то ничего страшного не будет. Игрок конечно сможет пройти в нее, но это лишь дает ему больший обзор пространства и ничего больше (сам снять что-то или "пошариться" по сундукам он не сможет).       Прочие открытые проемы и спуски
    Тоже одна из главных ошибок игроков, когда они делают возле своего дома различные спуски в шахту и т.п.
    А если этот спуск каким-то образом взаимосвязан с входом в дом (например из подвала в дом), то возможен вход через них робота.
    Способы защиты от грифа: не делать различные спуски и проходы возле своего дома, а если и делаете, то не соединяйте их с проходами, подъемами в дом.       Сундуки на территории привата
    Очередная больная тема по поводу сундуков. Многие игроки (в основном начинающие) оставляют сундуки прямо на территории привата, при этом они находятся в открытом доступе для робота.
    В результате чего сундуки могут быть опустошены, а отследить кто это сделал невозможно.
    Способы защиты от грифа: не оставляйте сундуки на открытом пространстве, по возможности располагайте их в недоступном для робота месте.
    Самые ценные ресурсы (алмазы, изумруды, иридий и т.п.) храните не в обычных сундуках, а в эндер-сундуках.
    В отличии от обычных сундуков, роботы не смогут вытащить предметы из эндер-сундука.
    Причина тому, что эндер-сундуки индивидуальны для всех, то есть если для вас эндер-сундук виден вам с вашим содержимым и вашим ником, то для робота эндер-сундук уже свой, со своим именем (робота) и своим инвентарем.
    В общем думаю Вы поняли про что я имею ввиду. Просто запомните, что эндер-сундуки недоступны для роботов.  
    UPD от 19 марта: @Fingercomp подсказал мне, что в якорный сундук из мода Ganys Mod робот также может проникнуть и извлечь все вещи.
    Стоит об этом тоже позаботиться и не ставить в самое видное и удобное место для робота.   Вот на этом я закончу статью.
    Думаю я расписал самые возможные уязвимости и места в постройках игроков.
    Не совершайте подобных ошибок, стройтесь правильно с умом и не будьте жертвами робогрифа.   Если я что-то пропустил или у Вас есть еще варианты того, что может быть объектом для грифа - оставляйте в комментариях эти предложения.
    • 1 комментарий
    • 269 просмотров
  • Zer0Galaxy

    Создаем собственный сайт в сети OpenNet (часть 0x00)

    Автор: Zer0Galaxy

    И так, Вы попали в белый список, построили дом, добыли ресурсов, собрали свой первый компьютер, написали первую программу. Настало время поведать о своих успехах миру. Лучший способ сделать это - создать OpenNet-сайт с изложением всех своих достижений. Для этого Вам понадобится WEB-сервер. Это может быть обычный ОС компьютер. Желательно обеспечить его бесперебойным питанием и разместить в постоянно прогруженном чанке. В противном случае Ваш сервер может оказаться временно недоступным. Вопрос питания и прогрузки чанка я оставляю на усмотрение владельца и расскажу о требованиях к аппаратному и программному обеспечению сервера. Сервер должен содержать беспроводную сетевую плату, а это значит, что системный блок сервера должен быть не ниже 2-го уровня. Требования к остальным компонентам самые минимальные. Если же Вы собираетесь использовать этот компьютер не только как сервер, но и создавать и просматривать на нем же свои страницы, комплектация должна быть получше. Вот, что бы я рекомендовал: - Системный блок - 3-го уровня; - Процессор 2-го уровня; - Видеокарта 2-го уровня; - беспроводная сетевая карта; - две линейки ОЗУ 2-го уровня; - жесткий диск 2-го уровня; - Lua BIOS; - монитор 2-го уровня; - клавиатура.   Установку программного обеспечения начинаем с операционной системы. Надеюсь, Вы знаете как это делается. После установки OpenOS пытаемся подключиться к сети OpenNet. Для этого заходим в интерпретатор Lua, копируем в буфер обмена следующую строку: on=component.modem;e=event;on.open(1)on.broadcast(1,"","","getip")function m()r={e.pull(10,"modem_message")}end;m()ud="update"ip=r[6]function sv()on.send(r[3],1,ud,ip,ud,"getFile","client/"..p)m()filesystem.makeDirectory(filesystem.path(p))f=io.open(p,"w")f:write(r[8])f:close()end p="lib/opennet.lua"sv()p="on/update.lua"sv()loadfile(p)("install") вставляем ее в редактор Lua кнопочкой Ins и запускаем на выполнение. В результате выполнения из Сети будут скачаны все необходимые для подключения файлы и разложены по нужным папкам. Если же чудо не произошло, скорее всего Вы находитесь вне зоны покрытия OpenNet. Обратитесь ко мне и я постараюсь помочь. Если установка прошла успешно, перегружаем компьютер и создаем папку /web mkdir webcd web В этой папке будут храниться страницы нашего будущего сайта. Почему отдельная папка а не корень? Да потому, что к ней будет осуществляться удаленный доступ, причем и на чтение и возможно на запись. И если бы это был корень диска, то каждый хакер при желании смог бы почистить на нашем сервере весь диск. Имена файлов, содержащих страницы сайта могут быть любыми, но непременно должны присутствовать два файла: "index" и "404". Файл index должен содержать главную страницу сайта, а 404 - текст, который будет возвращаться при попытке открыть несуществующую страницу. Создадим файл index, содержащий текст: Главная страница моего сайта И файл 404 с текстом: Извините, запрашиваемая страница не найдена. Для начала попытаемся открыть файл index браузером прямо с сервера: onBrowser /web/index Вот что мы должны увидеть: Поскольку мы указали путь к файлу, начинающийся с косой черты, файл будет открываться браузером не по сети, а с локального компьютера. (продолжение следует)
    • 2 комментария
    • 2 007 просмотров
  • NEO

    Реализация идеи от товарища Zer0Galaxy, а именно телепортация между компьютерами.

    Автор: NEO

    Вчера уважаемый форумчанин Zer0Galaxy предложил идею как можно телепортировать между компьютерами, без необходимости находится конечному телепортеру в одной сети(Как компоненты), можете смотреть видео ниже.
    https://www.youtube.com/watch?v=e530frIKUGc
    • 13 комментариев
    • 1 819 просмотров
  • Totoro

    Запускаем дронов!

    Автор: Totoro

    Дроны - как керосин. Они есть везде. Еще года два назад это было просто еще одно интересное видео на Ютубе. Год назад они вдруг оказались в интернет магазинах. Затем просочились в рекламу на ТВ, и вот теперь - они есть и в OpenComputers! Пришла пора с ними разобраться.   1. Матчасть Дрон, в данном случае - квадрокоптер, это беспилотный летающий аппарат, приводимый в движение двумя парами горизонтальных винтов. Приостановливая вращение винтов с одного боку, дрон двигается в сторону (стрейф). Эти винты вращаются в разном направлении (два - по часовой срелке и два - против), за счет чего дрон не нуждается в стабилизирующем хвостовом пропеллере (как вертолет). За счет этого же он и разворачивается в воздухе, замедлив вращение однонаправленной пары винтов. Дрон обладает небольшой массой, для экономии энергии, которой у него не много (на 10-30 минут полета в среднем). (с) Википедия   2. Дроны и OpenComputers Приблизительное изображение дрона в OpenComputers =): В мире Майнкрафта дрон представляет из себя "сущность" (Entity). Это значит, что он обладает возможностями мобов Майнкрафта. (В то время как робот - это блок.) Его можно сдвинуть с места толкая. Он умеет пролетать сквозь двери и калитки (в отличии от робота). Он движется не последовательно, из блока в блок, а из точки в точку. Причем маршрут может лежать по диагонали.   Конечно, движется он по кратчайшей линии, и если на пути окажется стена - дрон столкнется с нею.   Программирование дрона как две капли воды похоже на программирование микроконтроллера. Вы точно так же записываете программу на EEPROM, и при необходимости меняете ее на верстаке. Только в отличии от контроллера, вам становится доступен новый компонент: drone.   Подробнее об командах дрона можно узнать здесь: OpenComputers/Дрон. (Или здесь: ocdoc.wiki (англ.))   3. План Нужна какая-нибудь несложная задача, для целей эксперимента. Используем программку send из предыдущего поста, для удаленного управления. Зальем ее на планшет. А дрон пусть... носит свиней. Будем оригинальными и непоследовательными.     1. Команда 'add X Y Z Name From'. Добавляем точку Name к маршруту, цепляя ее к точке From. Зададим дрону последовательность точек, которые образуют граф - безопасные маршруты. 2. Команда 'catch' - дрон ловит свинью. 3. Команда 'drop' - дрон выпускает свинью. 4. Команда 'to X' - дрон летит в точку Х.   Для начала не будем особо заморачиваться с графом маршрутов. Это будет простое неориентированное дерево. Примерно такое:   4. Строим полигон Построим что-нибудь подходящее для тестов. Отметим ключевые точки будущего графа красными блоками. А синий блок - будет стартовой площадкой дрона.           Поскольку я играю без модов на энергию, мой планшет и дрон будут работать вечно. И я не заморачиваюсь станцией подзарядки.   Иначе, к схеме выше было бы необходимо добавить станцию, где дрон мог бы зарядить аккумулятор.     5. Пишем программу Скрипт для удаленного управления скопипастим из прошлого поста, подправим, чтобы умела отправлять несколько переменных и зальем на планшетик, для удобства. (Для этого, соберите планшет - не забудьте клавиатуру и видеокарту! - положите его в зарядник и запустите с подключенного компа команду install. Укажите адрес винчестера планшета - и все, что было у вас на компе автоматически загрузится в планшет, включая даже ваши собственные программы.) local com = require('component')local modem = com.modemlocal args = {...}modem.broadcast(27, table.unpack(args))io.write("Message: ")print(table.unpack(args)) Далее - более сложная часть. Программа дрона. Программа предназначена для EEPROM. Значит соблюдаем те же правила: используем computer, component и API имеющихся у дрона компонентов. Включая его родной компонент drone. В нашем случае, дрон вооружен апргейдом-лассо (leash) и беспроводной сетевой картой (modem) для связи.   Стоит отметить, что процесс отладки программы (по крайней мере в текущем билде мода) достаточно неудобен. В случае ошибки дрон отказывается включиться, издав тонкий писк, и не выводя никакой информации. Получить отчет об ошибке при помощи анализатора не выйдет - ведь Shift+ПКМ просто снимает дрона. Автор обещал в скором времени это исправить. Ну а пока - помучаемся.   Отредактировать чип в стороннем редакторе, не вынимая его из дрона тоже не выйдет. В отличии от файловых систем, которые имеют удобную папку вида /saves/World/opencomputers/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/, чипы EEPROM хранят свой код в NBT тегах предмета. Этим же обусловлено и ограничение размера кода в 4 килобайта.   5.1. Основная часть Это цикл который ждет указаний, а затем запускает соответствующую функцию. drone = component.proxy(component.list("drone")())modem = component.proxy(component.list("modem")())leash = component.proxy(component.list("leash")())modem.open(27)route = {}path = {}current = ""while true do name, _, sender, _, _, message, x, y, z, point, from = computer.pullSignal(1) if name == "modem_message" then if message == 'add' then add(tonumber(x), tonumber(y), tonumber(z), point, from) if current == "" then current = point end elseif message == 'to' then to(x) elseif message == 'catch' then catch() elseif message == 'drop' then drop() end end if #path > 0 and drone.getOffset() < 1 then drone.move(route[path[#path]].x-route[current].x, route[path[#path]].y-route[current].y, route[path[#path]].z-route[current].z) current = path[#path] path[#path] = nil endendmodem.close() Чтобы облегчить себе жизнь (и тестирование bios), вы можете сделать так: напишите заглушку для компонента drone (и других, если надо), вроде этой: http://pastebin.com/EVYzN5Bj Просто скопируйте в папку на компьютере, где вы пишете программу для дрона. Затем измените первые строки программы следующим образом: component = require('component')computer = require('computer')drone = require('drone')modem = component.modem-- leash = component.proxy(component.list("leash")()) Затем добавьте в цикл условие выхода по нажатию кнопки: if name == 'key_down' then break end И вы можете просто запустить вашу программу для дрона на компьютере. Разумеется полноценной эмуляцией дрона тут и не пахнет, зато очень удобно отслеживать глупые синтаксические и логические ошибки.     Как устроен код основного цикла? Переменная route - хранит таблицу "вейпоинтов" (waypoints). Это вершины графа и информация о связях между ними. Переменная path - хранит путь от текущей вершины до цели. Переменная current - отмечает текущее местоположение дрона в графе.   В цикле мы читаем получаемые сообщения и вызываем соответствующие функции. Первая переданная вершина считается дроном текущей.   Во второй части цикла происходит проверка. Если путь до цели - не пуст (это значит, что дрону надо куда-то лететь) и дрон уже долетел до текущей вершины (getOffset()), то программа берет следующую вершину из path, отправляет дрона к ней и объявляет ее текущей.   5.2. Функции-команды Теперь последовательно добавим функции для каждой команды. function add(x, y, z, name, from) route[name] = {x=x, y=y, z=z, link = {}} if from ~= nil then if route[name] == nil or route[from] == nil then drone.setStatusText("Error!") else table.insert(route[name].link, from) table.insert(route[from].link, name) end endend Тут все просто. Пишем вершину в список. Если он связана с другой вершиной (from ~= nil), то в специальную табличку link заносим две связи: из name в from, и из from в name. function search(target, point, prev) for key, name in pairs(route[point].link) do if name == target then table.insert(path, point) return true end end for key, name in pairs(route[point].link) do if name ~= prev then if search(target, name, point) then table.insert(path, point) return true end end end return falseendfunction to(name) path = {} table.insert(path, name) search(name, current)end Функция to обнуляет старый путь (на всякий случай), затем вставляет в него цель пути (name) и запускает функцию search, которая рекурсивно ищет и записывает остальные промежуточные вершины на маршруте от name до current (текущей локации). Функция search сделана достаточно примитивно (возможно вы предложите более эффективный способ?). Поскольку мы договорились, в целях упрощения использовать граф-дерево (не содержаший петель), от любой точки к другой существует один и только один маршрут, который функция и находит перебором связанных вершин. function catch() for c = 2, 5 do if leash.leash(c) then return true end end return falseendfunction drop() leash.unleash()end Тут все элементарно.   6. Подготовка Пишем программу на дрона, заряжаем планшет и выдвигаемся в зону действий. Дрона ставим на синий куб (стартовая площадка) и включаем.     После уточнения на местности, составляем карту вейпоинтов и строим на бумажке будущий граф:   Для каждого загона добавлены две точки - name и name_up. Основные "трассы" дрона лежат на высоте в 6 блоков. А в каждом загоне спускаются к земле. (Чтобы заарканить животное, выстреливая лассо вбок, дрону желательно находиться на одном уровне с жертвой).   С планшета вносим координаты в память дрона. Примерно так:     Главное - не ошибиться. Т.к. в код не была добавлена защита "от дурака" =) Алгоритм позволяет добавлять вершину "на лету". В любой момент вы можете добавить еще одну ветку к схеме.   Теперь все готово к тесту.   7. Запуск Все готово. Проверим, как он двигается. Введем send to sheeps в консоль планшета. Дрон уверенно поднимается в воздух и опускается в загоне в овцами.   Теперь введем send to pigs. Функция search снова вычислит путь и робот переместится в указанную вершину:     Функции catch и drop тоже работают штатно =)     Хотя и не лишены некоторых глюков (ведь физика веревки не просчитывается):     8. Итоги а) Дрон - любопытная штуковина. б) Полный код прошивки. использованный в этом посте - здесь: http://pastebin.com/Cy1UR6vy в) Навигация по вейпоинтам - интересный и очень распространенный способ организации сложного движения. Схему можно усложнить - опционально добавлять только одну связь в таблицу link - тогда получатся ребра с односторонним движением. Добавить петли, оптимизировать поиск кратчайшего пути. Еще можно облегчить правление дроном - хранить все команды для конкретной задачи в виде файла-скрипта, который запускать одной командой и т.д.   Enjoy!
    • 19 комментариев
    • 13 424 просмотра

Блоги сайта

  1. Fingercomp
    Последняя запись

    Он вышел раньше, чем я предполагал — ниже список нового.

    • Сила овец и оцелотов в их пушистости. Теперь пушистость можно приложить к делу и питать компы — с помощью ковровых конденсаторов. От обычных конденсаторов они толком не отличаются, но могут генерировать энергию, если по ним ходят минимум 2 пушистых животных: овцы или оцелоты, которые генерируют больше энергии.
    • Все новые процессоры, которые будут скрафчены, будут с Lua 5.3 по умолчанию. Сменить можно так же — шифт-пкм.
    • К беспроводной карточке, которую мы все знали, теперь добавили урезанную версию T1, тоже беспроводную. Она может открывать только 1 порт и стрелять сигналом на 16 блоков, а не 400.
    • Креативная компонентная шина (штука, пихабельная в серверы), которая добавляет 1024 компонента. Логичное дополнение.
    • Роботов можно подключать к компьютерам как компоненты. И менять имя роботов: то, что раньше делалось в наковальне, теперь можно через setName и getName. Робот должен быть выключен, чтобы функции работали.
    • Починены всякие проблемки с рендерингом всяких символов.
    • Блоки-инвентари иногда не сохраняли содержимое при сохранении мира.
    • Дроны с чанклодырями не всегда грузили чанки.
    • Пофикшена интеграция с AE2.
    • computer.addUser неправильно отдавал ошибку как-то.
    • Хитбоксы у кабелей теперь обтягивают их форму. Раньше кабели-пересечения были с хитбоксом на весь блок.
    • Апгрейд крафта не всегда крафтил, когда должен был.
    • Апгрейд крафта крафтил один предмет и ломал рецепт — для всех, в том числе игроков. Весело.
    • Датчик движения как-то коряво работал.
    • Пофикшена работа роботов с предметами-инвентарями вроде жидкостных ячеек IC2.
    • Устранена возможная утечка памяти в сетевом коде.
    • В MC 1.10+: пофикшена getMetadata у дебаг-карты.
    • В MC 1.10+: добавлена getBlockstate для дебаг-карты.
    • В MC 1.12: нельзя было заменить EEPROM дрону.
    • В MC 1.7.10: добавлены getAllStacks и inventoryName для транспозеров с инвентарных апгрейдов.
    • Обновлён французский перевод.
    • В OpenOS:
      • Обновлён install.lua, чтобы работал более предсказуемо.
      • uuid.lua возвращает правильные UUID 4 версии, как в RFC написано.
      • Фиксы всякие поддержки vt100.
      • Утечка памяти при загрузке процессов (есть и такая, даже в Луа).
      • Более конкретные комбинации клавиш: Ctrl+Alt+Delete не будет считаться за Ctrl+Delete, например.



    Вайтлиста измерений для чанклоадера... ну, их пока нет.

     

    Скачать.

  2. usgiMAd.png

     

    Иногда случается такое, что ваши компьютеры расположены на расстоянии большем,
    чем стандартные 400 блоков. Wi-Fi отказал, а вам надо связать компьютеры по сети.

     

    Какие тут есть варианты?

     

    1) Повысить лимит в конфиге.
    Это просто, но не всегда возможно.

     

    2) Использовать linked карту.
    С её помощью можно пробить любое расстояние, да.
    Но тут есть несколько своих проблем. Она связывает компьютеры только попарно.
    Для связи нескольких компьютеров надо уже делать сложную систему проброса сообщений.
    Она занимает дополнительный слот. И т.п.

     

    3) Использовать цепочку Wi-Fi карт
    Казалось бы, чем это проще второго варианта?
    А проще оно тем, что тут есть уже готовые библиотеки. =)

     

    Интермедия

     

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

     

    К сожалению, исходники и гайды до сих пор разбросаны по частям по всему форуму.
    Чтобы собрать это снова вместе, потребуется немало усилий.
    Да и зачем нам поднимать полноценный "интернет", если всё, чего мы хотим - это
    пробросить парочку сообщений туда-сюда?

     

    Поэтому в более новые и не такие добрые времена (птички потише, трава потускнее),
    некто Totoro и fingercomp придумали систему попроще и погибче.
    И назвали её Zn.

     

    Приступаем к решению

     

    Итак, как нам связать Васю и Олю, которые живут на противоположных краях Земного Блина?

     

    1) Через микроконтроллёр
    Самое дешёвое в плане ресурсов решение - собрать микроконтроллёр, прошить его
    и закопать где-нибудь в лесу на полпути между Васей и Олей.

     

    Сначала нам потребуется код прошивки. Он идёт в комплекте с Zn библиотекой.
    Как цивилизованные современные люди, мы скачаем её с Hel-репозитория:

    hpm install zn


    Теперь в папке /usr/share/zn/ у нас есть файлик eeprom.lua. Который мы и прошиваем
    на чистый EEPROM:

    flash -q /usr/share/zn/eeprom.lua "Zn node"


    Всё. Осталось вставить чип в контроллер, включить его и закопать.
    Сеть создана!

     


    2) Через компьютер
    Более солидное и основательное решение. Строим в лесу будку. В будке ставим
    компьютер. На компьютер устанавливаем OpenOS и HPM (если он не идёт в комплекте).
    Снова качаем библиотеку:

    hpm install zn


    Создаём мини скрипт:

    edit node.lua


    Пишем в нём такой код:

    (require ('zn')).connect()


    Сохраняем, выходим, запускаем его:

    node


    Всё! Скрипт выполнится и завершится, а в фоновом режиме останется работать
    демон Zn-сети, который будет пробрасывать сообщения.
    По желанию можно сделать скрипт более сложным - например выводить на экран
    сетевой трафик и другую полезную инфу.
    Также можно добавить скрипт в автозапуск компьютера, чтобы даже неожиданные
    сбои питания (белка залезла в трансформатор) не смогли повалить сеть.

     


    Эти два варианта обладают некоторыми недостатком, конечно.
    Чтобы ретранслятор работал автономно, надо ставить чанклодер и источник энергии.
    Однако, в силу своей гибкости, Zn сеть можно организовать и по другому.
    Поднять, так сказать, "лайт версию" ретранслятора.

     

    3) Через планшет
    Устанавливаем на планшет OpenOS и ставим библиотеку и скрипт по методике #2.
    Далее, вручаем планшет соседу Пете и забиваем ему стрелку в том самом лесу.
    На протяжении X минут (где X зависит от терпения Пети) у вас будет полноценная сеть!
    Игрок будет служить чанклодером, а батарея планшета источником питания.

     

    4) Через робота
    Строим робота, устанавливаем скрипт по методике #2. Затем ставим робота где-нибудь
    в незаметном месте (можно спрятать в кроне дерева, так чтобы свет солнца падал
    на солнечную батарею). Всё, мобильный ретранслятор готов.
    Если чанклодеры к роботам разрешены, он может существовать автономно долгое время,
    питаясь солнечной энергией.

     

    5) Через дрон
    Прошиваете EEPROM как для микроконтроллёра, заряжаете в дрона. Дрона запускаете
    в свободный полёт над лесом. Готово! Хотя чанклодер всё равно нужен. Так что вам
    наверное придётся пастись где-то рядом.
    Этот вариант самый сложный, потому что если вы хотите управлять дроном (например,
    с планшета) то вам потребуется модифицировать прошивку и добавить блок управления.
    Зато запустив 1000 дронов, вы можете почувствовать себя Илоном Маском,
    или Цукербергом, раздающим Интернет папуасам.

     

    А как теперь этой сетью пользоваться?

     

    Все просто. Это делается почти как с обычным модемом.
    Только вместо модема вы используете библиотеку Zn.

     

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

    -- подключаем библиотекуlocal zn = require('zn')-- коннектимся к сетиzn.connect()-- посылаем Оле сообщениеzn.send("адрес модема Оли", "сообщение для Оли")-- при завершении программы не забываем закрыть коннект-- (можно и не закрывать, но зачем тратить ресурсы компа зазря)zn.disconnect()


    Ну а если адресат неизвестен, можно кинуть сообщение бродкастом. Тогда его получат все,
    кто подключен к сети. И адресат, конечно тоже.

    local zn = require('zn')zn.connect()-- посылаем сообщение всем, кто подключён к сети (Оле в том числе)zn.broadcast("сообщение для Оли")zn.disconnect()


    Удачи в построении своих сетей.
    Enjoy Zn!

  3. Дача Игоря

    • 1
      запись
    • 17
      комментариев
    • 39
      просмотров

    Последние записи

    ECS
    Последняя запись

    Еще мой дед говаривал, что каждый кодер на ОС просто обязан начать писать собственный эмуль для самоутверждения. Не желая изменять семейным ценностям, я тоже окунулся с головой в эту клоаку. Вообще в существующих эмуляторах лично меня люто бесит возня с ручной компиляцией, докачиванием всяческих либ по типу openssl, а также отсутствие возможности запуска нескольких виртуальных компиков в едином пространстве с масштабированием экранов, не говоря уже про пересылку данных между ними посредством не менее виртуальных модемов. Поэтому почесав репу, собрав JavaFX + LuaJ, накатав несколько компонентов, на данный момент я заимел следующие зачатки проекта:

     

    • Библиотеки computer, component, unicode
    • Компоненты computer, eeprom, filesystem, gpu, modem, screen, keyboard
    • Имитация системных сигналов по типу touch/drag/drop/key_down/key_up/scroll/modem_message с поддержкой pullSignal/pushSignal
    • Пересылка сетевых пакетов между имеющимися машинами в рабочем пространстве через modem.send/broadcast
    • BSOD для "unrecoverable error"
    • Звуковая система а-ля "комп в мире кубача", имитирующая звуки доступа к диску, и прикольно шумящая на фоне для антуража
    • Создание/сохранение/загрузка виртуальных машин с сериализацией данных имеющихся компонентов. Ну, всяких там адресов, разрешений видях, размеров, координат и т.п.
    • Кнопочка включения (!)

     

    Разумеется, компоненты имеют далеко не все методы, их написание - дело долгосрочное. Но поскольку этот раздел называется блогом, то, кажется, никто не мешает мне писать о запланированном. В идеале хочу замутить компоненты internet, tunnel и data, позволить юзерам выбирать пути к прошивке виртуального EEPROM и содержимому жесткого диска. Также остается открытым вопрос о лимитировании памяти: я понятия не имею, как это реализовать на LuaJ и ублюдочной Яве без обожаемого sizeof(). Городить костыли в виде JavaAgent + Instrumentation.getObjectSize не хочется, но, видимо, придется. Ну, и если у кого-то имеются занятные предложения по функционалу софтины - буду рад.

     

    Сырцы:

    https://github.com/IgorTimofeev/OpenComputersVM

     

    Скриншотик:

     

    7dsXjvM.png

     

     

  4. PieLand

    • 1
      запись
    • 6
      комментариев
    • 1912
      просмотров

    Последние записи

    mrlobaker
    Последняя запись

    Читал я в очередной раз форум, и нашёл тему "Цитадель". Я давно хотел посмотреть, что да как в ОС, поэтому я создал новый мир на своей сборке (в конце кину), подстроил правила под себя, построил бункер... И ушёл писать копалку.
    F9S2dg2.png
    FCKzSfx.png
    0J0cug2.png
    По правилам:

    • Даны компоненты, а не целые компы/дроны/роботы;
    • Внутри бункера можно делать что угодно (даже расширять, но только вниз);
    • Под компом - креативная батарейка из thermal expansion;
    • Энергию от креативной батарейки нельзя никуда подводить!
    • Рядом с единственным зарядником - waypoint для нахождения пути к базе.
    • Цель - сделать систем автоматического создания роботов для добычи большинства ресурсов.


    Я не знаю, на сколько меня хватит, но я надеюсь на хотя-бы 7 записей.
    Следующая запись будет, когда я допишу копалку, а пока всё!

  5. Очумелые ручки

    • 1
      запись
    • 3
      комментария
    • 3591
      просмотр

    Последние записи

    1Ridav
    Последняя запись

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

     

    В этой части будет немного круче. Было две флешки по 8ГБ на интерфейсе USB 2.0, оба корпуса сломались ввиду того, что были из некачественного пластика даже сами коннекторы. Выкинуть жаба душила, вспомнил, как поделка из первой части хорошо так удивляла тех, кому её давал. Решил сделать нечто похожее.

     

    Для корпуса использован патрон стартера люминесцентных ламп. Обе флешки без корпусов подпаяны параллельно за исключением питания, которое переключается через кнопку.

     

    https://puu.sh/zd11V/a5888e4f1d.jpg
    http://puu.sh/zd0Wf/3de60405ea.jpg

     

    Теперь остаётся собирать лулзы и наслаждаться ступором окружающих :smile3:

  6. NullException - DevBlog

    ARPSS - Automated Resource Production and Supply System (Автоматизированная Система Добычи и Поставки Ресурсов)
    (Да, я люблю навороченные аббревиатуры)

     

    *Automated Resource Production and Supply System, спасибо Fingercomp за поправку.

     

    Внимание, оч много текста

     

    Начну с напоминания о том, что в данном посте будет описание прототипа. И в дальнейшем могут быть изменения в плане. Здесь могут быть недосказанны такие подробности, как размещение мониторов с нужной информацией и подобное, но ничего страшного, поскольку я собираюсь позже опубликовать что-то наподобие видео-инфографики и pdf-файл.

     

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

     

    Весь процесс эксплуатации системы пользователем происходит в 4 этапа:

    1. Разработка проекта
    2. Транспортировка
    3. Отслеживание автоматизированной постройки
    4. Мониторинг добычи и транспортировки руд.

     


    Первый пункт начинается с компьютера, в котором, естественно, установлен софт. В нем мы разрабатываем проект из нескольких компонентов:

    1. Проектирование дизайна тоннелей и комнат - высота, ширина, материал.
    2. Проектирование поезда-строителя - состав из нужных вагонеток и импортирования дополнительных, по возможности, предметов. Программа не допустит состава без вагонетки, так как это поезд-строитель.
    3. Проектирование схемы подземных путей сообщения.
    4. Проектирование схемы движения на основе спроектированной схемы из предыдущего пункта.
    5. Проектирование схемы раскопок и фильтрации ресурсов для экспорта и транспортировки.


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

     


    Второй пункт - транспортировка, здесь есть большие трудности с банальным придумыванием самого способа для автоматизации. Игрок может просто созданный состав переместить самостоятельно, с помощью поезда, но кто хочет тратить на это время и дополнительные ресурсы?
    С одной стороны, если сделать обязательно вагонетки из RailCraft, то уже возникает потребность в моде, хотя там и так потребностей дофига....ну допустим у всех стоит реил. Но если использовать вагонетку для прокладывания рельс, то возникает следующая проблема - это препятствия в виде обрыва, водной местности или встречного блока. Телепортация? Ваще без понятия как, это если прикинуть сразу. Можно использовать Дронов, но появляются дополнительные проблемы в виде вместимости. Возможно вообще стоит исключить сборку поезда из этого проекта, а просто сделать отдельно. Направить в нужное место рельсы? Ну хоть какой-то способ. С одной стороны ты берешь, проектируешь и отправляешь по нужным рельсам поезд, а с другой, все равно тратишь какое-то время на прокладывание путей. Или взять стаю дронов, которая в нужном месте будут раскладывать строителей. Если бы, например уже существовал проект менеджера по рельсам, то можно было все спокойно связать и автоматизировать, но только при автоматических переключателей стрелок. Все вышеизложенное делает упор на то, что передвигающиеся объект не имеет знаний о местности. То есть нету предварительной карты, по которой система может симулировать свои планы действий перед тем, как это притворить в действие, точнее, просто взять данные и начать перемещение, симуляция - излишнее. Поэтому, надо изменить основной план действий самой системы, что и будет сделано дальше. Итак, представим, что этот пункт мы преодолели и поезд приехал/пришел/прилетел/упал/телепортнулся в это место.

     

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

     

    Четвертый пункт - добыча и доставка.
    Уууу, ещё надо проводить раскопки по указанной схеме, транспортировки, сортировки руд, отсылки данных на главный сервер для дальнейшей обработки, а ещё это может быть на огромном расстоянии и в другом мире....ооо.... Ну с отправкой данных ещё можно справиться. Ну что ж, поезда приезжают, и ресурсы регистрируется в БД. Хмм, а если взять ThermalExpansion, то можно просто поставить тессеракт и все. Но надо стремится к независимости от других модов, ну кроме реила :D

     

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

     

    Первый вид - упрощённый:

    1. Пользователь отсканировал нужный участок и собрал проект
    2. Проект отсылается на хранение в RAID и на исполнение главным сервером.
    3. Гл. сервер даёт команду и отсылает данные, изъятые из файла проекта.
    4. Робот, опираясь на зарегистрированные координаты, начинает ставит вагонетки на рельсы, отсылая контроллеру команды на испускание редстоун сигнала в нужные участки для объединения вагонеток.
    5. а) Поезд по рельсам прибывает в нужное место и ставит роботов.
      б) Дроны вылетают из депо и летят к месту постройки, раскладывают роботов и летят обратно. (Этот сценарий требует доработки, так как надо устанавливать координаты обратного перемещения по рельсам. Или просто всю логистическую систему завязать на дронах.)
       

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

     


    Второй вид - детальный:
    Тоже самое, что и первый, только еще детальнее :unsure:

     

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

     

    Все удачного кодинга и креативных идей :lol:

  7. Laine_prikol
    Последняя запись

    Всем привет! Сегодня я вам покажу до чего дошли технологии что теперь, можно играть в ПОНГ прямо в чате Discord. Для этого нам пригодится немного времени и пару вещей:
    1. Иметь свой сервер в Discord или права управления сервером на каком-нибудь сервере
    2. Пригласить бота на свой сервер!
    Как его добавить:

     

    1. Итак, ищем бота на этом сайте P.S бот называется Koneko. Потом нажимаем на кнопку:
    blogentry-18530-0-73025200-1493661466_thumb.png
    2. Откроется окно, нажимаем на кнопку:
    blogentry-18530-0-28422100-1493661676_thumb.png
    3. И после этого на вашем сервере появится бот. (Префикс: ')
    Сам понг:
    Пишем команду в чат: 'pong, и появится выбор сложности (зависит от частоты обновления поля)
    blogentry-18530-0-71360900-1493662104_thumb.png
    ИГРАЕМ! Жмём на кнопочки снизу и управляем своей ракеткой
    S86Hmw5.gif

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

     

    Для начала открывает чат в одной вкладке браузера. И тут мы можем делать всё (в рамках правил форума), писать сообщения в чат, нажимать на кнопку "обновить" чуть ниже чата и прочее. Но есть одно условие. Не переходить на другие страницы, сайты и не нажимать кнопку "обновить страницу" у браузера.
    Страница при этом работает так. Приходит новое сообщение чата - оно записывается в лог всех пришедших сообщений. И мы их видим. Проверки на наличие новых сообщений производятся примерно раз в минуту (но это не точно). Но есть кнопка обновить, которая проверит наличие новых сообщений сразу после её нажатия.
    У вас может возникнуть вопрос, почему сообщения удалённые админами и модераторами не исчезнут? А тут всё просто. В ваш лог сообщений который хранится и обновляется новыми сообщениями никто не может повлиять и удалить сообщение. (на момент написания этой статьи) А чтобы сообщения удалились, нужно обновить страницу. Или прийти на страницу с перепиской после удаления сообщения. Тогда страница при загрузке, на запрос всей переписки вышлет все сообщения которые есть на данный момент. И удалённых конечно же не будет.

     

    Отсюда вытекает следующее правило. Одна страница/вкладка браузера должна не обновляться - для мониторинга сообщений. А вторая вкладка обновляться. И тогда мы сможет отслеживать, какие сообщения были удалены, по отсутствию их во второй вкладке.

     

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

     

    Хотя никто не застрахован от произвола и сообщения могут удаляться по собственному желанию модераторов, без оснований на правила. В таком случае, можете попробовать написать жалобу на модератора в этом разделе.
    И если вам дали неправомерный бан/мут, можете так же его оспорить в этом разделе.
    Так же, перед созданием темы в разделах указанных выше, не забудьте прочитать тему с правилами подачи жалобы.
    И пусть вас не смущает, что там нет других тем от игроков. После вынесения решения, темы закрывают и какое-то время они висят для ознакомления с итогами. А потом удаляются. По этому не бойтесь создавать там темы.
    Так же напоминаю про правила:


    1.1.9 Жалоба на модератора может быть подана не позже, чем через 7 дней с момента выдачи наказания.
    Логи и доказательства хранятся в течении определённого времени. В дальнейшем модератору сложно будет найти причину наказания.
    1.1.8 Независимо от статуса игрока - все равны перед правилами и все понесут наказание за нарушение правил.
    Привилегии (донатер ли это, гуру программист или новичок "ХеллоуВорлдщик", модератор или друг и брат администратора) не позволяют Вам нарушать Правила, снижать срок наказания.
    1.1.6 Администрация ведет логи всех действий игроков на сервере и всех сообщений чата.
    1.1.2 Администратор вправе наказать игрока по причине, не указанной в настоящих Правилах.
    Применяется, как правило, при возникновении конфликта игрока с администратором.


    И хотел бы акцентировать внимание на правиле 1.1.2. В нём речь идёт только об администрации. А модераторы чата/сервера/форума под эту категорию не попадают и на их действия подавать жалобы не запрещается (на момент написания статьи)

     

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

  9. Всем привет! Сегодня я хочу выпустить новую версию аддона OpenTechnology.
    Расскажу что же добавилось в ней.

     

    Добавлена интеграция с IC2.

     

    Практически все предметы и блоки имеют крафт.

     

    Добавлен апгрейд реактор, появляется только с модом IC2.

     

    Добавлен сканер роботов. Сканирует в радиусе вокруг игрока на наличие робота(Ибо теперь есть Тесла, нужно быть на готове). Использует энергию ОС, заряжается в заряднике для планшета и роботов.

     

    Добавлен PIB(Player Inventory Binder), он уже был но я его вырезал, позволяет удаленно взаимодействовать с инвентарём игрока, тратит энергию. Крафта не имеет.

     

    Начался процесс написания документации на гитхабе. На этом пока что всё, спасибо за внимание! :D Ссылку на скачивание можно найти слева в полезных ссылках.

    • 3
      записи
    • 30
      комментариев
    • 8342
      просмотра

    Последние записи

    Собираем первый компьютер[Гайд 1]


    Все рецепты по OpenComputers можно посмотреть здесь: http://minecraft-ru....m/OpenComputers , по IndusrialCraft2 здесь: http://minecraft-ru....dustrialCraft_2
    Первое, что мы должны сделать - генератор энергии из IndustrialCraft / ThermalExpansion / EnderIO / Build Craft / Immersive Engineering / AppliedEnergistics. В нашем случае это генератор из IndustrialCraft2 Grid_%D0%93%D0%B5%D0%BD%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80_%28IndustrialCraft_2%29.png?version=80662f98d4f575dfa1c267b41ad1d852, если не ставить не каких энергитических модов, то компьютер будет работать без энергии, но это фу-фу-фу.

     

     

     

    Второе - преобразователь энергии или конвертер
    Grid_%D0%9A%D0%BE%D0%BD%D0%B2%D0%B5%D1%80%D1%82%D0%B5%D1%80_%28OpenComputers%29.png?version=4b22de4a485aeed5122225c8ae292433
    Третье - корпус компьютера, 2-го уровня
    Grid_%D0%9A%D0%BE%D1%80%D0%BF%D1%83%D1%81_%D0%BA%D0%BE%D0%BC%D0%BF%D1%8C%D1%8E%D1%82%D0%B5%D1%80%D0%B0_%28%D0%A3%D1%80%D0%BE%D0%B2%D0%B5%D0%BD%D1%8C_2%29_%28OpenComputers%29.png?version=96999ec7d8e442f5b64ec1a8aaaa3c61
    Четвертое - монитор, лучше всего 2-го уровня, но можно 1-го
    Grid_%D0%9C%D0%BE%D0%BD%D0%B8%D1%82%D0%BE%D1%80_%28%D0%A3%D1%80%D0%BE%D0%B2%D0%B5%D0%BD%D1%8C_2%29_%28OpenComputers%29.png?version=3a325d688bf079790831144dbd6aed0e
    Пятое - клавиатура
    Grid_%D0%9A%D0%BB%D0%B0%D0%B2%D0%B8%D0%B0%D1%82%D1%83%D1%80%D0%B0_%28OpenComputers%29.png?version=0f886a8123d369dad945df62e8e51793
    Шестое - комплектующие системного блока (корпуса компьютера): процессор 1-го уровняGrid_%D0%A6%D0%9F%D0%A3_%28%D0%A3%D1%80%D0%BE%D0%B2%D0%B5%D0%BD%D1%8C_1%29_%28OpenComputers%29.png?version=d93e67ee57dbc0c408d1746250760078, видеокарта желательно 2-го уровня, но можно и 1-гоGrid_%D0%92%D0%B8%D0%B4%D0%B5%D0%BE%D0%BA%D0%B0%D1%80%D1%82%D0%B0_%28%D0%A3%D1%80%D0%BE%D0%B2%D0%B5%D0%BD%D1%8C_2%29_%28OpenComputers%29.png?version=c4c822b14a03bbdaf8234733ac879720, оперативную память лучше всего 2-го уровня, но можно и 1.5 Grid_%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%B8%D0%B2%D0%BD%D0%B0%D1%8F_%D0%BF%D0%B0%D0%BC%D1%8F%D1%82%D1%8C_%28%D0%A3%D1%80%D0%BE%D0%B2%D0%B5%D0%BD%D1%8C_2%29_%28OpenComputers%29.png?version=f4f74b5091c1c6b71ac4827dde7c868a, EEPROM(Lua BIOS) Grid_EEPROM_%28OpenComputers%29.png?version=999363e174e807e0b21c084283ebcca4, жёсткий диск 1-го уровняGrid_%D0%96%D0%B5%D1%81%D1%82%D0%BA%D0%B8%D0%B9_%D0%B4%D0%B8%D1%81%D0%BA_%28%D0%A3%D1%80%D0%BE%D0%B2%D0%B5%D0%BD%D1%8C_1%29_%28OpenComputers%29.png?version=5bb37f57364937f2e33db036fd1a5c07, дискета с OpenOS Grid_%D0%94%D0%B8%D1%81%D0%BA%D0%B5%D1%82%D0%B0_%D1%81_%D0%BE%D0%BF%D0%B5%D1%80%D0%B0%D1%86%D0%B8%D0%BE%D0%BD%D0%BD%D0%BE%D0%B9_%D1%81%D0%B8%D1%81%D1%82%D0%B5%D0%BC%D0%BE%D0%B9_%28OpenComputers%29.png?version=8b2b5d77327751998cb3b98ab7d0e035, дисководGrid_%D0%94%D0%B8%D1%81%D0%BA%D0%BE%D0%B2%D0%BE%D0%B4_%28OpenComputers%29.png?version=3c4f116a9197008bdd4066746cd47ed8.

     

     

     

    Сделали? Тогда приступим!


    Внимание!!! Все блоки ставить друг к другу в ПЛОТНУЮ! Но можно соединять блоки OpenComputers между собой проводами.


    Первое - ставим корпус компьютера.

    Второе - позади корпуса компьютера поставьте преобразователь

    Третье - поставить рядом с преобразователем генератор

    Четвёртое - на блок преобразователя поставьте монитор

    Пятое - На корпус компьютера поставить клавиатуру

    Шестое - поставить справа от корпуса компьютера дисковод. И вставить туда дискету c OpenOS

    Седьм
    ое - Нажать на корпус компьютера правой кнопкой мыши и разложить по местам комплектующие, комплектующие могут поставиться
    только в нужный слот!

    Восьмое - А вы знаете, что генератор вырабатывает энергию от угля? Положите в генератор угля

    Девятое - Нажать правой кнопкой мыши по корпусу компьютера и нажать конпку со значком включения.

    Десятое -Если перед вами загорелась командная строка, значит вы всё сделали правильно. Но вам необходимо прописать install, ввести 1 (у нас 1 диск) и после
    того как вас спросят о перезагрузке прописать y. Подробнее тут в разделе.

     

     

     

     

     

     

     

    Готово! Вы собрали и запустили свой первый компьютер! И постарайтесь пока ничего не сломать

    :)

     

     

     

     

     

     

     

    Делаем книжку, пользуемся Not Enough Items[Гайд 2]


    Всю инфу о компонентах компухтера, блокам и не только можно узнать в книжке. Но её можно и не делать, а пользоваться
    , ч
    тобы
    узнать основную информацию о предмете/блоке вам нужно навести на него курсор и зажать Shift, а чтобы узнать стоимость крафта
    предмета/блока вам нужно зажать Ctrl.

     

     

     

     

     

     

     

    Основные функции Not Enough Items, которые вам понадобятся во время крафта компухтера:
    • R — Показать рецепты предмет\блок.
    • U — Показать, в каких рецептах используется предмет\блок.
    • Itemsubsets.jpg?version=a490d5b31cbb13f1e45b3c600542a549 — каталоги предметов, нажав туда вам откроется менюшечка, наведите мышь на пункт mods, проматайте колёсиком мыши список модов до нужного вам мода(если это необходимо) и быстро кликнуть на него два раза Левой Кнопкой Мыши


    Скачиваем программы с pastebin и закрываем практически все программы![Гайд 3]


    В этом блоге я расскажу вам, как скачать программу с pastebin, выйти практически из любой программы


    Для того, чтобы скачать программу с pastebin вы должны иметь интернет карту и написать pastebin get номерпрограммы имяпрограммы(какое вы хотите), это вы поняли, но как узнать этот номер? А очень просто вам просто нужно скопировать то, что находиться после чёрточкиblogentry-19322-0-21752400-1470915607_thumb.png . А для того, чтобы запусить программу не скачивая вам нужно прописать pastebin run, например это понадобиться при установке MineOS. А как же загрузить туда файл? Очень просто вам нужно прописать pastebin put имяфайла(какое вы хотите).

     

     

     

     

     

     

     

    Для того чтобы выйти практически из любой программы, вам необходимо нажать Ctrl + Alt + C

    Удачи и ресурсов вам!

  10. Programist135
    Последняя запись

    Всем привет!!!

     

    Это моя уже третяя программа в моём магазине приложенийблоге. Для неё понадобится уже робот.
    Итак, приступим.

     

    1. Комплектация и сборка
    Вам понадобится:

    • Системный блок 2 уровня
    • Геолайзер
    • Интернет-карта
    • Видеокарта 1 уровня
    • Монитор 1 уровня
    • Клавиатура
    • Дисковод
    • EEPROM c Lua BIOS
    • Дискета с OpenOS


    Собираем нашего робота. После чего вставляем в него дискету и устанавливаем OpenOS.

     

    2. Поле
    Строим следующее:
    UbZZDN6.png
    И ставим рядом с роботом зарядник и подводим к нему редстоун-сигнал и питание.

     

    3. Запуск
    Пишем в роботе следующее:
    pastebin get pV2iGZ2n /farm.lua
    А дальше набираем farm и.. Готово! Ваш робот "прочешет" всю ферму, если найдёт выросшую пшеницу (metadata = 7) то он её срубит и посадит снова. А ещё в программе ведутся логи с достаточно высоким приоритетом. Логируется даже инфа о каждой пшенице.
    c8V3Ut0.png4. В следующей версии
    В следующей версии наверное будет следующее:

    • Воздействие костной мукой
    • Проверка вспаханности земли


    Ну вот и всё, надеюсь вам эта программа пригодится, всем пока!

  11. XK893iv.pngRust


    Сегодня познакомимся с функциями и указателями, а также по мелочи: зоны видимости.

     

    Функции
    Функции в расте похожи на функции в Си, Jawa, луа. Для создания функции используется ключевое слово fn.

    fn add(a: i32, b: usize) -> usize {  a + b}


    После ключевого слова fn идет имя функции, далее в скобках указываются аргументы через запятую, и опционально, стрелочка -> и возвращаемый тип.
    Указывая аргументы нужно указывать тип аргумента после символа :.

     

    Функции в которых не указано возвращаемое значение, возвращают ()

     

    Ключевое слово return возвращает значение из функции.

    fn answer() -> i32 {  return 42;}


    return не всегда обязателен, позже разберемся где он нужен, а где не нужен.

     

    Указатели
    Указатели в расте гораздо безопаснее чем указатели в Си. Создать указатель на неизменяемые данные можно при помощи &.

    let a = 10;let pa = &a;


    Получить значение из указателя можно при помощи символа *.

    let a = 10;let pa = &a;println!("a = {}; *pa = {}; a + a = {}; *pa + *pa = {}", a, *pa, a + a, *pa + *pa);// \--> a = 10; *pa = 10; a + a = 20; *pa + *pa = 20


    Но в некоторых случаях писать * не обязательно.

    let a = 10;let pa = &a;println!("a = {}; pa = {}; a + a = {}; pa + pa = {}", a, pa, a + a, pa + pa);// \--> a = 10; pa = 10; a + a = 20; pa + pa = 20


    Раст сам все поймет, за что ему спасибо.
    Иногда мы хотим создать изменяемую ссылку. Для этого используется &mut.

    let mut a = 10;let pa = &mut a;*pa += 1;   // здесь * обязателен    println!("{}", pa);   //-->  11


    Если мы хотим изменить значение на которое указывает наш указатель, * обязателен. Без него раст не может понять, мы хотим присвоить новый указатель, или значение.
    В расте используется концепция "либо один писатель, либо много читателей". В примере выше, переменную a прочитать мы уже не сможем, и писать в нее тоже не сможем, так как она передана указателю pa. pa – писатель.

     

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

    let mut a = 10;let mut b = 20;let mut pa = &mut a;    println!("{}", pa);  // --> 10    pa = &mut b;    println!("{}", pa);  // --> 20    println!("{}", a);  // --> 10//             ^  ошибка, a уже имеет писателя, читателя не создать.    println!("{}", &a);  // --> 10//             ^-  ошибка, a уже имеет писателя, читателя не создать.    println!("{}", &mut a);  // --> 10//             ^-----  ошибка, a уже имеет писателя, еще одного не создать.


    Как видите, все правила про "либо один писатель, либо много читателей" работают даже если на a уже не указывает ничего.

     

    Зоны видимости
    Зоны видимости в расте ничем не отличаются от тех же в Луа.

    fn main() {  let a = 10;  {    let b = 20;    println!("{}", a);   // --> 10    println!("{}", b);   // --> 10  }  println!("{}", a);   // --> 10  println!("{}", b);   // --> 10  //             ^  ошибка, b нет.}


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

     

    Хозяйке на заметку:

    {
    и
    )
    это аналог
    do
    и
    end
    в Луа.

     

    На сегодня все. Извините что запоздал с 3 частью, так уж вышло. В следующий раз познакомимся с перечеслениями (enum) и структурами (struct). =)

    • 2
      записи
    • 14
      комментариев
    • 7465
      просмотров

    Последние записи

    Pofigist
    Последняя запись

    Не думайте, что я буквально за день написал три библиотеки и вполне рабочий проводник. Это не так. Создание PafOS началось еще недели две-три назад, но учитывая мою лень, реально, на создание того, что я сейчас имею было потрачено от силы 4 часа.
    Итак:
    На данный момент моя супер-пупер никому не нужная графическая оболочка называется test.lua и запускается из консоли, как и все программы. Запуск через init? До всего этого мне еще далеко, как и до превращения граф оболочки в полноценную ОС. Да и плохо я понимаю, что из себя она представляет. Операционная Система эта та для которой все базовые библиотеки написаны отдельно? Или та, которая запускается через BIOS? Лично для меня этот вопрос остается загадкой. Но может кто-то может дать ответ, к которому я в будущем буду стремиться.

     

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

     

    OonRTSM.png

     

    На скрине вы можете увидеть итог моей текущей работы - создание полноценного проводника. Безусловно я не прописывал через gpu.set каждый пиксель моего изображения: для картинок была создана отдельная библиотека. Соответственно есть и отдельный формат изображения - PIF(Pofigist Image Format). Особенность или нет - судить вам, но на один пиксель в моем формате уходит всего 2 байта, а на полупиксель - 1 байт, соответственно. На данный момент я не вижу смысла в использовании символов в формате картинок, но если он и будет реализован - это будет новый формат.
    PIF спокойно поддерживает картинку 160x50, чего достаточно для обычных программ. PIF поддерживает прозрачность, но на это уходит какой либо цвет. Если все 256 цветов используются в изображении то будут определенные проблемы, но на данный момент я доволен форматом.

     

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

     

    Вы удивитесь, но кроме того как посмотреть на содержимое текущей папки программа так же позволяет перейти в другую папку или вернуться на шаг назад!!1
    bMVFqmx.png

     

    Ву-упс, кажется что-то пошло не так... Если файлов в папке слишком много некоторые из них могут не отображаться. Ну как некоторые... большинство. Причем все контролируется волей рандома и открыв и закрыв папку пару раз можно убедиться, что неотображаемые файлы меняются... Я долго думал над тем, почему так происходит. На ум пришла идея с проблемой функции Draw, которая вырисовывает изображение, но это мысль была ошибочной. Мною был найден небольшой баг... если не закрывать чтение какого-либо файла и потом вновь его открывать для нового чтения файловая система может разозлиться и послать тебя в Эндер мир. На данный же момент проблема уже решена. file:close() победил баг и все отображается так как надо.
    RJAQgi7.png

     

    Что же мы в итоге имеем?
    Убогие иконки с разрешением 10x10, кривое отображение имен файлов. Невозможность сделать ничего, кроме как открыть папку или уйти на шаг назад; отсутствие объекта той или иной иконки(системно лишь визуально отображается иконка и создается кликабельная область в ее границах(И я считаю это преимуществом)). И... пафосное название недо-операционки PafOS, которая изначально должна была называться PofOS от моего ника, но пафос все же круче :D

     

    Теперь пара вопросов от нубика:
    Какая библиотека java(а лучше С#/C++) позволит мне открыть изображение, прочитать изображение по байтам? И есть ли документация по структуре PNG файла?

     

    P.S. На вопросы можно не отвечать, а просто оставить мнение о моей разработке :D Прямых рук Вам, Господа.

  12. eu_tomat
    Последняя запись

    Здравствуй, брат автоматизатор!

     

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

     

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

     

    В прошлый раз я рассказал о том, как математика помогает писать более простые, понятные и при этом более эффективные программы.
    qwertyMAN заметил, что использование взятия остатка от деления – это не математическая проблема, и я с ним отчасти согласился. Решение о том, использовать или нет операцию %, мало влияет на общий алгоритм, но сильно влияет на то, как будет выглядеть готовый код. Но всё-таки об этой операции следует помнить уже на этапе проектирования алгоритма, а не только на этапе кодинга.
    А вот, о тонкостях написания кода я хочу рассказать сегодня, не особо вдаваясь в общие алгоритмы. Моим подопытным будет уже знакомый код из охранной системы турелей.
    Вот сам код:


    local function func()	local com					= require("component")	local event					= require("event")	local gpu					= com.gpu	local turret				= com.os_energyturret	local radar					= com.openperipheral_sensor	local autors				= {"qwertyMAN"}	local version				= "0.9.1"	-- Настройки	local firePleayers			= true	local fireMobs				= true	local Black_Player_List		= {}	local White_Player_List		= {}	-- относительные координаты пушки от сканера	local correct = {		x = 0,		y = 4,		z = 0	}	local function pointer(x,y,z)		local distXY = math.sqrt(x^2+z^2)		local distDY = math.sqrt(y^2+distXY^2)		local outX = math.deg(math.acos(x/distXY))+90		local outY = 90-math.deg(math.acos(y/distDY))		if z<0 then			outX = (180-outX)%360		end		return outX,outY	end								while true do		os.sleep(0)		local target = false		local fire = true		local scan=radar.getPlayers()		if firePleayers and #scan>0 then			if #White_Player_List>0 then				for i=1, #autors do					White_Player_List[#White_Player_List+1] = autors[i]				end				for i=1, #scan do					local swich = true					for j=1, #White_Player_List do						if scan[i].name==White_Player_List[j] or not scan[i].name then							swich = false						end					end					if swich then						target = scan[i].name						break					end				end			elseif #Black_Player_List>0 then				for i=#Black_Player_List, 1, -1 do					for j=1, #autors do						if Black_Player_List[i] == autors[j] then							table.remove(Black_Player_List,i)						end					end				end				for i=1, #scan do					local swich = false					for j=1, #Black_Player_List do						if scan[i].name==Black_Player_List[j] then							swich = true						end					end					if swich then						target = scan[i].name						break					end				end			else				if #autors>0 then					for i=1, #autors do						White_Player_List[#White_Player_List+1] = autors[i]					end				else					target = scan[1].name				end			end			if target and radar.getPlayerByName(target) then				target=radar.getPlayerByName(target).all()				local x,y,z = target.position.x-0.5-correct.x, target.position.y+0.3-correct.y, target.position.z-0.5-correct.z				local vx,vy = pointer(x,y,z)				turret.moveTo(vx,vy)				if turret.isOnTarget() then					turret.fire()				end				fire = false			end		end		target = false		if fireMobs and fire then			local scan=radar.getMobIds()			if #scan>0 then				for i=1, #scan do					local mob					if radar.getMobData(scan[i]).basic() then						mob = radar.getMobData(scan[i]).basic()						target = mob					end				end				if target then					local x,y,z = target.position.x-0.5-correct.x, target.position.y-0.5-correct.y, target.position.z-0.5-correct.z					local vx,vy = pointer(x,y,z)					turret.moveTo(vx,vy)					if turret.isOnTarget() then						turret.fire()					end				end			end		end	endend-- мегакостыльwhile true do	local oop = pcall(func)	print(oop)end

     

     

    Первое, на что я обратил внимание – это использование pcall. Именно оно и побудило меня к разбору кода, но прежде я предлагаю обсудить другой нюанс.

     

    1. Избегай повторения уже выполненных вычислений
    Имеются два фрагмента кода:

    if target and radar.getPlayerByName(target) then  target=radar.getPlayerByName(target).all()...local mobif radar.getMobData(scan[i]).basic() then  mob = radar.getMobData(scan[i]).basic()  target = mob

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

    if target then  target = radar.getPlayerByName(target)  if target then    target=target.all()...target = radar.getMobData(scan[i])if target then  target = target.basic()

    Почему я проверяю результаты getPlayerByName и getMobData, а не других функций вроде all() или basic()? Потому что именно они могут вызвать ошибку. Ошибка возникает от того, что игрок или моб может покинуть зону действия сенсора, пока выполняется обработка внутри программы. К сожалению, указанной проверки недостаточно, т. к. мод OpenPeripheral вместо того чтобы вернуть nil или иным образом указать на проблему, тупо генерирует ошибку, не оставляя иного варианта кроме использования pcall.

     

    2. Используй защищенный режим только там, где это необходимо
    Код программы выглядит примерно так:

    local function func()  -- почти весь код программы помещен в эту функцию  -- включая инициализацию переменных и определение функций  ...  -- этот бесконечный цикл прерывается из-за отсутствующей обработки ошибок  while true do    ...    local target = false    local scan=radar.getPlayers()    ...    target = ...    if target and radar.getPlayerByName(target) then      target=radar.getPlayerByName(target).all()      ...    end    ...  endend-- мегакостыль (комментарий самого автора)while true do	local oop = pcall(func)	print(oop)end

    Автор понимает, что использует костыль, но правильное решение использовать не хочет. Подобные городушки провоцируют появление новых: уже сейчас на ровном месте появилась дополнительная функция и вложение двух бесконечных циклов. Но главная проблема этого кода в том, что pcall скрывает любые ошибки, и дальнейшая отладка программы становится затруднительной. Даже печать результата, возвращаемого pcall, реализована неверно – ничего кроме false выведено не будет.
    Для решения проблемы следует использовать pcall точечно, только там, где это необходимо, а именно в вызове getPlayerByName и getMobData. А если есть возможность вообще обойтись без pcall, то в готовой программе без него следует обойтись. В нашем случае обойтись без pcall, похоже, нельзя. Поэтому убираем наш костыль и функцию func, оставив лишь ее содержимое, и дорабатываем проблемные участки таким образом:

    if target then  local flag,res = pcall(radar.getPlayerByName,target)  if flag then    target=res.all()...local flag,res = pcall(radar.getMobData,scan[i])if flag then  target = res.basic()

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

     

    3. Выноси за цикл всё, что возможно
    Это правило подобно первому, но пренебрежение им не так бросается в глаза начинающего программиста, т.к. сам код не дублируется, зато дублируется его исполнение.
    Восстановим общий алгоритм работы программы, чуть подробнее разобрав этот кусок:

    while true do  local target = false  ...  local scan=radar.getPlayers()  if firePleayers and #scan>0 then    if #White_Player_List>0 then      добавление списка авторов в в белый список      target = первый игрок на радаре вне белого списка    elseif #Black_Player_List>0 then      удаление авторов из черного списка      target = первый игрок на радаре в черном списке    else      if #autors>0 then        перенос авторов в белый список      else        target = первый игрок на радаре  вычисление координат цели и выполнение выстрела  сканирование мобов, вычисление их координат с последующим расстрелом.

    Как ты уже догадался по заголовку, в бесконечном цикле выполняется что-то явно лишнее. А именно, работа со списком авторов. Всё это могло бы прекрасно работать и до основного цикла, создавая при этом нужный эффект. Более того, вынос этого кода за цикл позволит исправить серьезнейшую ошибку: на каждой итерации бесконечного цикла происходит добавление авторов в белый список, при этом их наличие в белом списке никак не проверяется, но каждый раз происходит добавление новых. Даже с двумя планками памяти 3.5 уровня через сотню-другую тысяч итераций программа завершится с ошибкой «not enough memory».
    Вынося лишние действия за цикл, ты избавишь программу как от неконтролируемого расхода памяти, так и от лишних действий, замедляющих ее работу. Думаю, демонстрировать корректный код здесь излишне. Достаточно лишь вынести эти участки кода из цикла.

     

    В программе присутствуют и менее очевидные вычисления, которые можно вынести за цикл.

    -- этот код находится за цикломlocal correct = { x = 0, y = 4, z = 0 }...-- а этот внутриlocal x,y,z = target.position.x-0.5-correct.x, target.position.y+0.3-correct.y, target.position.z-0.5-correct.z...local x,y,z = target.position.x-0.5-correct.x, target.position.y-0.5-correct.y, target.position.z-0.5-correct.z

    Логичным будет переписать код таким образом:

    -- этот код за цикломlocal correct = { x = 0+0.5, y = 4+1, z = 0+0.5 }...-- а этот внутриlocal x,y,z = target.position.x-correct.x, target.position.y+1.3-correct.y, target.position.z-correct.z...local x,y,z = target.position.x-correct.x, target.position.y+0.5-correct.y, target.position.z-correct.z

    Так мы избавимся от лишних сложений и вычитаний в цикле. Лишние сложения при инициализации таблицы correct не сильно помещают, т. к. они выполняются всего один раз, а нужны они для наглядности кода. Поясню, что здесь происходит.
    Во-первых, турель и сенсор находятся в разных блоках, поэтому координаты игрока следует скорректировать на эту разницу. Координаты турели относительно сенсора хранятся в таблице correct.
    Во-вторых, сенсор определяет координаты игроков и мобов относительно своего северо-западного угла, а турель вращается вокруг центра блока. Поэтому приходится корректировать координаты (x,z) на половину блока по горизонтали.
    В-третьих, сама турель стреляет на один блок выше уровня ног игрока или моба. Автор корректирует высоту цели в зависимости от цели: для игрока прицел приподнимается на 0.3 блока, чтобы игрок не мог уходить от выстрела прыжком или прятаться за блоки, а для мобов прицел опускается на полблока, чтобы попадать, например, в кур или свиней. Но тут тоже не всё просто. Чтобы попадать в цыплят, прицел следует опустить еще ниже, но тогда турель промахивается мимо взрослых кур, стреляя им куда-то под ноги. Для эффективной стрельбы по любым мобам нужен алгоритм, определяющий вид моба, его возраст, и находящий по таблице его рост. Причем, нужен не только рост. Например, нет смысла целиться в нижнюю часть слизня, т. к. тот постоянно прыгает. В общем, это отдельная тема для поиска оптимального алгоритма, сейчас же я хочу продолжить рассказ о кодинге.
    В итоговом коде не только вынесены лишние вычисления из цикла. Кроме этого он стал более логичным: числа 1.3 и 0.5 по сути означают высоту цели относительно ног игрока или моба.

     

    4. Прерывай циклы, когда они уже выполнили свою задачу
    Вот два подобных друг другу фрагмента кода:

    local swich = truefor j=1, #White_Player_List do  if scan[i].name==White_Player_List[j] or not scan[i].name then    swich = false  endendif swich then...local swich = falsefor j=1, #Black_Player_List do  if scan[i].name==Black_Player_List[j] then    swich = true  endendif swich then

    Задача циклов в том, чтобы при подходящем случае изменить значение переменной switch. Но как только оно изменилось, зачем продолжать работу? Далай break. Иначе выполнение твоей программы замедляется.
    Пока я писал этот текст, то напрягался при каждом наборе названия переменной swich. Нет такого слова, зато есть слово switch, и не глядя я набирал именно его. Поэтому буду писать switch. Кроме того, название переменной все равно не отражает ее сути. С тем же успехом можно было использовать однобуквенное название переменной. А лучше бы и вовсе избавиться от нее.

     

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

    local target = false...for i=1, #scan do  local swich = true  for j=1, #White_Player_List do    if scan[i].name==White_Player_List[j] or not scan[i].name then      swich = false      break    end  end  if swich then    target = scan[i].name    break  endend...for i=1, #scan do  local swich = false  for j=1, #Black_Player_List do    if scan[i].name==Black_Player_List[j] then      swich = true      break    end  end  if swich then    target = scan[i].name    break  endend

    Что выполняют оба фрагмента? Ищут подходящую цель по белому и черному спискам игроков.
    Где хранится цель? В переменной target.
    Что хранится в переменной switch? Флаг того, что переменная target должна быть изменена.
    А зачем нам этот флаг? Что мешает сразу изменить переменную?

    local target = false...for i=1, #scan do  target = scan[i].name  for j=1, #White_Player_List do    if scan[i].name==White_Player_List[j] or not scan[i].name then      target = false      break    end  end  if target then    break  endend...for i=1, #scan do  for j=1, #Black_Player_List do    if scan[i].name==Black_Player_List[j] then      target = scan[i].name      break    end  end  if target then    break  endend

    Код стал немного короче и быстрее, но и это еще не предел.

     

    Еще непонятно, что делает, or not scan.name в условии. Повлиять это выражение может в том случае, если scan.name будет равно false, или nil. А разве такое возможно? Даже не знаю, как классифицировать этот недочет. Видимо, от старых экспериментов осталось. Посоветовать можно только одно: вычищать код перед публикацией.

     

    6. Используй ассоциативные возможности таблиц Lua
    Таблицы в Lua – это больше чем массивы. Это и объекты, и списки, и словари. А может, и что-то еще, о чем я забыл или даже не знал.
    Таблицы в Lua – это наборы пар ключ-значение. В качестве ключей и значений таблицы может быть что угодно кроме nil.
    Пара ключ-значение в таблицах Lua присутствует даже если мы не используем ключи явным образом.
    Попробуй запустить такой код:

    PlayerList={"Ded", "Baba", "KurochkaRyaba"}for k,v in pairs(PlayerList)do print(k,v)endfor i=1,#PlayerList do print(PlayerList[i])endPlayerList={[1]="Ded", [2]="Baba", [3]="KurochkaRyaba"}for k,v in pairs(PlayerList)do print(k,v)endfor i=1,#PlayerList do print(PlayerList[i])endPlayerList={["Ded"]=1, ["Baba"]=2, ["KurochkaRyaba"]=3}for k,v in pairs(PlayerList)do print(k,v)endfor i=1,#PlayerList do print(PlayerList[i])endprint(#PlayerList)print(PlayerList["Ded"])print(PlayerList["Baba"])print(PlayerList["RedHatBaby"])

    blogentry-13296-0-54921600-1459108363_thumb.png
    В первом случае мы не указываем ключи явно, но они создаются. Мы свободно перебираем как пары ключ-значение, так и значения по их индексу, который совпадает с ключом.
    Во втором случае мы явно указали ключи. Перебор пар ключ-значение показывает, что элементы таблицы хранятся в неведомом нам порядке, скорее всего, в соответствии с неким хешем, но на перебор по индексу это никак не влияет, порядок не нарушен, а это самое главное.
    В третьем случае мы поменяли ключи и значения местами. Естественно, ни о каком переборе по индексу теперь не идет и речи. Более того, определить длину таблицы теперь тоже не так просто. Зато появилась возможность, не выполняя перебор всех значений в цикле, одной командой определить, присутствует ли игрок в списке. Для игроков Дед и Баба есть значение, а игрок КраснаяШапочка в список не внесен, и имеет значение nil.

     

    Как это соотносится с нашим кодом? Попробуем заполнять списки игроков таким образом:
    local Black_Player_List = { ["qwertyMAN"]=1 }
    local White_Player_List = { ["Ded"]=1, ["Baba"]=1, ["KurochkaRyaba"]=1 }
    В качестве значения я использовал 1, и оно может быть любым, но 1 - записывается кратко. Главное, чтобы не nil. И не false, чтобы проще было выполнять проверку элемента.
    То, что qwertyMAN оказался в черном списке, ему никак не повредит, он же автор.

     

    Теперь все фрагменты кода изменятся таким образом:

     

    Добавление списка авторов в в белый список:

    -- былоfor i=1, #autors do  White_Player_List[#White_Player_List+1] = autors[i]end-- сталоfor i=1, #autors do  White_Player_List[autors[i]] = 1end

    Код немного укоротился, а главное – теперь переполнение памяти не грозит даже при работе в бесконечном цикле, т. к. элемент создается один раз, а в последующие – лишь изменяется его значение.

     

    Удаление авторов из черного списка:

    -- былоfor i=#Black_Player_List, 1, -1 do  for j=1, #autors do    if Black_Player_List[i] == autors[j] then      table.remove(Black_Player_List,i)    end  endend-- сталоfor j=1, #autors do  Black_Player_List[autors[i]] = nilend

    Код заметно укоротился.
    Сомневаешься, действительно ли элемент таблицы удаляется? Запусти этот код, и все станет понятным:

    PlayerList={["Ded"]=1, ["Baba"]=2, ["KurochkaRyaba"]=3}for k,v in pairs(PlayerList)do print(k,v)endPlayerList["Ded"]=nilfor k,v in pairs(PlayerList)do print(k,v)end

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

    -- былоfor i=1, #scan do  target = scan[i].name  for j=1, #White_Player_List do    if scan[i].name==White_Player_List[j] then      target = false      break    end  end  if target then    break  endend...for i=1, #scan do  for j=1, #Black_Player_List do    if scan[i].name==Black_Player_List[j] then      target = scan[i].name      break    end  end  if target then    break  endend-- сталоfor i=1, #scan do  if not White_Player_List[scan[i].name] then     target = scan[i].name     break  endend...for i=1, #scan do  if Black_Player_List[scan[i].name] then      target = scan[i].name      break    endend

    7. Минимизируй идентичные участки кода
    При добавлении сходного функционала в программу можно скопировать рабочий участок кода и немного изменить его. Иногда до неузнаваемости. Но если фрагмент достаточно велик, а изменения малы, то правильнее будет вынести этот фрагмент в отдельную функцию. Во-первых, итоговой код будет более компактным. Во-вторых, при необходимости будет проще вносить изменения, не правя все участки кода.
    В программе имеется два таких похожих участка:

    local x,y,z = target.position.x-correct.x, target.position.y+1.3-correct.y, target.position.z-correct.zlocal vx,vy = pointer(x,y,z)turret.moveTo(vx,vy)if turret.isOnTarget() then  turret.fire()end...local x,y,z = target.position.x-correct.x, target.position.y+0.5-correct.y, target.position.z-correct.zlocal vx,vy = pointer(x,y,z)turret.moveTo(vx,vy)if turret.isOnTarget() then  turret.fire()end

    Ранее мы уже выяснили, что единственная изменяемая величина здесь – это коррекция высоты цели. Сейчас основной вопрос: что из этого следует вынести в отдельную функцию. С точки зрения минимизации кода следует выносить почти всё. Но чтобы сделать код более логичным, не следует всё мешать в одну кучу. Лучшим решением мне кажется вынос всего, что связано с вычислениями, в уже имеющуюся функцию pointer. Вот она:

    local function pointer(x,y,z)  local distXY = math.sqrt(x^2+z^2)  local distDY = math.sqrt(y^2+distXY^2)  local outX = math.deg(math.acos(x/distXY))+90  local outY = 90-math.deg(math.acos(y/distDY))  if z<0 then    outX = (180-outX)%360  end  return outX,outYend

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

    local function pointer(pos,h)  local x,y,z = pos.x-correct.x, pos.y-correct.y+h, pos.z-correct.z  local azimuth=math.deg(math.atan2(x,-z))%360  local elevation=math.deg(math.atan2(y,math.sqrt(x*x+z*z)))  return azimuth, elevationend...turret.moveTo(pointer(target.position,1.3))if turret.isOnTarget() then  turret.fire()end...turret.moveTo(pointer(target.position,0.5))if turret.isOnTarget() then  turret.fire()end

    Конечно, этот код можно ужать еще плотнее, но я увижу в этом смысл, если дальнейшая доработка программы вынудит меня продублировать эти блоки кода.

     

    На этом закончу. Возможно, я дал бы тебе еще пару советов, но за исключением описанных выше моментов код qwertyMAN'а вполне адекватен.

     

    Программируй красиво, брат!

  13. Блог недоблоггера

    • 3
      записи
    • 16
      комментариев
    • 6918
      просмотров

    Последние записи

    Доброго времени суток.
    Не секрет наверное, что UU-валюту можно получить, проголосовав за проект на рейтинговых порталах (мониторингах серверов MC).
    Но бывает так, что слишком сильно засиживаешься в игре, что забываешь проголосовать и теряешь в день целых 70 UU.
    Я по началу тоже пропускал (забывал) голосовать. И я решил, а что если написать "напоминалку" о том, что нужно проголосовать.

     

    Итак, данная статья рассчитана на linux-пользователей (для windows-юзеров я ниже напишу альтернативу этому).

     

    Что нужно для того, чтобы сделать "напоминалку":

    • Любой linux-диструбутив (у меня Arch Linux)
    • Любое DE (рабочая среда. Пример у меня KDE5)
    • bash (с этим проблем нет у линуксеров)
    • Установленный пакет zenity (утилита, которая позволяет выводить на экран диалоговые окна GTK+ из командной строки и скриптов командной оболочки. С установкой в ubuntu и linux mint с этим проблем нет. Для других дистрибутивов надо копать самим этот пакет. В Arch Linux он есть)
    • cron (он же планировщик задач. По-умолчанию его нет в десктопных версиях дистрибутивов. Нужно поставить самим)
    • Руки, растущие из плеч (ибо результат может отличаться от примера в статье)


    Я долго не стану расписывать что есть что. Документацию по zenity и cron можно найти спокойно в сети.
    Я лишь сразу выложу уже готовый bash-скрипт, который выводит данное окошечко на экран:

     

     

     

     

     

    dzehCAN.png


    Вот собственно сам код:

    #!/bin/bashDISPLAY=:0.0 /usr/bin/zenity --info --no-wrap --title="Время голосовать" --text="<i>Настало время проголосовать за проект</i> <a href='http://computercraft.ru'><b>computercraft.ru</b></a>\n\n<a href='http://mcrate.su/rate/5123'><b>mcrate.su</b></a> | <a href='http://topcraft.ru/servers/3000'><b>topcraft.ru</b></a> | <a href='http://monitoringminecraft.ru/top/computercraft'><b>monitoringminecraft.ru</b></a>" --ok-label="Уже спешу голосовать"


    И чтобы это окошко вылезало каждый день в определенное время напишем в cron задачу (по-умолчанию добавление задачи осуществляется командой в консоле crontab -e. Ну это так для тех кто забыл):

    00 22 * * *     /bin/bash /home/user/vote.sh


    Коротко скажу что делает данная задача.
    00 22 - это время. Я поставил 22:00 (моего времени местного стоит отметить).
    * * * - это день, месяц, день недели (нам надо чтобы каждый день выполнялось поэтому ставим *).
    /bin/bash /home/user/vote.sh - собственно сама команда на исполнение скрипта. Я всегда прописываю полный путь до bash, чтобы не было проблем, а далее указываем путь, где лежит файл-скрипт.

     


    В общем-то и все. "Напоминалка" готова.
    Ах да, забыл сказать, после добавления и сохранения в crontab задачи не забудьте перезапустить демон (для тех у кого стоит init.d, а это в основном убунтеры и линукс минтеры для них sudo service cron restart, для systemd - sudo systemctl restart cronie.service (я поставил пакет cronie)).

     

    Не забывайте голосовать за проект и удачи в программировании :smile9:

     

    P.S. Как и обещал для windows-пользователей. Можно конечно поставить zenity (И если хватит скилла настроить через стандартный планировщик задач Windows вызов bat-скрипта с настроенным path до zenity, то респект и уважуха вам. Можно прочитать как сделать консольную напоминалку).
    Но можно не заниматься извращением, а сразу поставить специализированные "напоминалки". Вот несколько из них: LeaderTask, Simple Sticky Notes и т.п.
    Насчет работоспособности и функционала я не знаю что у них. Т.к. я не могу протестировать их.

     

    СМ.ТАКЖЕ

  14. Квантовый блог

    • 1
      запись
    • 9
      комментариев
    • 12728
      просмотров

    Последние записи

    Аналоговый передатчик


    Файлов по рэдстоуну


    Возвращение легенды)


    Некоторые помнят мою передавалку чисел по рэдстоуну...
    Но чисел мало...
    Но теперь скорость настолько большая,что можно передавать даже файлы!
    Конструкция осталась такой,какой была и раньше:
    mwM6b.jpg
    Зато изменились протокол передачи и программа)
    Краткая характеристика:
    Поддержка юникода +
    Скорсть передачи байта от 0,1 до 0,3 секунд



    Посмотреть код:

    Отправлялка:http://pastebin.com/Zdj8Gh5F
    Принималка:http://pastebin.com/bAACig6m

     

  15. Всем привет! Сегодня я расскажу Вам о том, как делать задания для игроков с помощью мода Custom Npcs. Для начала вам понадобится любой диалог ( подробнее тут

    ).

    1. Зайдём в меню диалога
    2. Создадим...."поддиалог"
    3. В поле "текст диалога" пишем что-то вроде "Принеси мне 1 блок обсидиана. я тебя за это щедро награжу, {player}!"
    4. Подключаем "поддиалог" так, чтобы у нас была возможность перейти на него
    5. Забываем на время про диалог


    Дальше делаем так Глобальные -> Задания -> Добавить -> лкм по созданному заданию -> кнопка Задания -> Добавить -> лкм по созданному окошку. Разберём его:

    • Название - просто название, чтобы не запутаться
    • Завершение текста - пишем туда что-то вроде "Ты сделал это! Держи награду!!!"
    • Текст квеста - описание задания
    • Награда - туда ставите то, что получит прошедший (можно оставить воздух)
    • Тип - есть задания на вещи, убийства, диалоги, локации и т.д. в зависимости от типа игрок надо с кем-то поговорить, что-нибудь принести и т.д.
    • Повторяется - да или нет - можно ли пройти задание несколько раз
    • Продвинутые - отношения с фракциями после прохождения, команда после прохождения, автоматически дать следующее задание


    Так разобрались! теперь пишем:

    1. "завершение диалога" - "Поздравляю! Сейчас достану награду."
    2. "текст квеста" - "Melancholy попросил принести блок обсидиана. Обещает вкусную плюху...."
    3. "награда" - кидаем 5 алмазов
    4. "тип" - разумеется на вещь", "редактировать" - положим блок обсидиана. "выдать предмет" - отберут ли у нас предмет. О том что такое "Урон" и "NBT" я рассказывать не буду
    5. Всё. Задание готово!


    Теперь надо это привязать. Выбираем "Задание" (диалог, про который мы на время забыли). нажимаем на "Выбрать квест". Выбираем наш квест.
    Наслаждаемся работой.
    PS
    Осталось рассказать о предметах и о малозначительных вкладках. Стоит ли продолжать?

  16. Krutoy
    Последняя запись

    Новости!

    • Теперь мой браузер будет называться "Арбузер", и будет выполнен в зеленоватых тонах.
    • Zer0Galaxy мне помогает, и уже набросал парсинг и поиск по самым простым селекторам в CSS. Думаю, ему для полной работы с CSS нужно будет написать еще разов в 6 больше кода.
    • Готовы первые наброски самого браузера без страниц. Закладки, навигация, строка пути.

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

     

    9AtyDPm.png

     

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

  17. В прошлый раз мы научились подключаться к сети OpenNet, создавать простенький сайт и открывать его на локальном компьютере. Сегодня мы попытаемся получить доступ к сайту удаленно.

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

    wget -f https://preview.c9.io/krutoy242/opennet/_source/WEB/WEBserver.lua webserv.lua

    Да, да, не удивляйтесь, именно wget, хоть в составе нашего компьютера и нет интернет-карты. После того, как мы подключились к Сети нам стали доступны все прелести интернет-карты даже при отсутствии оной, а всё благодаря крутому интернет-серверу, функционирующему в Сети. Pastebin, кстати, тоже работает.

    Загрузили webserver? Запускаем его. Мы должны увидеть вот такую картинку:

    blogentry-7-0-90118400-1435679055_thumb.png

    Запомним IP-адрес нашего сервера (выделено на картинке). Он понадобится в первое время для подключения к серверу. Теперь идем к другому компьютеру, подключенному к Сети, и проверяем наличие связи с сервером:

    ping c0b.9cf.a4f

    Если у Вас нет второго компьютера, Вы можете воспользоваться любым свободным в нашем датацентре.

    Связь есть? Запускаем браузер с указанием адреса нашего сервера.

    onBrowser c0b.9cf.a4f

    blogentry-7-0-91764200-1435679191_thumb.png

    Как видим, для открытия сайта по сети нет необходимости указывать не только папку /web, но и имя файла index. Дело в том, что папка /web считается корневой для нашего сайта. А если не указать имя файла, то по умолчанию сервер вернет файл index. Все остальные файлы придется указывать.

     

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

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

    Как же происходит процедура регистрации? Можно, конечно, воспользоваться напрямую функциями DNS-сервера, описанными в теме http://computercraft.ru/topic/675-opennetoc-prodolzhenie/?do=findComment&comment=9097, но с некоторого момента я предпочитаю пользоваться утилитой setdns, которая входит в стандартный набор программ OpenNet.

    Эта утилита позволяет проверить не зарегистрировано ли еще DNS-имя, какие имена зарегистрированы на тот или иной IP, проводить собственно регистрацию или корректировать настройки уже зарегистрированного имени. В будущем планируется реализовать функцию удаления DNS-имени, но пока она не реализована.

    Первым делом убеждаемся, что выбранное имя еще не никем не занято (пункт 1).

    blogentry-7-0-81800300-1435679429_thumb.png

    Затем запускаем процедуру регистрации (пункт 3).

    При регистрации необходимо указать желаемое dns-имя, IP-адрес, с которым это имя будет ассоциировано, и пароль. Пароль понадобится, если мы заходим перерегистрировать имя на другой IP.

    blogentry-7-0-80094400-1435679450_thumb.png

    Если регистрация проводится с того компьютера, чей IP ассоциируется с dns-именем, на запрос IP можно ввести пустую строку.

    После регистрации выбираем пункт 0 для выхода из утилиты setdns.

    Теперь мы можем обращаться к серверу не по IP, а по удобному имени. Снова запустим webserver на нашем компьютере, а на соседнем

    onBrowser Zer0

    blogentry-7-0-28516400-1435679755_thumb.png

     

    В следующий раз я постараюсь рассказать как сделать наш сайт разноцветным и интерактивным.

    (продолжение следует)

  18. KelLiN' - блог

    • 1
      запись
    • 4
      комментария
    • 9425
      просмотров

    Последние записи

    KelLiN
    Последняя запись

    Ресурсов всегда не хватает. Что делать ?! Копать! Где копать ?! Вот сейчас то после прочтения данной записи мы и узнаем.

     

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

     

    Использоваться будет команда сканера scan. Вот выдержка из вики:

    scan(x: number, y: number, [ignoreReplaceable: boolean]): table or nil, stringФункция сканирует "колонну" блоков в относительных координатах (x, y) и возвращает таблицу плотностей (с определенной погрешностью). В случае ошибки возвращает nil и ее текст.Координаты (0, 0) обозначают колонну блоков, в которой располагается сам сканер (32 блока вверх от него, и 32 блока вниз).

    От себя добавлю только то, что можно сканировать куб 64*64*64 , где центр куба - положение сканера. Положением сканера будет центр этого куба, тоесть 32 высота ( Также у нас на сервер насколько я понял куб будет 128*128 и высотой в 64 блока). На сканирование одного блока уходит 10 энергии. На один столб должно порядка 640.

     

    Для начала работы нам потребуется сам планшет со следующими минимальными компонентами:

    -видеокарта 1 уровня

    -монитор 1 уровня

    -клавиатура

    -геосканер

    -любые процессор, оперативная память, винчестер, bios и пр. .

     

    Для начала работы нам нужен планшет с записанной на диск программой. Я не использовал в планшете интернет-карту, а просто вставил текст программы нажатием средней кнопки мыши в открытый для редактирования файл. Ссылка на pastebin: http://pastebin.com/eJne1Dna . Код eJne1Dna

    c=        require("component")computer= require("computer")event=    require("event")os=       require("os")term =    require("term")gpu=c.gpus=c.geolyzerfunction intro()  print("Нажмите пробел для сканирования")  print("Нажмите q для выхода")  print("Нажмите с для очистки экрана")  print("Область сканирования 20 блоков на восток")endfunction scann()--сканирует область в 20 блоков от игрока в сторону севера.  local cx,cy=1,1  local onThatX=0;--количество ресурсов для данного столбца. Используется для отрисовки глубины копки для нового  local maxy=1;--положение курсора по окончании сканирования  for x=1,20 do    gpu.set(cx,cy,tostring(x));--текущий столбец    data=s.scan(x,0);-- х инкриментируется до 20, у=0 ширина сканирования 1.    local t=0;--"табулятор" для двухсимвольной глубины.    if x>9 then t=1 end    for d=1,32 do      if data[d]>2 then        -- в data записаны плотности блоков. >2 означает сообщать о блоках с плотностью более 2.        -- Весь диапазон от 0 до 99. 99 это вроде игрок. Все ресурсы примерно одинаковой плотности в районе 3.        computer.beep(2000,0.1)        if onThatX>0 then          cy=cy+1          if (32-d)>9 and t==0 then t=1 end;--смещаем курсор для печати на один столбец дальше из-за цифт больше 9.          if cy<15 then             gpu.set(cx,cy,tostring(math.floor(32-d)));--Печатает глубину на которую нужно копать вниз относительно начальной высоты игрока.          else            -- для 80*15 экрана. Для больших экранов можно изменить и убрать.            gpu.set(cx,15,tostring(math.floor(32-d)))          end        end        onThatX=onThatX+1       end    end    if t==1 then cx=cx+2 else cx=cx+1 end;t=0        if cy>maxy then maxy=cy end;--положение курсора при продолжениие печати о "нажмите enter для продолжения".    cy=1    onThatY=0;--обнуляем количество ресурсов для текущего столбца.  end  term.setCursor(1,maxy)  term.write("нажмите enter для продолжения")  io.read()  term.clear()  intro()endintro()while true do  _,_,key1,key2=event.pull("key_down")  if key2==57 then      term.clear();scann()  elseif key2==46 then  term.clear();intro()  elseif key2==16 then  term.clear();os.exit()  endend

    Для демонстрации работы я подготовил стэнд:

    index.php?app=core&module=attach&section=attach&attach_rel_module=post&attach_id=424

     

    С включенным планшетом я стал в позицию 1. Для работы программы нужно обязательно смотреть на восток. Это связанно с жестким закреплением направления сканирования в программе из-за избыточной сложности пользования gps (не сложности программирования, а малого gps.range() ). Скриншоты с начальным положением и направлением в начале работы для тех, кто путается со сторонами света или пока еще не проходил географию в школе:

    index.php?app=core&module=attach&section=attach&attach_rel_module=post&attach_id=425

     

    index.php?app=core&module=attach&section=attach&attach_rel_module=post&attach_id=427

     

    Далее запускаем программу и увидим небольшие инструкции для работы. Возможностей пока мало:

    -выход по нажатию на кнопку "q" .

    -сканирование по нажатию на кнопку пробела .

    -очистка экрана по нажатию на "c".

     

    Смело нажимаем пробел и программа начнёт сканировать породу под игроком на расстояние в 20 блоков на восток. В итоге у нас получиться примерно вот такая табличка, разобраться в которой я помогу на следующих скриншотах (По оси X удаление от игрока, по Y- глубина залегания добра).

    index.php?app=core&module=attach&section=attach&attach_rel_module=post&attach_id=426

     

    А вот и обьяснение как расшифровать эту табличку:

    index.php?app=core&module=attach&section=attach&attach_rel_module=post&attach_id=428

    Рассмотрим на примере золота. Нужно сделать 5 шагов вперед от начальной точки и прокопать на глубину минимум 4 блока. Если копать до 7го блока, то мы выкопаем все ресурсы .

     

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

     

    Обьяснение скудное, но заходите в игру и покажу.

    Программу можно модифицировать разными способами. Добавить сетку привязок высот, чтобы небыло мешанины цифр. Тогда можно будет определять лавовые озера по горизонтальному скоплению "ресурсов". С успеход дописывается работа с gps, тогда отпадает необходимость работы только в сторону востока. Но gps.range() у нас на сервере всего 64 блока, поэтому уйдя далее этого расстояния необходимо отрисовывать новую карту и вставлять её в gps приемник, что очень сильно напрягает. А так бы можно было сделать визуальное и звуковое оповещение над каким блоком копать вниз и на сколько. Визуально показывать на сколько копать вниз, звуком пищать на широте и долготе залегания ресурсов. При этом сам модуль gps ставить невнутри в робта, а в контейнер для улучшений,иначе нужно будет разбирать робота чтобы поменять карту.

     

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

  19. Права и команды обычного игрока (пояснения по командам будут под списком):

    • Просмотр игровых правил (команда /rules)
    • Просмотр текущего времени (команда /time)
    • Просмотр сообщения дня MOTD (команда /motd)
    • Возврат на предыдущее место,а также на место смерти (команда /back)
    • Телепорт к себе домой (команда /home)
    • Точка телепорт "Дом" устанавливается с помощью кровати (как в обычном minecraft)
    • Доступно одно хранилище размером в 9 ячеек (обновлено 12.02.15)
    • Телепорт на спавн (команда /spawn)
    • Просмотр всех точек телепорта (команда /warp)
    • Телепорт в одну из доступных точек телепорта (команда /warp имяточки)
    • Просмотр и использование системы почты (команды /mail и /mail send)
    • Просмотр и использование системы личных сообщений (команды /msg, /w, /tell /whisper, /t, /m)
    • Использование цвета, форматирования, ссылок, множества получателей в личных сообщениях
    • Быстрый ответ на личное сообщение (команда /r)
    • Написание от 3 лица (команда /me)
    • Игнорирование игрока (его сообщений) (команда /ignore)
    • Получение набора предметов для привата (команда /kit private)
    • Просмотр границ миров (команда /wb list)

    Пояснение по командам:

    Личные сообщения: /msg игрок текст

    Быстрый ответ: /r текст

    Написание от 3 лица: /me текст

    Телепорт на точку телепорта: /warp имяточки

    Система почты: /mail read (чтение), /mail send игрок текст (отправка)

     

    Права и команды хелпера (пояснения по командам будут под списком):

    • Права обычного игрока
    • Получение набора предметов хелпера (команда /kit helper)
    • Возможность ограничить чат игроку (команда /mute)
    • Проверка игрока по IP на мультиаккаунт (команда /ipc)
    • Возможность выкинуть игрока из игры (команда /ipc kick)
    • Просмотр всех действий с блоками в игре (команда /co inspect)
    • Просмотр всех действий игрока (команда /co lookup)
    • Префикс [H]

    Пояснение по командам:

    Ограничение чата: /mute игрок время (время можно указывать в минутах,секундах,часах,днях и т.п. (например 1h 23m заблокирует чат на 1 час и 23 минуты)

    Проверка на мультиаккаунт: /ipc ник игрока

    Выкинуть игрока: /ipc kick ник причина

    Проверка действий с блоками: /co inspect и после чего ударить по блоку (подробнее тут)

    Проверка действий игрока: /co lookup (подробнее тут)

     

    Права и команды программиста:

    • Права обычного игрока
    • Доступ к наборам программистов (команды /kit programmer1 и /kit programmer2)
    • Префикс [P]

    Права и команды модератора:

    • Права хелпера
    • Доступ к набору модератора (команда /kit moderator)
    • Возможность убить игрока (команда /kill ник)
    • Проверка всех игроков онлайн на мультиаккаунт (команда /ipc scan)
    • Возможность забанить игрока (команда /ipc ban ник причина)
    • Возможность телепортироваться к игрокам (команда /tp ник)
    • Возможность телепортировать игрока к игроку (команда /tp кого куда)
    • Возможность вылечить себя (команда /heal)
    • Возможность пополнить полоску голода (команда /feed)
    • Возможность включения режима бога (команда /godmode)
    • Возможность включения режима полета (команда /fly)
    • Префикс [M]

    Права и команды администратора:

    • Все возможные права и команды
    • Префикс [A]

    P.S. если есть дополнения - пишите в комментариях

  20. 1Ridav' - блог

    • 1
      запись
    • 4
      комментария
    • 14021
      просмотр

    Последние записи

    1Ridav
    Последняя запись

    Пастбин для ОС компьютерной части на nKbGjVPw

     

    Разрабатываю удаленное управление компьютерами в игре через android/jar приложение.

    Ссылка на превью тему с андроид приложением: http://computercraft.ru/topic/347-android-opencomputers/

     

     

    API ОС части если и изменится, то крайне не существенно.

    Текущий API OC части:

     

    local br = require("bridge")

     

    br.init() - Создает соединение с мостом, позволяет использовать дальнейшие функции. Возвращает значение true/false через return. false вернется в случае неудачного соединения.

     

    br.auth("ключ в виде строки") - Производит авторизацию на мосту, позволяет найти соединение с партнером по ключу. Возращает значение true/false false вернется в случае неудачной попытки отправить ключ. Если мост найдет партнера с таким же ключем - мост пришлет сообщение CONNECTION WITH КЛЮЧ ESTABLISHED

     

    br.send("сообщение") - Посылает сообщение на мост, Если сообщение отослано нормально - вернется true через return функции. Если на мосту нет другого соединения с таким же ключом - мост пришлет сообщение I DO NOT HAVE A PAIR

     

    br.receive() - Блокирует процесс до тех пор, пока не придет сообщение от моста, возвращает два значения - true/false и message. true/false означает выполнилась ли функция нормально, message будет содержать сообщение от моста. Возможно значение nil, если соединение потеряно, даже, если первый аргумент будет true.

     

    br.finish() - Не имеет return значений, Закрывает соединение.

     

     

    Пример использования без параллельного запуска:

    local br = require("bridge")br.init() -- Соединяемся с мостомbr.auth("12345") -- Авторизируемся на мостуwhile true do   local status, message = br.receive() -- считываем ответ моста, ждем когда он найдет для нас партнера(НЕ ОБЯЗАТЕЛЬНО)   print(message)   br.send(io.read()) -- Пишем сообщение с клавиатуры и отправляем партнеру, если партнер не найден - мост об этом уведомит endbr.finish() -- ОБЯЗАТЕЛЬНО закрываем за собой соединение

  21. Гость Fenixrus
    Последняя запись

    Здравствуйте с вами Fenixrus и я начинаю серию гайдов по API мода OpenComputers.

     

    Начнем мы с Component API.

     

    Вообщем смотрим, изучаем, пробуем, комментируем!

     

    http://www.youtube.com/watch?v=hStnB3hCpFs

  22. DUIIIES ' - блог

    • 0
      записей
    • 0
      комментариев
    • 14
      просмотров

    Здесь ещё нет записей

  23. Another Brick In The Wall

    • 0
      записей
    • 0
      комментариев
    • 27
      просмотров

    Здесь ещё нет записей

×