Fingercomp
-
Публикации
1 629 -
Зарегистрирован
-
Посещение
-
Победитель дней
283
Сообщения, опубликованные пользователем Fingercomp
-
-
OpenComputers, если и позволяет почувствовать отдельным личностям суперхакером, не только не позволяет ничего взломать, но, если сравнивать с ComputerCraft, ещё более озабочен быть мягким и пушистым модом. Если нет опки, если нет командного блока, если не включена дебаг карта или драйвер для командного блока, то о никаких читах речи быть и не может.
-
Интересные вещи @Doob пишет. Поковырялся в коде бегло по этому поводу. Гипотеза была такая: юзер, загружая чанк с компом, получает полную инфу о блоках в этом чанке, включая NBT. Соответственно, если в NBT записывается или содержимое памяти (lua state / stack), или содержимое ФС, то можно почитать инфу.
ФС, разумеется, не любая. tmpfs, насколько я понял, хранится как раз в NBT. Остальные виды ФС хранят там, похоже, только хэндлы открытые. Но Дуб про тмпфс и не говорит.
Посмотрим тогда на стейт. В NBT машинки, действительно, сохраняется много всего интересного, включая юзеров, сообщение об ошибке, если есть, список компонентов и необработанных сигналов. Но луа-стейт там не хранится. Он, как и ФС, выносится в отдельный файл, держится на сервере в памяти и на клиент не передаётся. Как минимум, я не нашёл такого.
Потому гипотеза не верна. Внутри кода OC найти ничего, подобного описанному Дубом, найти не смог. Пакета, который бы отсылал на клиент зачем-то содержимое луа-стейта, в коде OC тоже нет. Возможно, нужно рассматривать картинку более большую — работу MC и Forge. Но в этом я олень.
Интересно было бы обсудить, что именно заставляет сервер выслать содержимое компов. Не публично, конечно. Тем более, в оффтоп ушли.
-
2
-
-
Для интересующихся историей, тот самый поучительный рассказ.
-
1
-
1
-
-
14 часа назад, eu_tomat сказал:А роботы разве выталкиваются поршнями?
А, кстати, точно, скорее всего, они ещё и не выталкиваются. Ну, тогда ответ ещё проще становится.
-
Возможно. Берём планшет с апгрейдом-поршнем, выталкиваем робота со спауна и ломаем киркой. Робот ваш.
Если есть админка, инструкция на 2 шага короче.
Через беспроводной модем, редстоун и прочее робота утащить можно, только если автор так захочет. Достаточно проверки отправителя сообщения, чтобы быть неуязвимым.
-
20 минут назад, eu_tomat сказал:@Fingercomp, удивил. Один вопрос: как ты ухитрился разглядеть эту четверть пикселя? Или ты её чтением кода нашёл?
Если экран полностью заполнить чем-то ярким, то довольно просто увидеть, что начинается не сразу внутри границы синей рамочки, а с небольшим отступом. А дальше остаётся просто пролистать код рендерера и найти размер отступа этого.
-
2
-
1
-
-
Стоит ещё отметить, что ни один гайд или программа, которые бы мне известны были, не до конца учитывают отображение монитора, и находимые разрешения не идеальны, хотя обычно несущественно.
"Правильную" формулу для нахождения пропорций я показывал в посте здесь. Но там я не останавливался на этом. Распишу подробнее.
Сначала говорю сразу. "Правильная" пропорция измерений —
, где
— ширина экрана в блоках,
— высота.
Возьмём экранчик 1×1. На рисунке сверху он схематически показан. Как видно, чёрная зона, в которой показываются символы, окружена рамкой.
- Во-первых, это голубая рамка снаружи, по которой можно судить об уровне монитора. Если мы примем длину и ширину блока равными 16 пикселей, то толщина голубой рамки составит два пикселя.
- Во-вторых, есть ещё одна рамочка. На рисунке она показана серым, хотя на деле она тоже чёрная. Её толщина — 0.25 пикселей.
Вторая рамка появляется потому, что содержимое экрана дополнительно смещено внутрь от голубой рамочки на 0.25 пикселя. Таким образом, вместо 4 в формуле нужно использовать 2 × (2 + 0.25) = 4.5.
В посте, про который я говорил, я рассчитывал оптимальное разрешение для экрана 8×3. График из него:
Абсцисса — это разница между отношением сторон точки и нужным. Ордината — площадь в "квадратных символах" (w × h). Пропорция, которой мы добиваемся для данного сетапа, по формуле равна 494/87. Лидер на графике — 159×28. Его дельта равна ~0.000411. Она больше нуля, поэтому ширина будет забита полностью, но будет внутренняя чёрная рамка сверху и снизу. Дальше я подсчитал, что её толщина составит 1/27666 высоты внутренней области (чёрной зоны на картинке выше) — это ~0.000638 пикселя. То есть с безумной точностью всё сходится.
А ниже я нарисовал график, но использовал формулу не "правильную", а ту, о которой знают больше.
Разрешение 159×28, которое, вообще-то, больше всего подходит, не только имеет дельту в почти −0.05, но даже не кажется самым лучшим, затмеваемый 160×28.
...И всё-таки забавно, как много можно писать о том, как подобрать оптимальное разрешение экрана.
-
6
-
1
-
1
-
1
-
Сначала нотации. Пока сам не понимаешь ошибку, другим нельзя писать, что "при выполнении ошибка". Я, конечно, пойму, что не так, но это займёт лишнее время. Сразу нужно описывать ошибку со стэком и прочим.
А теперь к сути. В третьей строке лишний local. local — это объявление локальной переменной. colors.setColor(col) — это вызов функции, но не объявление локальной переменной. Поэтому local здесь невалидный.
Придирки. Если функция требует число, зачем ещё раз его пропускать через tonumber?
-
tmpfs — это тоже filesystem. И да, список может поменяться на каждом ребуте.
-
1
-
-
2 часа назад, eu_tomat сказал:Что вирусного в этой программе?
Картинка с восклицательным знаком.
-
1
-
2
-
-
В 31.10.2019 в 19:35, hohserg сказал:@Fingercomp хоть бы пост сделал на форуме
Такие проги сродни hello world: их должен велосипедить и костылять каждый сам, я считаю. Выложил в репу, чтобы не потерять. Ну, ещё там интерфейс консольный поудобнее и нет ограничения в 4 киБ.
-
1
-
-
3 часа назад, eu_tomat сказал:А как можно "запороть" файл?
Кодить код вне git-репозитория.
-
2
-
1
-
-
51 минуту назад, NEO сказал:@Fingercomp, как же размер озу?
От 20 таблиц даже планка T1 не закончится. Рациональный вариант надо подбирать исходя из требуемых задач. Например, самый простой в использовании и поддержке вариант — это сериализация. Самый эффективный по памяти и размеру БД — свой формат через string.pack. И т. д.
Вообще, это уже в оффтопик уходит.
-
1 час назад, Teen_Romance сказал:@Fingercomp проблема в том, что каждый раз когда я буду запускать программу, я буду записывать только 1 таблицу в файл. Как мне все их поместить в 1 таблицу в файл в который я записываю ?
Прочесть весь файл, десериализовать всю таблицу, добавить новое значение, сериализовать обратно и перезаписать.
local srl = require("serialization") local f = io.open(path, "r") local tbls = srl.deserialize(f:read("*a")) f:close() table.insert(tbls, {...}) -- если внезапно вылетит ошибка здесь, файл не будет потёрт local serialized = srl.serialize(tbls) local f = io.open(path, "w") f:write(serialized) f:close()
-
1 час назад, Teen_Romance сказал:Что такое "*a" и как оно рассчитывается?
Это параметр, который говорит прочитать всё из файла.
1 час назад, Teen_Romance сказал:И подскажите пожалуйста, как мне из 20 таблиц определить нужную мне? Я писал выше, что насколько я понял, мне нужно знать промежуток байтов в которых записана таблица? Или как?
Нет, зачем? Достаточно поместить все таблицы в одну и её уже сериализовать. А искать можно и линейным поиском.
local itemToCraft = {id = "IC2:blockGenerator", dmg = 3} local tbls = srl.unserialize(f:read("*a")) local recipe for _, tbl in pairs(tbls) do if (tbl.craft.id == itemToCraft.id and tbl.craft.dmg == itemToCraft.dmg) then recipe = tbl break end end assert(recipe, "recipe not found")
-
Да, в данном случае проще всего будет использовать serialization. Только вот использование некорректное.
local srl = require("serialization") local solar = { craft = {id = "IC2:blockGenerator", dmg = 3}; {id = "minecraft:cobblestone", dmg = 0, qty = 11}, {id="IC2:itemIngot", dmg = 1, qty = 3}, {id="minecraft:coal", dmg = 0, qty = 3}, {id="minecraft:redstone", dmg = 0, qty = 6}, {id="IC2:itemRubber", dmg = 0, qty = 13}, {id="IC2:itemIngot", dmg = 0, qty = 4}, {id="minecraft:iron_ingot", dmg = 0, qty = 10} } -- Запись local f = io.open("/tmp/recipe.tbl", "w") f:write(srl.serialize(solar)) f:close() -- Чтение local f = io.open("/tmp/recipe.tbl", "r") local tbl = srl.unserialize(f:read("*a")) f:close() print(tbl.craft.id, tbl.craft.dmg) print(tbl[2].id, tbl[2].dmg, tbl[2].qty)
Как видно, спокойно можно сериализовать вложенные таблицы и затем к ним обращаться после десериализации.
-
Файл — последовательность байтов. Кроме них ничего записать в него невозможно. Осмысленность этой последовательности придаёт формат — соглашённость о том, как представлять некий вид информации в байтах и как оттуда его считывать. В данном случае нужно подобрать формат для таблицы и записывать в нём. Так как в вопросе не дана структура этой таблицы, то могу только перечислить инструменты, которыми можно воспользоваться.
- Либа serialization (OpenOS). Сериализует таблицу и десериализует в таблицу назад.
- Функции string.pack и string.unpack. Первая по строке-формату пакует данные в строку, вторая их извлекает.
- Функции string.char и string.byte. Первая создаёт строку с байтом, значение которого равно переданному; вторая возвращает значения байтов, из которых состоит строка.
- Функции string.gsub, string.gmatch, string.find, string.match. Для поиска по шаблону.
Прошу описать структуру содержимого таблицы, чтобы помочь подобрать правильный инструмент.
Кроме того, чтобы файл не переписывать с нуля, а дописывать с конца, нужно использовать io.open(path, "a") (от append).
-
1
-
1
-
Не фигачь строку по одному символу. Используй string.find, чтобы найти позицию последовательности смены цвета. Паттерн — "%[0x(%x%x%x%x%x%x)]". Вернёт позицию начала, конца и цвет.
local unicode = require("unicode") local s = "test[0x123456]testtest[0x654321]spameggs" local pattern = "%[0x(%x%x%x%x%x%x)]" local begin = 1 local x, y = 1, 1 while true do local b, e, color = s:find(pattern, begin) local precedingString = s:sub(begin, b and (b - 1)) if precedingString then gpu.set(x, y, precedingString) x = x + unicode.wlen(precedingString) end if not color then break end gpu.setForeground(tonumber(color, 16)) begin = e + 1 end-
4
-
2
-
-
Обе вики не обновляются. Если хочешь что-то более-менее серьёзное делать, то читай код. В server/component, common/component находятся scala-файлы. Все методы, помеченные через @Callback, доступны из Lua-кода. Ещё стоит заглянуть в server/machine/Machine.scala, где есть методы компонента computer, integration, где лежат драйверы для разных штук из разных модов (в т. ч. OpenComputers) лежат, и в machine.lua, который запускается при старте компьютера, готовит песочницу и запускает в ней BIOS.
Если что-то неясно, то задавай вопросы. Тут, в ирке, в дискорде — где угодно.
(Когда @Asior спрашивает что-то по OpenComputers, то я обычно как раз прочитываю код и отвечаю.)
Конечно, экспериментальное изучение тоже не запрещено, если не лень тыкать методы компонента (components -l robot, напоминаю).
И учи английский. С гугл-переводчиком ты код не прочтёшь.
-
1
-
-
Да, с radioegor146 мы это в ирке обсуждали пару дней. С версии 1.7.3 в OC включён коммит https://github.com/MightyPirates/OpenComputers/commit/4010927a3ee04700d80fdeade705fca885bc7c92. Пока не разобрались, что там не так, можно откатить его и собрать мод без него.
-
Насколько я понимаю, в OpenGlasses 2 можно в очки встроить геолизатор и апгрейд навигации, после чего на стороне моста вызывать getUserLookingAt(username: string) и получать в таблице под ключами x, y, z координаты блока.
Клик регистрируется ивентами interact_world{,_block}_{right, left}. Но, пожалуй, для интерфейса проще даже рисовать на оверлее: кликать можно курсором, как в любом другом гуи.
-
2
-
-
Ограничение памяти можно осуществить и в ванильном луа, если сделать свой аллокатор и передать его луа (она это умеет, что очень её красит). Персистентность из Eris для этого не нужна.
-
2
-
1
-
-
Извините за скептицизм. Я не особо понял, чем эта тема от
отличается. И вообще, надо какие-то действия дальше подбора лого и имени делать: код писать, спеки делать; пустые идеи ничего не стоят.
-
Логирование можно и в ванильном OC сделать, если в сэндбокс пропустить print из machine.lua. Но да, отдельный интерфейс был бы полезен. Дебаггер, профилятор и что там ещё на свете ни придумали.

Перекладывание стаков
в Помогите найти ошибку
Опубликовано:
Компонента "crafting" нет.