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

Fingercomp

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

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

  • Посещение

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

    283

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


  1. // TODO: здесь будет очередная офигенная пикча от @Totoro

     

    Всё, что с хелем повязано было прямо али косвенно, перенесено успешно и без ранений. БД осталась та же, hpm не изменился. Внешне поменялся лишь только IP, на который ведёт домен hel.fomalhaut.me. Если у вас DNS-записи не имеют безумный ttl вроде 604800, разницы заметить не должны.

     

    Хотя, конечно, своё заявление я не проверял. Посему если что-то отвалилось, то прошу меня тыкнуть.

    • Нравится 2

  2. Я не пойму. Это у вас такие развлечения? Вот же, 90% процентов слово-в-слово, даже шрифт тот же самый: http://computercraft.ru/topic/1882-programma-monitoring-zhidkosti

     

    А ведь там и ответы даже есть.

     


     

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


  3. Надо понимать, что такое require. У функции есть часть сишная, которую мы проигнорируем, и часть луа. Последняя очень проста.

    • Аргумент функции мы отдаём в резолвер, который возвращает найденный по данному пути файл.
    • Файл обрабатываем через load или loadfile.

    Как видно, всё исполнение кода осуществляется лишь этими функциями (хотя есть ещё и dofile, к слову). Если интересно про них узнать, посылаю в мануал. А как практический пример рекуомендую изучить сырцы /lib/require.lua в OpenOS.


  4. @@Totoro наверное это уже будет придиркой, но интересно, а почему же эта конструкция не удаляет ссылку на переменную:

    require = require
    

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

    Для меня просто стало открытием, что это не работает в функциях.

    Хотя если бы я пользовался привычными и понятными локальными переменными, такой бы ошибки не было бы. Всё же отличная штука эти локальные переменные.

    Потому что ссылочка остаётся, разве нет? При a = a ты же не будешь ожидать, что значение куда-то внезапно пропадёт?

     

    Сборщик мусора — это умная вещь, не надо его недооценивать.

     

    А объяснение Тоторы я б хотел дополнить ещё комментарием: тело функции, заданной в форме function NAME(...) ... end, будет иметь ссылку на саму себя. Это позволяет тебе очень просто делать рекурсивные функции.

    local function fib(n)
      local function iter(acc, i)
        if i <= 0 then
          return acc
        else
          return iter(i * acc, i - 1)
        end
      end
    
      return iter(1, n)
    end
    

    Код типа local a = function() a() end уже не рекурсия: он будет проинтерпретирован как local function a() _ENV.a() end.

    Но код a = function() a() end — это _G.a = function() _G.a() end, то есть ссылочка будет. Если не будешь трогать _G.a.

     

    Что, впрочем, не означает, что рекурсия возможна только при наличии внутри функции ссылки на себя.

    local function recurse(g)
      return (function(f)
                return g(function(x)
                           return f(f)(x)
                         end)
              end)(function(f)
                     return g(function(x)
                                return f(f)(x)
                              end)
                   end)
    end
    
    print(recurse(function(rec)
                    return function(n)
                      if n == 0 then
                        return 1
                      else
                        return n * rec(n - 1)
                      end
                    end
                  end)(10))
    --> 3628800
    

    Но я надеюсь, что для тебя этот код будет тоже похож на макароны с кетчупом.


  5. Ну, я могу только поздравить с любовью к технике Apple. Это баг где-то промеж OC и видеокартой (иными словами, фиг знает где).

     

    Стандартная процедура: проверить наличие работающей видеокарты, обновлений на неё, обновлений на систему, наличие некусаного компьютера у соседа — дополняется в начале ещё одним пунктом — попробовать тыкнуть <F3-T>. Пишут, помогает.


  6. Сегодня на форуме аж две темы со странным содержанием и не соответствующими ему заголовками. Это был вопрос? Тогда, похоже, вопросительные знаки на краудсорсинг вывели. Утверждение? Но какой смысл в нём? Кто работать не будет? Почему? Что значит "проблемы с юникодом"? Какие проблемы? Это проверялось? Каким образом? Почему тогда у меня даже в OC всё прекрасно с юникодом?


  7. Я по oc.cil.li как-то не особо могу сказать, что безумно шикарно выглядит IPB 4. Фич там что-то сильно поменьше. Но апгрейд поддерживаю.

     

     

     

    можно втихаря спросить ответы у какого-нибудь игрока, уже прошедшего тест

    Можно нагуглить. Но тест, тем не менее, нужен: многие даже этого делать не могут.

    • Нравится 1

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

    rule(public) { every "10 seconds" } (function(state)
      state.counter = state.counter + 1
    end)
    

    Раскрывается оно в это:

     

     

    rule(public)({every("10 seconds")})(function(state)
      state.counter = state.counter + 1
    end)
    

     

     

     

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

    class [[public static]] "What" {
      member [[public static]] "main" (throws "IOException") (function()
        throw(new "IOException"("what."));
      end);
    }
    

    И раскрытие:

     

     

    class("public static")("What")({
      member("public static")("main")(throws "IOException")(function()
        throw(new("IOException")("what."))
      end)
    })
    

     

     

     

    Неясен тут только смысл.

    • Нравится 3

  9. # Improved chunkloader upgrade
    This PR adds a lot of features, most of which give server admins more control over the behavior of the chunkloader upgrade.
    Namely:
    
    - An option to disable a chunkloader if its owner goes offline.
    - A whitelist and a blacklist of dimensions in which the update is allowed to load chunks.
      Closes #2768.
    - An option to use the `forgeChunkLoading.cfg`'s settings to limit number of tickets per player.
    - A command that lists all chunkloaders in the world (`/oc_cl`).
    - More verbose logging (the logging level is configurable).
    - If a chunkloader is duplicated in a way so that multiple items share the same address,
      only one of them is allowed to work at a time.
    - In case a drone with the chunkloader upgrade is teleported to another dimension, it requests a new ticket.
    - Allows adapters and microcontrollers to have the chunkloader upgrade.
      Closes #2499.
    
    A new configuration group, `chunkloader`, is added with the following settings:
    
    - `requireOnline`. If `true`, the chunkloader only loads chunks if its owner is online.
      If the owner goes offline, the chunks the upgrade kept loaded are unloaded;
      the upgrade keeps consuming energy, though, and `isActive()` returns `true`.
      If the option is enabled, tickets are registered for the player, not for the mod.
    - `dimBlacklist`. The chunkloader does not load chunks in dimensions whose IDs are listed there.
    - `dimWhitelist`. This setting is the opposite of `dimBlacklist`, and lists dimensions in which the chunkloader is allowed to work.
      Ignored if left empty (so the upgrade works in all dimensions not listed in the blacklist).
      If the same entry appears in both lists, the blacklist takes precedence.
      `setActive()` returns `false` if the chunkloader is blocked in that dimension.
    - `playerTicket`. If `true`, tickets are assigned to the player who owns the chunkloader rather than the mod,
      so the `forgeChunkLoading.cfg`'s limits get applied for that player.
      Makes it impossible to activate a chunkloader not owned by a player.
    - `logLevel`. Controls the level of logging: (`0` for quiet; `1` for more verbose; `2` for debug).
    
    A new command, `/oc_chunkloaders` (`/oc_cl`), is added, which lists chunkloaders in the loaded chunks,
    and inactive registered tickets, displaying the following information:
    
    - the component address
    - the chunkloader status
      - `inactive` (the chunkloader is inactive)
      - `active` (the chunkloader is enabled, and loads chunks)
      - `active/suspend` (the chunkloader is enabled, but doesn't load chunks)
    - the block coordinates
    - the chunk coordinates
    - the dimension ID
    - the owner
    
    И может быть кто-нибудь переведёт описание на англ., а то я сомневаюсь в адекватности перевода GoogleTranslate?

    Делай PR :3

    • Нравится 2

  10. Да, форматирование — это вещь, которая в этой теме далека от златой середины. Я насчитал минимум 4 разных шрифта — зачем? Кучу пустого пространства надо оптимизировать, картинки убрать под спойлеры.

     

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

    • Нравится 1

  11. Тот код, что есть уже, тоже желательно выкладывать.

    local f, err = io.open("/home/bytes.txt", "w")
    
    if not f then
      error("could not open file for writing: " .. err)
    end
    
    f:write("Bytes don't bite.\n")
    f:close()
    
    local f, err = io.open("/home/password.txt", "r")
    
    if not f then
      error("could not open file for writing: " .. err)
    end
    
    local contents = f:read("*a")
    f:close()
    
    print("Your password is: " .. contents)
    
    • Нравится 2

  12. local internet = require("internet")
    
    local response = internet.request("http://192.168.1.100/led/1")
    
    for chunk in response do
      io.write(chunk)
    end
    
    print()
    

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


  13. Правильный ответ: никак. payonel отрубил это давным-давно из-за костылизма решения. Обратно что-то заменяющее, однако, введено не было.

     

    Можно пока эксперементировать с pcall, ибо hard interrupt (^[c) — это обычная ошибка, пущенная через error.

    • Нравится 2

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

     

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

     

    В стэктрейсе самым верхним фреймом показывается некий метод thaumcraft.common.tiles.TileAlchemyFurnaceAdvancedNozzle.getEssentiaAmount. Открываем его и переходим на указанную строку. Там вот такое:

    return (this.furnace != null ? Integer.valueOf(this.furnace.aspects.getAmount(this.furnace.aspects.getAspects()[0])) : null).intValue();
    
    Ну, то есть, что это хреновый код, понятно, но нам его прочесть нужно, так что разбавим его горсткой переводов строки.

    return (
      this.furnace != null
      ? Integer.valueOf(this.furnace.aspects.getAmount(this.furnace.aspects.getAspects()[0]))
      : null
    ).intValue();
    
    Нетрудно заметить, когда у нас здесь может возникнуть NPE. Допустим, что this.furnace == null. Тогда выражение выше преобразуется вот в такое:

    return null.intValue();
    
    Не нужно быть профи в жавве, чтобы понимать, что так вещи не работают.

     

    Значит, проблема в том, что this.furnace == null. Как туда null-то угораздило? Тоже нетрудно узнать.

     

    Во-первых, это поле класса, как мы замечаем по префиксу this., и, перейдя на объявление, находим тип поля: TileAlchemyFurnaceAdvanced. Это класс, потому вместо инстанса можно использовать null. Идиотское решение, но вот такая жавва у нас. Во-вторых, мы видим, что null там устанавливается при создании объекта класса TileAlchemyFurnaceAdvancedNozzle. То есть это дефолтное значение, проще говоря. И оно должно где-то и когда-то устанавливаться в нормальное.

     

    Ищем присвоения в это поле. Находим его в func_145845_h. Хе-хееее. Этот метод — обфусцированный update. Он вызывается игрою у всех тайлов каждый тик. Запомним, потому что знание это ещё понадобится.

     

    Этот метод всегда устанавливает не-нуллёвое значение полю, поэтому сама имплементация метода интересовать нас не будет.

     

    Отлично. Выяснили, что вместо null присваивается значение конкретное там при первом апдейте тайла. Ещё надо понять, что такое Nozzle — это штука, в которую пихается эссенция. Я не помню, где она там на печке, но где-то быть должна точно, судя по всему.

     

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

     

    Осматриваем остальную релевантную часть стэктрейса, в котором есть ещё 2 фрейма. Тааак. Некий метод TileTubeBuffer.func_145845_h, вызывающий TileTubeBuffer.fillBuffer, вызывающий TileTransvectorInterface.getEssentiaAmount, вызывающий TileAlchemyFurnaceAdvancedNozzle.getEssentiaAmount...

     

    Начинает складываться картинка проблемы.

     

    ...Нет? Не начинает? Тогда вспоминаем, что значит func_145845_h. Это, как уже замечал, есть обфусцированный update.

     

    Вот теперь-то точно начинает складываться она.

     

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

     

    Труба пытается передать эссенцию из себя в другую трубу. Та труба проверяет, сколько эссенции в подцепленном к ней блоке — трансвекторе. Трансвектор сам эссению не хранит — он перенаправляет запрос на количество эссенции печке. А печка ещё не обновлялась, поэтому this.furnace == null, и поэтому мы получаем ]NullPointerException, который успешно прикладывает сервер.

     

    У нас должен остаться один вопрос на этом моменте. Где баг?

     

    ...

     

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

     

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

     

    Как фиксить будем? А фиг мы пофиксим. Репортить некуда. Таум 4 не поддерживается уже сколько лет. Покуда мы на 1.7.10, жить нам с этой проблемой. Хотя я полагаю, что можно и как-то пропатчить жарник, пересобрать мод и провести ещё с дюжину шаманских ритуалов, но я в такое не вдавался.

     

    Возможно, можно заказать фикс. Возможно, можно что-то запретить. Но тут уж пусть решает Алекс.

     

    Зе енд.

     

    А, нет, погодите с зе ендом. Где виспы-то? Виспов тут нет. Виспы тут никоей роли не играют. Кроме, возможно, того, что @KelLiN, гоняясь с сачком и банкой за виспами, как-то так подгрузил печку, мы получили краш. Но и слава коду. Ведь виспы должны в банке жить, а не сервер крашить, верно?

     

    (Почему вёрстка едет, меня не спрашивайте. У меня все теги прикрыты корректно.)

    • Нравится 5

  15. Благодарю, но ваш код не очень, из-за того что при внедрении в мою программу либо видно только сам текст программы, кнопок не видно, либо только кнопки, но не видно программы. Помогите, буду рад c:

    А что за текст программы? Код, что ли? Но зачем видеть код во время исполнения программы?

     

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

    • Нравится 1

  16.  

     

    Извините за тонну вопросов

    Знаете, а я вот что-то тут наблюдаю абсолютный нуль вопросительных знаков. Что же, добавлю сам их несколько. Вопрос сам где — что делать-то от нас просится? Рассказать, как строки склеивать? Да пожалуйста.

    local event = require("event")
    local unicode = require("unicode")
    
    local input = ""
    
    while true do
      local chr = select(3, event.pull("key_down"))
    
      if chr == 3 or chr == 4 then
        -- got ^C or ^D; interrupt
        break
      elseif chr >= 32 then
        input = input .. unicode.char(chr)
      end
    end
    
    print(input)
    
    • Нравится 2

  17. Единственный фолдинг, который я юзаю, происходит от ФП и с этой темой не связан. Посему я не знаю, зачем оно нужно. Может кто-то пояснить? В чём смысл того, чтобы скрыть тело блока? Увидеть листинг функций удобнее через сайдбар, против длинного тела цикла помогает извлечение в функции и полоска, обозначающая scope.

     

    vZUI2Sx.png

     

    Других юзкейсов не вижу.

    • Нравится 1

  18. Всё намного проще

    component.modem.broadcast(port,io.read())

    message=event.pull("modem_message")

    Нет. У @Asior правильно (если забыть про то, что вы оба глобальные переменные юзаете). У тебя же в message будет не первая часть сообщения, а название ивента ("modem_message") всегда. Очень сомневаюсь, что именно это нужно.

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