RccHD
-
Публикации
142 -
Зарегистрирован
-
Посещение
-
Победитель дней
13
Сообщения, опубликованные пользователем RccHD
-
-
Как можно определить(программно) точное направление, куда смотрит игрок?
Нужно определять не одну из сторон света, а именно абсолютный угол поворота игрока.
Есть ли для этого какой-то блок-детектор в аддонах? -
@@RccHD, транспозер и подобные механизмы не могут взаимодействовать с системником?
Если подключать транспозер к системнику, то придется освобождать слот для диска и как-то следить за тем, чтобы транспозер не начал использовать для работы в сети наш основной диск с ОС
-
Го так с жесткими дисками
Это труднее, т.к. для них не предусмотрено специального блока-контейнера, которых может их считывать
-
Раннее я уже делал обзор того, как можно пересылать данные по сундуку из EnderStorage
Получилось неплохо: 12 байт в секунду
Но в какой-то момент стало понятно, что 12 байт в секунду - это очень маленькая скорость передачи, поэтому я решил попробовать увеличить это значение
И у меня получилось! Теперь ender-net передает данные в 42666 раз быстрее(на самом деле можно увеличить скорость передачи до космических значений, можно сделать в 42666*27 раз быстрее, но мне лень). Неплохая прибавка к скорости, я считаю!Я бы уже давно реализовал систему именно с такой скоростью передачи данных, если бы я мог видеть очевидные вещи сразу.
А очевидная вещь вот какая: зачем кодировать данные стаками блоков если есть ДИСКЕТЫ!!! Это настолько очевидно! Дискеты вмещают 512КБ данных, поэтому я решил использовать их для отправки сообщений.
В обновленной версии ender-net теперь понадобится дисковод для считывания данных
Вот так выглядит комп, подключенный к сети(при подключении к сети дискета обязательно должна быть вставлена в дисковод)
Вот так выглядят компы, подключенные к одной сети
*ДЕМКА*
В настоящий момент система с багами и вообще еще не доработана. Может быть потом выложу ссылку на доработанную библиотеку в комменты.
Я написал демо-скрипт test-ender-net.lua, который осуществляет пересылку сообщений между участниками сети.
Пусть у нас есть 3 компа:
Запустим на одном из них скрипт test-ender-net.lua
Сеть определила адрес КОМПА -- 4
Теперь пойдем к другим двум компам и на каждом запустим этот же скрипт.
Для двух других компов выбраны адреса 6 и 8
Пойдем к компу 4 и напишем с этого компа сообщение на комп 8
Потом пойдем к компу 6 и тоже что-нибудь напишем компу под номером 8 (пикчи нет)
Теперь пойдем к компу номер 8 и ответим компу номер 6 "хватит спамить!"
Если подойти к компу номер 6, будет видно что пришло сообщение

Получилось что-то вроде чатика.
Вот в общем-то и все. Если кого-то заинтересовала эта тема, то я могу постараться допилить библиотеку ender-net чтобы не было никаких багов в работе сети.
Чтобы поближе посмотреть, как работает ender-net через дискеты, скачайте мое сохранение с компами и потестите. (Я там пару подсказок оставил на экранах мониторов). Нужно распокавать архив и положить папку "comp" в папку с сохранениями игры
Ссылка: https://www.dropbox.com/s/0h1kc0dhc6vew78/comp.zip?dl=0Ссылки на библиотеки и другие скрипты не буду выкладывать, пока не доработаю ender-net
ИТОГИГлавное отличие ender-net от сети на связанных картах: возможность соединить в одну сеть более чем 2 компа.
Преимущества: почти не тратит энергию, очень быстрая скорость передачи данных.
Недостатки: возможны баги
Забавная особенность: при частом обмене сообщениями дисковод издает просто дьявольские звуки, транспозер пищит, а комп мигает!
-
5
-
-
Трудности появятся при масштабировании производства.Гораздо чаще возникает ситуация, когда 15 датчиков посылают данные на один пульт. И в этом случае твоя схема увеличивается в 15 раз. Каждый новый датчик потребует для себя постройки не только передатчика с сундуком, но и приемника в каждой точке приема. В результате твоя система обмена данными будет занимать места больше, чем обслуживаемые ею механизмы. Настройка такой системы тоже отнимет много времени.
Вот и нет. Ты видимо неправильно понял устройство моей сети.
Потому что на самом деле не нужно ставить 15 приемников в точке приема. Достаточно в каждой точке сети поставить ОДИН комп + 1 сундук. А все потому что любой участник сети может и принимать и отправлять сообщения одновременно.
Если два участника вызвали функцию отправки запроса одновременно, то они встанут в очередь, это я продумал
-
Берем несколько сундуков, закладываем в них 255 разных ресурсов.
Для передачи информации, переносим ресурсы в эндерчест, по заранее созданной таблице соответствий (синхронизировать можно при старте).
Получаем 53 байта за раз, следовательно, можно жать информацию, бить на блоки по 53 байта и передавать без особых извращений.
изначально так и хотел делать, но потом понял что сложно это и решил для начала сделать вариант попроще и постабильнее
-
А практическая значимость всего этого действа есть или все в ОС это FUN?

Практическая значимость есть...
Если нужно разослать "легкую" информацию по 15 точкам на огромном удалении друг от друга можно выбрать один из двух вариантов:
1) Обеспечить к каждой точке приток большого кол-ва EU + скрафтить к каждой точке по паре связанных сетевых карт(для которых как раз и была подведена EU).
Плюс ко всему надо будет писать софт для пересылки сообщения между несвязанными между собой картами. Сеть получится централизированная.
Задача решена
2) Либо можно установить на каждый комп ender-net + 1 генератор на угле. Задача тоже решена.
Итог:
A) меньше заморочек с получением EU.
B) получилась нецентрализированная сеть, и если у кого-то в сети сломается комп(не важно у кого), то сеть не перестанет функционировать
-
Вот то же самое хотел посоветовать. Это позволит передавать с максимальной скоростью и даёт 100% шанс, что сообщение было получено, что очень важно.
Изначально я реализовывал обмен сообщениями по ender-net в виде broadcast-рассылки. При рассылках обычно не определяют дошло письмо или нет, так как кто-то просто рассылает, и его не волнует успел кто-то прочитать посланное сообщение или нет.
Но вот как нам определить что сообщение было получено если в нашей ender-сети 15 участников? Выделить 15 слотов под это дело? Или делать инкрементный счетчик от 0 до 14? А что делать если кусок сети просто отвалился и не реагирует?
Я все это пишу к тому, что рассылать сообщения по принципу broadcast гораздо проще, и тогда не важно кто прочитал, а кто нет. Если кто-то не успевает читать сообщения, пусть увеличивает TPS в своей зоне, убирает бесполезных мобов с территории, либо договаривается об увеличении TIMEOUT'а
Плюс ко всему на основе ender-net можно городить свои протоколы и способы обмена информацией: можно сделать подтверждение о том, что сообщение было получено в виде ответного ender_net.sendMessage, в качестве кода сообщения указать 50(код, который означает что сообщение дошло до получателя), а в качестве самого сообщения указать ID сообщения, которое было получено
-
Для тех, кому лень искать все ссылки на файлы:
Библиотека ender-net:
pastebin get qYiQWtb0 /lib/ender-net.lua
Простой 'слушатель' сообщений сети
https://pastebin.com/x6GyEynm
Драйвер передачи файлов
base64(необходимая библиотека) - pastebin get 0xDgW35R /lib/ender-net-base64.lua
Драйвер состоит из двух программ
1) waitFile.lua (установить можно командой pastebin get aD20ZF4q /bin/waitFile.lua)
2) sendFile.lua (установить можно командой pastebin get wHA6QzH6 /bin/sendFile.lua) -
Передавать информацию на любое расстояние и в любые измерения гораздо удобнее с помощью связанной карты. Работает быстро, программируется просто, используется легко.
Связанные карты нельзя связать в целостную сеть без серверных стоек(или роутеров) и без написания доп. кода к ним
Представь ситуацию, когда информация о температуре реактора должна рассылаться в 15 точек одновременно.
В таком случае нам понадобится аж 30 связанных карт + придется потратить энергии на 15 запросов(а они у связанных карт недешевые в плане энергии). А ведь нам всего лишь нужно переслать одно жалкое число и ничего более
Вот чтобы не тратиться на сетевые карты и не обеспечивать к каждому компу сети большое кол-во энергии, можно использовать ender-net
Я конечно не спорю, что связанные карты удобнее, но для таких мелочных операций как пересылка чисел более чем одному получателю они не совсем подходят. В таких случаях я бы предпочел ender-net -
Ой, вот зря я загрузил пикчи на сервера ВКонтакте
Надо было на битбакет загрузить
Вечером ссылки поменяю
-
Кто-то уже пробовал в одиночной игре в креативе тестировать эту систему?
Какие баги возникали?
-
Если запустить передачу файла и в этот момент посмотреть в эндер-сундук компа, то можно залипнуть на пару минут
Завораживает
-
Передача данных по EnderStorage-сундуку
Важно:
В статье идет речь именно о сундуках из мода EnderStorage, а не о ванилла-эндерсундуках
Сундуки из EnderStorage могут быть очень полезны не только потому что с их помощью можно иметь доступ к хранилищу ресурсов находясь на большом расстоянии от дома(или вообще в другом измерении), но и потому, что существует возможность передавать информацию на любое расстояние используя эти сундуки.
Дело в том, что есть способ 'синхронизировать' несколько сундуков(достаточно покрасить полоски этих сундуков в одинаковые цвета), и тогда эти сундуки будут иметь общее хранилище и ресурсы положенные сундук моментально окажутся во в остальных сундуках 'синхронизированных' с этим сундуком.
Используя данные о том, сколько предметов лежит в том или ином слоте сундука можно получать информацию. Например, если в первый трех слотах лежит 30, 24 и 58 камня, то компьютер сможет "прочитать" из этого сундука ровно 3 числа - 30, 24, 58
Меняя количество предметов в разных слотах, можно "отправлять" информацию.
Пример:
1) компьютер№1 положил в первые 4 слота по 10, 0, 1, 63 камня
2) через некоторое время компьютер№2 прочитал из сундука числа 10, 0, 1, 63
ИТОГ: компьютер№1 передал компьютеру№2 4 числа
Важное условие: сундуки у компьютера№1 и у компьютера№2 должны быть синхронизированы, т.е. иметь одинаковые цвета полос, чанки должны быть прогруженыДалее я буду описывать свою систему для обмена данными, построенную на связанных эндер-сундуках
Для начала нам нужно построить вот такую конструкцию:
Важное условие: транспозер ОБЯЗАТЕЛЬНО должен находиться под эндер-сундуком, а адаптер может быть подсоединен к любой из оставшихся сторон сундука
Подключаем все это дело к компьютеру:
Подобная конструкция(эндер-сундук, адаптер, транспозер) должна быть присоеденена к каждому компу, который участвует(или будет участвовать) в обмене данными
Далее открываем эндер-сундук и заполняем первые 27 слотов любыми блоками в количестве 64 штуки
ЕСЛИ ЭТО НЕ СДЕЛАТЬ ИЛИ ПОЛОЖИТЬ 26 СТАКОВ ВМЕСТО 27, ТО СИСТЕМА РАБОТАТЬ НЕ БУДЕТ
На этом настройка системы заканчивается, теперь нужно скачать исходный код моей библиотеки ender-net.lua:pastebin get qYiQWtb0 /lib/ender-net.lua
Документация библиотеки ender-net:sendMessage(msgCode, message, timeout): nil
msgCode - код сообщения
message - может быть либо числом от 0 до 64^23 либо таблицей из чисел
timeout - время, которое дается другим узлам сети, чтобы прочесть переданное сообщение(не рекомендуется указывать меньше 0.2)
pullMessage(): messageRecieved, messageCode, message
messageRecieved - true если пришло новое сообщение, false если новое сообщение не пришло
messageCode - код сообщения, переданный в sendMessage()
message - сообщение, переданное в sendMessage()
maxMessageSize - максимальная длина сообщения(кол-во передаваемых чисел)
Главное правило пользования этой системой: не лезть руками в сундук во время передачи/отправки сообщений, иначе все сломается нафиг
Простейший(базовый) пример использования сети
Для демонстрации возможностей этой сети я написал парочку программ
Начнем с самой простой: listen.lua ( https://pastebin.com/x6GyEynm )
Запустим эту программу на одном из компов, который является частью сети(т.е. подключен к эндер-сундуку через адаптер и транспозер):
Теперь пойдем к другому компу и попытаемся обменяться сообщениями:
И теперь вернемся туда, где мы запускали listen:
Все сообщения переданы!
Для того чтобы подробнее понять как были переданы сообщения откроем эндер-сундук:
Здесь мы увидим числа, которые были последними переданы по сети(а именно 10, 11 и 12) а также код сообщения(56):
Слоты сундука:
Отправленное сообщение:
Мы можем передавать по такой сети короткие сообщения(24 числа = 1 число на msgType и 23 числа на message)
Но что нам делать, если мы хотим передать по этой сети файл в несколько килобайт?
Для этого нужно писать сетевые драйвера с конвертацией передаваемых данных в числа от 1 до 64 (формат base64) и разбиением ваших данных на части по 24 числа в каждой.
Чтобы моя разработка не оставалась совсем-уж бесполезной( стандартные возможности сети позволяют передавать всего лишь 24 числа за сообщение ) я решил написать для нее сетевой драйвер передачи файловОписание драйвера для передачи файлов
Важно: Для работы драйвера необходимо установить библиотеку base64:pastebin get 0xDgW35R /lib/ender-net-base64.lua
Драйвер состоит из двух программ
1) waitFile.lua (установить можно командой pastebin get aD20ZF4q /bin/waitFile.lua)
2) sendFile.lua (установить можно командой pastebin get wHA6QzH6 /bin/sendFile.lua)
Использование:waitFile <fileName>
Ожидает пока кто-то начнет передавать файл по сети. После окончания передачи файл будет сохранен под именем <fileName>. fileName - абсолютный путьsendFile <fileName>
Передает файл <fileName> другим участникам сети. fileName - абсолютный путь
Пример:
Предположим, мы хотим передать файл /home/secret.txt с компа1 на комп2 и сохранить полученный файл под именем /home/hehehe.txt на компе2
Все просто:
1) Идем к компу2 и запустив команду "waitFile /home/hehehe.txt" заставляем его ждать, пока по сети придет файл hehehe.txt
2) Идем к компу1 и отправляем файл secret.txt в нашу сеть. Для этого пишем команду "sendFile /home/secret.txt"
Как только выполнили оба шага в правильной последовательности, комп1 начнет посылать сообщения в сеть, а комп2 будет их принимать
Передача файла размером 299 байт заняла около 30 секунд:
Как мы можем видеть, файл действительно передан с одного компа на другой
Итог всей этой статьи
Используя мою библиотеку ender-net вы сможете передавать данные по сети, основанной на эндер-сундуках
Данные эти должны иметь маленький размер(помещаться в 24 числа), иначе придется ломать голову над созданием сетевого дравера
Эта сеть подойдет для обмена числами между двумя компами(пример: мониторинг температуры реакторов, которые находятся ОЧЕНЬ далеко)
Положительные стороны ender-net:
1) передача данных куда угодно, на какое угодно расстояние, даже между измерениями
2) передача данных с помощью ender-net практически не тратит энергию, в то время как связанные сетевые карты из OpenComputers тратят очень много
3) в сеть возможно подключить более чем двух участников и делать рассылку каких-нибудь сообщений
Недостатки:
1) Недостаточная для некоторых задач скорость передачи данных ( 10-12 байт в секунду )
2) Дороговизна, т.к. придется тратиться на эндер-сундук, транспозер и адаптер
3) Библиотека ender-net еще не доведена да совершенства, поэтому возможны баги
Окончательный итог: получился крутой эксперимент с эндер-сундуками, но пока трудно организовать обмен полноценными сообщениями используя библиотеку ender-net-
11
-

Библиотека для создания классов в Lua
в Библиотеки
Опубликовано: · Изменено пользователем RccHD
Предисловие
Во многих языках программирования классы включены в стандартную реализацию. Однако Lua настолько минималистичен, что по умолчанию классов в нем нет. Но нам ничего не мешает реализовать классы используя стандартные возможности языка. В моей реализации классы реализованы через замыкания.
Описание моей библиотеки
Здесь особо описывать нечего, поэтому я просто приложил примеры кода( комментарии обязательны к прочтению! )
1. Создание класса
local Class = require("class") -- Класс для точки в 2д пространстве local Point2d = Class({ -- Конструктор класса __init__ = function(self, x, y) self.x, self.y = x, y end, -- Методы класса -- Примечание: -- аргументы каждого метода класса обязательно -- должны начинаться с "self" (ну, либо с "this" или "it", кому как угодно) printCoords = function(self) print("X = ".. self.x .."; Y = ".. self.y) end }) -- Создание экземпляра класса Point2d local p1 = Point2d(5, 11) -- Вызов метода p1.printCoords() -- Выведет "X = 5; Y = 11" local p2 = Point2d(p1.x * 2, p1.y * 2) p2.printCoords() -- Выведет "X = 10; Y = 22"2. Ты ведь не забыл про наследования?!
Я не очень люблю нагромождать свой код зависимостями, а потом постоянно ломать голову мыслями "А от чего у меня унаследован вот этот класс? От какого именно класса у меня унаследован этот метод? Почему одно наследование перекрывает другое? "
Поэтому я реализовал возможность выборочно унаследовать необходимый метод у конкретного класса, так как такой способ наследования тупо проще, понятнее, и лишний раз не нагружает разум программиста адскими зависимостями между классами.
Простой пример:
local Class = require("class") -- Класс для точки в 2д пространстве local Point2d, Point2d_prototype = Class({ __init__ = function(self, x, y) self.x, self.y = x, y end, printCoords = function(self) print("X = ".. self.x .."; Y = ".. self.y) end }) local Player = Class({ __init__ = function(self, x, y, ...) self.x, self.y = x, y self.otherInfo = ... end, -- Унаследуем метод "printCoords" у класса Point2d -- Для этого обратимся к *прототипу* этого метода и получим наследуемый метод по имени printCoords = Point2d_prototype.printCoords }) -- Создание экземпляра класса Point2d local point = Point2d(5, 11) -- Вызов метода point.printCoords() -- Выведет "X = 5; Y = 11" local player = Player(4, 2, "RccHD") player.printCoords() -- Выведет "X = 4; Y = 2"Исходники библиотеки
Библиотека получилась совсем небольшой, поэтому вы можете скопировать исходник прямо из этой статьи:
Либо скачать с pastebin ( https://pastebin.com/WVxaHb4Y )
class.lua :
local prepareObj prepareObj = function(root, obj, proto, mt) for k, v in pairs(proto) do local t = type(v) if t == "table" and k ~= "__proto__" and k ~= "__root__" then obj[k] = prepareObj(root, { __proto__ = v, __root__ = root }, v, mt) end end setmetatable(obj, mt) return obj end local classMt = { __index = function(self, key) local v = self.__proto__[key] if type(v) == "function" then return function(...) return v(self.__root__, ...) end else return v end end } return function(proto) proto.__new__ = function(...) local obj = { __proto__ = proto } obj.__root__ = prepareObj(obj, obj, proto, classMt) if proto.__init__ ~= nil then proto.__init__(obj.__root__, ...) end return obj end return proto.__new__, proto endДля того, чтобы начать использовать классы в своих программах нужно положить файл class.lua в папку рядом со своими программами (или в /usr/lib , но лучше не надо)
После этого импортируйте библиотеку написав в своем коде вот это:
local Class = require("class")И помните: важно не количество кода, а его качество!