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

Fingercomp

Гуру
  • Публикации

    1 629
  • Зарегистрирован

  • Посещение

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

    283

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


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


  2. Интересные вещи @Doob пишет. Поковырялся в коде бегло по этому поводу. Гипотеза была такая: юзер, загружая чанк с компом, получает полную инфу о блоках в этом чанке, включая NBT. Соответственно, если в NBT записывается или содержимое памяти (lua state / stack), или содержимое ФС, то можно почитать инфу.

     

    ФС, разумеется, не любая. tmpfs, насколько я понял, хранится как раз в NBT. Остальные виды ФС хранят там, похоже, только хэндлы открытые. Но Дуб про тмпфс и не говорит.

     

    Посмотрим тогда на стейт. В NBT машинки, действительно, сохраняется много всего интересного, включая юзеров, сообщение об ошибке, если есть, список компонентов и необработанных сигналов. Но луа-стейт там не хранится. Он, как и ФС, выносится в отдельный файл, держится на сервере в памяти и на клиент не передаётся. Как минимум, я не нашёл такого.

     

    Потому гипотеза не верна. Внутри кода OC найти ничего, подобного описанному Дубом, найти не смог. Пакета, который бы отсылал на клиент зачем-то содержимое луа-стейта, в коде OC тоже нет. Возможно, нужно рассматривать картинку более большую — работу MC и Forge. Но в этом я олень.

     

    Интересно было бы обсудить, что именно заставляет сервер выслать содержимое компов. Не публично, конечно. Тем более, в оффтоп ушли.

    • Нравится 2

  3. Возможно. Берём планшет с апгрейдом-поршнем, выталкиваем робота со спауна и ломаем киркой. Робот ваш.

    Если есть админка, инструкция на 2 шага короче.

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


  4. 20 минут назад, eu_tomat сказал:

    @Fingercomp, удивил. Один вопрос: как ты ухитрился разглядеть эту четверть пикселя? Или ты её чтением кода нашёл?

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

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

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

     

    "Правильную" формулу для нахождения пропорций я показывал в посте здесь. Но там я не останавливался на этом. Распишу подробнее.

     

    Сначала говорю сразу. "Правильная" пропорция измерений — chart?cht=tx&chl=%7B2%20%5Ctimes%20(16w%, где chart?cht=tx&chl=w — ширина экрана в блоках, chart?cht=tx&chl=h — высота.

     

    tjnfjkg.png

     

    Возьмём экранчик 1×1. На рисунке сверху он схематически показан. Как видно, чёрная зона, в которой показываются символы, окружена рамкой.

    • Во-первых, это голубая рамка снаружи, по которой можно судить об уровне монитора. Если мы примем длину и ширину блока равными 16 пикселей, то толщина голубой рамки составит два пикселя.
    • Во-вторых, есть ещё одна рамочка. На рисунке она показана серым, хотя на деле она тоже чёрная. Её толщина — 0.25 пикселей.

    Вторая рамка появляется потому, что содержимое экрана дополнительно смещено внутрь от голубой рамочки на 0.25 пикселя. Таким образом, вместо 4 в формуле нужно использовать 2 × (2 + 0.25) = 4.5.

     

    В посте, про который я говорил, я рассчитывал оптимальное разрешение для экрана 8×3. График из него:

     

    Tc031Rb.png

     

    Абсцисса — это разница между отношением сторон точки и нужным. Ордината — площадь в "квадратных символах" (w × h). Пропорция, которой мы добиваемся для данного сетапа, по формуле равна 494/87. Лидер на графике — 159×28. Его дельта равна ~0.000411. Она больше нуля, поэтому ширина будет забита полностью, но будет внутренняя чёрная рамка сверху и снизу. Дальше я подсчитал, что её толщина составит 1/27666 высоты внутренней области (чёрной зоны на картинке выше) — это ~0.000638 пикселя. То есть с безумной точностью всё сходится.

     

    А ниже я нарисовал график, но использовал формулу не "правильную", а ту, о которой знают больше.

     

    tawGO3x.png

     

    Разрешение 159×28, которое, вообще-то, больше всего подходит, не только имеет дельту в почти −0.05, но даже не кажется самым лучшим, затмеваемый 160×28.

     

    ...И всё-таки забавно, как много можно писать о том, как подобрать оптимальное разрешение экрана.

    • Нравится 6
    • Одобряю 1
    • Спасибо 1
    • В шоке 1

  6. Сначала нотации. Пока сам не понимаешь ошибку, другим нельзя писать, что "при выполнении ошибка". Я, конечно, пойму, что не так, но это займёт лишнее время. Сразу нужно описывать ошибку со стэком и прочим.

     

    А теперь к сути. В третьей строке лишний local. local — это объявление локальной переменной. colors.setColor(col) — это вызов функции, но не объявление локальной переменной. Поэтому local здесь невалидный.

     

    Придирки. Если функция требует число, зачем ещё раз его пропускать через tonumber?


  7. В 31.10.2019 в 19:35, hohserg сказал:

    @Fingercomp хоть бы пост сделал на форуме

    Такие проги сродни hello world: их должен велосипедить и костылять каждый сам, я считаю. Выложил в репу, чтобы не потерять. Ну, ещё там интерфейс консольный поудобнее и нет ограничения в 4 киБ.

    • В шоке 1

  8. 51 минуту назад, NEO сказал:

    @Fingercomp, как же размер озу?

    От 20 таблиц даже планка T1 не закончится. Рациональный вариант надо подбирать исходя из требуемых задач. Например, самый простой в использовании и поддержке вариант — это сериализация. Самый эффективный по памяти и размеру БД — свой формат через string.pack. И т. д.

     

    Вообще, это уже в оффтопик уходит.


  9. 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()

     


  10. 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")

     


  11. Да, в данном случае проще всего будет использовать 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)

    Как видно, спокойно можно сериализовать вложенные таблицы и затем к ним обращаться после десериализации.


  12. Файл — последовательность байтов. Кроме них ничего записать в него невозможно. Осмысленность этой последовательности придаёт формат — соглашённость о том, как представлять некий вид информации в байтах и как оттуда его считывать. В данном случае нужно подобрать формат для таблицы и записывать в нём. Так как в вопросе не дана структура этой таблицы, то могу только перечислить инструменты, которыми можно воспользоваться.

    • Либа 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

  13. Не фигачь строку по одному символу. Используй 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

  14. Обе вики не обновляются. Если хочешь что-то более-менее серьёзное делать, то читай код. В server/component, common/component находятся scala-файлы. Все методы, помеченные через @Callback, доступны из Lua-кода. Ещё стоит заглянуть в server/machine/Machine.scala, где есть методы компонента computer, integration, где лежат драйверы для разных штук из разных модов (в т. ч. OpenComputers) лежат, и в machine.lua, который запускается при старте компьютера, готовит песочницу и запускает в ней BIOS.

    Если что-то неясно, то задавай вопросы. Тут, в ирке, в дискорде — где угодно.

     

    (Когда @Asior спрашивает что-то по OpenComputers, то я обычно как раз прочитываю код и отвечаю.)

     

    Конечно, экспериментальное изучение тоже не запрещено, если не лень тыкать методы компонента (components -l robot, напоминаю).

     

    И учи английский. С гугл-переводчиком ты код не прочтёшь.

    • Одобряю 1

  15. Да, с radioegor146 мы это в ирке обсуждали пару дней. С версии 1.7.3 в OC включён коммит https://github.com/MightyPirates/OpenComputers/commit/4010927a3ee04700d80fdeade705fca885bc7c92. Пока не разобрались, что там не так, можно откатить его и собрать мод без него.


  16. Насколько я понимаю, в OpenGlasses 2 можно в очки встроить геолизатор и апгрейд навигации, после чего на стороне моста вызывать getUserLookingAt(username: string) и получать в таблице под ключами x, y, z координаты блока.

    Клик регистрируется ивентами interact_world{,_block}_{right, left}. Но, пожалуй, для интерфейса проще даже рисовать на оверлее: кликать можно курсором, как в любом другом гуи.

    • Нравится 2
×
×
  • Создать...