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

ProgramCrafter

Пользователи
  • Публикации

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

  • Посещение

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

    41

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


  1. 15 минут назад, Teen_Romance сказал:

    /lib/<name>.lua

    Вроде бы лучше библиотеки складывать в /usr/lib/<name>.lua, но это так, просто для красоты.

     

    13 минуты назад, Teen_Romance сказал:

    Я не понимаю, новые библиотеки тоже кешируются или только те что указаны?

    Новые тоже.

     

    13 минуты назад, Teen_Romance сказал:

    Если новые тоже кешируются, что вероятно, то как это офнуть?

    Офнуть проблематично, для этого надо (и надо бы, кстати) переписать require.

    А выбросить библиотеку из кеша можно так: package.loaded[<name>] = nil


  2. @rootmaster

     

    А что насчёт

    В 14.04.2022 в 22:50, Taoshi сказал:

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

    а желательно и возможности посмотреть на код, не устанавливая его никуда?


  3. 4 часа назад, Progger_coder сказал:

    это надо несколько раз сканировать, и брать среднее значение?

    Можно, но есть более интересный метод, его можно здесь посмотреть:

     

    Вкратце: добавляемый OC шум может иметь только 256 разных значений. Можно перебрать плотность блока, вычислить, какой шум был добавлен, из этого получить тот байт, который для добавления шума используется. Если этот "байт" не целый или не лежит в интервале [-128; 128), то мы не угадали, и надо проверять какую-то другую плотность.

     

    P.S.

    4 часа назад, Progger_coder сказал:

    А вот скриншот просканированной пещеры

    На мой вкус, стоило бы сделать какой-то ровный фон, вроде угля, глины или чего-то подобного. Но это уже мелочи :)

    • Нравится 1
    • Одобряю 1

  4. 1 час назад, prop сказал:

    Без опыта работы и конкретного указания проектов Middle Programmer выглядит странно

    Так это и не резюме (как минимум, пока что).

     

    1 час назад, prop сказал:

    Так ведь есть уже

    Посмотрел, увидел, что компилирует только C/C++/что-то в LLVM, закрыл :). Хотя, мб, можно линукс перегнать в такой формат. Но надо ещё разбираться, как используемые регистры у x86 соответствуют моим.

    Вообще, псевдокод, который я транслирую в movasm, по синтаксису питон, а по используемым функциям - странная смесь C++, раста и, конечно, самого питона.

     

    Например, аллокатор, который я сейчас пишу (да, здесь могут быть баги и тому подобное):

    _static_alloc = 1024
    
    def _static_allocate(size):
      _static_alloc += size
      return _static_alloc - size
    
    def _static_deallocate(p): pass
    
    _alloc_cl_first = _static_allocate(4)
    _alloc_cl_first->first = 1048575
    
    def _list_ins_between(L: *list_node,
        R: *list_node, u: pair<size_t, size_t>):
      v = _static_allocate(4)
      v->first = u.first
      v->second = u.second
      v->third = R
      v->fourth = L
      if L: L->third = v
      if R: R->fourth = v
      return v
    
    ...

     


  5. 3 часа назад, ProgramCrafter сказал:

    теории конечных автоматов с изменяющимися правилами ещё никто не создавал

    Опс, я понял: если взять в качестве состояния не только текущую вершину, но и набор существующих на данный момент рёбер, то получится не менее конечный автомат, размер которого будет n * 2^(n^2/2). Теперь единственная проблема, что этот граф слишком большой, чтобы с ним по-нормальному работать, но как минимум, он не бесконечный. А значит, с ним можно работать, как с обычным...


  6. 16 часов назад, Taoshi сказал:

    А какие, кстати, задачи планируется решать на разрабатываемой архитектуре?

    Например, ОС написать. Или портировать что-нибудь из линуксов, я вообще хочу попробовать написать транслятор x86 в movasm.

    И будет наконец без помощи VirtualBox в майнкрафте серьёзная ОС.


  7. 16 часов назад, Taoshi сказал:

    А наличие возможности менять возвращаемое для поданной связки команда+данные содержимое реестра памяти открывает двери в по-своему увлекательный мир микропрограммирования

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

    (Кстати, может, именно поэтому не могут вывести "формулу всего" в физике?)


  8. 22 часа назад, Laine_prikol сказал:

    Чтобы в Rust при переполнении чисел не падал, надо явно указать поведение при арифметических операциях. Например, saturating_add - при прибавлении число просто clamp в лимит типа

    Да, я знаю, надо только записать в документацию поведение при переполнении.

     

    15 часов назад, ZO125 сказал:

    Придется дожидаться установки последнего из возможных регистров перед выполнением следующей инструкции

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

    Например, условные переходы у меня сейчас используют особый регистр atz: он возвращает atz1, если atz0 == 0, иначе atz2.

    Значит, если я хочу при v == 0 прыгнуть в одно место, а при v != 0 в другое, то я могу одновременно записывать v, положение первого и второго места в atz0, atz1 и atz2.

     

    Я говорю вот что: во-первых, mov исполняется никак не медленнее любой инструкции x86 (может быть, медленнее nop, но это не точно); во-вторых, вроде бы, любую из старых инструкций x86 (до появления дополнений с векторизацией и тому подобным) можно превратить не более чем в 8 моих инструкций. Работать будет, конечно, медленно, но будет.

     

    5 часов назад, prop сказал:

    Ты из под скакалки хочешь запилить архитектуру https://ocdoc.cil.li/tutorial:modding_architecture для ос? Почему не на джаве?

    Например, чтобы и скалу подучить. Для джавы у меня другой проект, OCTechnics :)

     

    5 часов назад, prop сказал:

    По поводу питонокода, нотация ISomething вроде сишарповская, в питоне вроде так непринято, просто к сведению

    Да какая разница, я могу код и без этого писать...

     

    5 часов назад, prop сказал:

    И ещё на хомяке в гитхабе у тебя "middle programmer", если имелось в виду "средний программист", то лучше поменять на decent programmer

    То есть, грейды junior-middle-senior только у нас так называют?

     

    24 минуты назад, eu_tomat сказал:

    А ты планируешь использовать только новую периферию, изначально написанную под этот мод, или создать протокол для работы с периферией CC и OC?

    Скорее всего, только новую.

     

    Только что, prop сказал:

    Нащелкиванием через front panel или через реликтовые прото(перфокарты/дискеты) с boot'ером, неизвестно как оказавшиеся в данжах?

    Через протоеепромы, конечно. Например, просто перекрутить обычный EEPROM гаечным ключом сколько-то раз.


  9. 8 часов назад, eu_tomat сказал:

    А как ты планируешь реализовать доступ к периферии?

    Пока единственная идея, которая у меня появлялась - использовать регистры io. io0 - индекс устройства, io - регистр для обмена данными.

    Протокол обмена данными с разными компонентами надо, конечно, продумывать. Например, с дискетой или жёстким диском такой обмен данными будет очень медленным, по 8 байт за операцию. Но, например, роботу хватит.


  10. Что это?

    Пока разрабатывается OpenComputers II, у меня уже появилась идея для OpenComputers III.

    Основывается она на далеко не новом принципе: сделать компьютер, в котором все вычисления происходят в памяти/регистрах, а единственная возможная команда - MOV (скопировать значение из одного регистра в другой). Но я не встречал никаких виртуальных машин для такой архитектуры, поэтому решил написать свою.

     

    Для чего?

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

     

    Где потыкать?

    Текущие реализации (2 штуки, не во всех случаях работают одинаково):

    https://github.com/ProgramCrafter/python-mov-vm - на Python

    https://github.com/ProgramCrafter/rust-mov-vm - на Rust

    У меня была и реализация на Lua, но её я куда-то потерял. :(

    Сейчас думаю написать на Scala, как дополнительную архитектуру к OpenComputers.

     

    Что умеет?

    Пока что - печатать текст в консоль и считывать там же нажатия клавиш.

    Вообще, насколько я посчитал, любая инструкция x86 представляется в виде не более чем 8 MOV-инструкций, так что эта архитектура не должна быть существенно медленнее. Кроме того, каждая инструкция здесь 32-битная, поэтому предсказатель ветвлений и конвейер инструкций (в физическом варианте процессора) будут быстрее работать.

     

    Как выглядит какая-нибудь программа?

    Выводит

    ╔══════════════════════════════════════════════════════════╗
    ║  TigerOS v0.0.1 | not licensed!!!                        ║
    ╚══════════════════════════════════════════════════════════╝

    Выход по нажатию пробела в консоли.

     

    Байткод: \x80<\x00\x1c\x80\n\x00\x1b\x80\x01\x00\x04\x00\x03\x00\x14\x00\x1d\x00\x15\x80\x07\x00\x16\x00\x17\x00\x1b\x00\x1e\x00\x10\x00\x05\x00\x03\x80\x03\x00\x1b\x00\x10\x00\x03\x80 \x00\x04\x00\x05\x00\x14\x80N\x00\x15\x80\x10\x00\x16\x00\x17\x00\x1b\xa5T\x00\x10\x00\x1c\x00\x03\x80\x02\x00\x04\x00\x05\x00\x03\xa5P\x00\x1e\x80\x17\x00\x1d\x80\x02\x00\x1b\xa5W\x00\x10\x80\n\x00\x10\xa5Q\x00\x10\x80 \x00\x10\x80 \x00\x10\x80T\x00\x10\x80i\x00\x10\x80g\x00\x10\x80e\x00\x10\x80r\x00\x10\x80O\x00\x10\x80S\x00\x10\x80 \x00\x10\x80v\x00\x10\x800\x00\x10\x80.\x00\x10\x800\x00\x10\x80.\x00\x10\x801\x00\x10\x80 \x00\x10\x80|\x00\x10\x80 \x00\x10\x80n\x00\x10\x80o\x00\x10\x80t\x00\x10\x80 \x00\x10\x80l\x00\x10\x80i\x00\x10\x80c\x00\x10\x80e\x00\x10\x80n\x00\x10\x80s\x00\x10\x80e\x00\x10\x80d\x00\x10\x80!\x00\x10\x80!\x00\x10\x80!\x00\x10\x00\x1c\x00\x03\x80$\x00\x04\x00\x05\x00\x03\x80 \x00\x1e\x80B\x00\x1d\x80\x02\x00\x1b\xa5Q\x00\x10\x80\n\x00\x10\xa5Z\x00\x10\x00\x1c\x00\x03\x80\x02\x00\x04\x00\x05\x00\x03\xa5P\x00\x1e\x80K\x00\x1d\x80\x02\x00\x1b\xa5]\x00\x10\x81\x00\x00\x10\x80\n\x00\x1b\x81\x01\x00\x10

     

    Ассемблер (программа для перевода в байткод лежит вместе со всем на Python):

    Скрытый текст
    
    
    L0      mov     60      [w]
    
    L1      mov     $L5     addr
    -- function L1 (char -> [char], n -> sub0, ret -> [L1RET])
    L2.0    mov     1       sub1
    L2.1    mov     sub0    atz0
            mov     [L1RET] atz1
            mov     $L3     atz2
            mov     atz     addr
    L3      mov     [char]  cio
    L4      mov     sub     sub0
    L4D     mov     $L2.1   addr
    L4DD    
    
    L5      
    
    -- main loop
    L6      mov     cio     sub0
            mov     32      sub1 -- exit on Space
            mov     sub     atz0
            mov     $L19    atz1
            mov     $L7     atz2
            mov     atz     addr
    L7      mov     9556    cio
    L8      mov     [w]     sub0
            mov     2       sub1
            mov     sub     sub0
            mov     9552    [char]
            mov     $L9     [L1RET]
            mov     $L2.0   addr
    L9      mov     9559    cio
    L10     mov     10      cio
    L11     mov     9553    cio
    L11.5   mov     32      cio
            mov     32      cio
            mov     84      cio
            mov     105     cio
            mov     103     cio
            mov     101     cio
            mov     114     cio
            mov     79      cio
            mov     83      cio
            mov     32      cio
            mov     118     cio
            mov     48      cio
            mov     46      cio
            mov     48      cio
            mov     46      cio
            mov     49      cio
            mov     32      cio
            mov     124     cio
            mov     32      cio
            mov     110     cio
            mov     111     cio
            mov     116     cio
            mov     32      cio
            mov     108     cio
            mov     105     cio
            mov     99      cio
            mov     101     cio
            mov     110     cio
            mov     115     cio
            mov     101     cio
            mov     100     cio
            mov     33      cio
            mov     33      cio
            mov     33      cio
    L12     mov     [w]     sub0
            mov     36      sub1
            mov     sub     sub0
            mov     32      [char]
            mov     $L13    [L1RET]
            mov     $L2.0   addr
    L13     mov     9553    cio
    L14     mov     10      cio
    L15     mov     9562    cio
    L16     mov     [w]     sub0
            mov     2       sub1
            mov     sub     sub0
            mov     9552    [char]
            mov     $L17    [L1RET]
            mov     $L2.0   addr
    L17     mov     9565    cio
    L18     mov     256     cio
    L18D    mov     $L6     addr
    
    -- exit
    L19     mov     257     cio
    

     

     

    Структура команд

    Каждая команда является 32-битной: первые 16 бит описывают источник, следующие 16 - номер регистра назначения, куда надо записать значение источника.

     

    Если первый (старший) бит из 16, задающих источник, равен единице, то оставшиеся 15 бит - это число, которое будет записано в регистр назначения.

    Иначе эти 15 бит задают номер регистра-источника, из которого будет считано значение.

     

    Набор регистров

    Каждый регистр хранит 64-битное целое число. Всего регистров может быть не более 32768 из-за адресации.

    Номера регистров:

    Скрытый текст
    
    {'add0': 0, 'add1': 1, 'add': 2,
     'sub0': 3, 'sub1': 4, 'sub': 5,
     'mul0': 6, 'mul1': 7, 'mul': 8,
     'div0': 9, 'div1': 10, 'div': 11, 'mod': 12,
     'tlt0': 13, 'tlt1': 14, 'tlt': 15,
     'cio': 16,
     'io0': 17, 'io1': 18, 'io': 19,
     'atz0': 20, 'atz1': 21, 'atz2': 22, 'atz': 23,
     'memory': 24, '': 25, 'maddr': 26,
     'addr': 27,
     'reg0': 28, 'reg1': 29, 'reg2': 30, 'reg3': 31, 'reg4': 32, 'reg5': 33, 'reg6': 34, 'reg7': 35}

     

    Значение доступных на данный момент регистров:

    Скрытый текст
    
    add = add0 + add1
    sub = sub0 - sub1
    mul = mul0 * mul1
    div = div0 / div1 (если div1 = 0, то div = div0)
    mod = div0 % div1 (если div1 = 0, то mod = 0)
    tlt = если tlt0 < tlt1, то 1; иначе 0
    atz = если atz0 == 0, то atz1; иначе atz2 (очень удобно для условных прыжков)
    addr = текущая инструкция (аналог IP - Instruction Pointer в x86/x64)
    reg0-7 = регистры общего назначения (ничего не считают)

    cio - ввод-вывод текста через терминал; на Rust использует библиотеку termion, на Python - curses, на Lua(OpenComputers) - Term API.

    Чтение значения из cio возвращает -1, если не нажата ни одна кнопка, а иначе код нажатой клавиши (может быть, код символа, я не помню).

    Запись 256 в cio очищает экран, 257 - отключает curses и возвращается в обычную консоль, запись любого другого числа выводит на экран символ с данным кодом.

     

    memory - находится в разработке (возникает проблема с тем, что регистры 64-битные, а память квантуется по 32 бита, так как команды короткие).

    io - старый способ вывода данных на экран (не позволяет очистить экран, например)

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

    • Нравится 3

  11. 51 минуту назад, men_epto сказал:

    Код скопировал

    В OpenComputers есть ограничение по количеству копируемых строк - максимум 256 строк копируется за один раз. (Это происходит из-за того, что ограничен размер очереди событий.) Поэтому придётся скопировать вторую половину кода отдельно.


  12. По мотивам

     

    Lua? ы серьёзно? Оно же будет запускаться любым компом, к которому будет подключено, то ли дело MovEMU Byte Code, запускаться будет только через виртуальную машину (на Lua, так уж и быть) или новую архитектуру OpenComputers (которая ещё не готова); там не будет TLWY, можно будет использовать sleep, не теряя события, и так далее...  :sarcasm:

    • Ха-ха 2

  13. И библиотека bigModem, от которой всё это зависит (она занимается, видимо, пересылкой больших сообщений и ретрансляцией сообщения по всем компьютерам в сети, как Zn):

    Скрытый текст

     

    
    local component = require("component")
    local event = require("event")
    local serialization = require("serialization")
    local su = require("superUtiles")
    local computer = require("computer")
    
    ------------------------------------------
    
    ------------------------------------------
    
    local lib = {}
    lib.devices = {}
    
    function lib.create(address, maxPacketSize, dupProtectTimeout, dupProtectUpdateTimeout)
        local obj = {}
        obj.address = address
        obj.maxPacketSize = maxPacketSize or 7168
        obj.proxy = component.proxy(obj.address)
        obj.dupProtectTimeout = dupProtectTimeout or 8
        obj.dupProtectUpdateTimeout = dupProtectUpdateTimeout or 1
        obj.objCode = su.generateRandomID()
        obj.listens = {}
    
        obj.codes = {}
        obj.timeouts = {}
        local function addcode(code)
            if su.inTable(obj.codes, code) then
                return false
            else
                table.insert(obj.codes, code)
                table.insert(obj.timeouts, computer.uptime())
                return true
            end
        end
    
        table.insert(obj.listens, event.timer(obj.dupProtectUpdateTimeout, function()
            for i, code in pairs(obj.codes) do
                local timeout = obj.timeouts[i]
                if computer.uptime() - timeout > obj.dupProtectTimeout then
                    table.remove(obj.codes, i)
                    table.remove(obj.timeouts, i)
                end
            end
        end, math.huge))
    
        function obj.send(targetAddress, port, ...)
            local proxy = obj.proxy
            local sendData = serialization.serialize({...})
            local parts = su.toParts(sendData, obj.maxPacketSize)
            local randomCode = su.generateRandomID()
    
            for i, part in ipairs(parts) do
                local endflag = i == #parts
                local unicallCode = su.generateRandomID()
                addcode(unicallCode)
                if component.type(obj.address) == "tunnel" then
                    proxy.send(unicallCode, endflag, randomCode, i, part)
                else
                    if targetAddress == true then
                        proxy.broadcast(port, unicallCode, endflag, randomCode, i, part)
                    else
                        proxy.send(targetAddress, port, unicallCode, endflag, randomCode, i, part)
                    end
                end
            end
        end
    
        function obj.broadcast(port, ...)
            obj.send(true, port, ...)
        end
    
        local buffer = {}
        table.insert(obj.listens, event.listen("modem_message", function(_, uuid, sender, port, dist, unicallCode, endflag, randomCode, index, dat)
            if uuid ~= obj.address or not addcode(unicallCode) then return end
            if not buffer[randomCode] then buffer[randomCode] = {} end
            buffer[randomCode][index] = dat
            if endflag then
                local sendData = serialization.unserialize(table.concat(buffer[randomCode]))
                buffer[randomCode] = nil
                event.push("big_message", uuid, sender, port, dist, obj.objCode, su.unpack(sendData))
            end
        end))
    
        function obj.kill()
            for i = 1, #obj.listens do
                event.cancel(obj.listens[i])
            end
            table.remove(lib.devices, obj.indexInTable)
        end    
    
        table.insert(lib.devices, obj)
        obj.indexInTable = #lib.devices
        return obj
    end
    
    return lib

     

    • Одобряю 1

  14. Is it time to analyze code?

     

    networks.lua (не особо разбирался, что и как работает)

    Скрытый текст
    
    local component = require("component")
    local event = require("event")
    local serialization = require("serialization")
    local su = require("superUtiles")
    local computer = require("computer")
    local bigModem = require("bigModem")
    
    -------------------------------------------
    
    local noAddress
    local function raw_send(devices, name, code, data, obj, isResend, port)
        local noAddress2 = noAddress
        noAddress = nil
        for i = 1, #devices do
            local device = devices[i]
            if isResend then
                if device["resend"] == nil then
                    if not obj.resend then
                        goto skip
                    end
                elseif device["resend"] == false then
                    goto skip
                end
            end
            local proxy = component.proxy(device[1])
            if proxy.type == "modem" then
                if isResend and proxy.address == noAddress2 and device[2] == port and (not proxy.isWireless() or device[3] == 0) then
                    goto skip
                end
                local strength = device[3]
                local oldStrength
                if proxy.isWireless() then
                    if strength then
                        oldStrength = proxy.getStrength()
                        proxy.setStrength(strength)
                    end
                end
    
                device.bigModem.broadcast(device[2], "network", name, code, data)
    
                if oldStrength then proxy.setStrength(oldStrength) end
            elseif proxy.type == "tunnel" then
                if not isResend or proxy.address ~= noAddress2 then
                    device.bigModem.broadcast(0, "network", name, code, data)
                end
            else
                error("unsupported device")
            end
            ::skip::
        end
    end
    
    local function isType(data, target)
        return type(data) == target
    end
    
    -------------------------------------------
    
    local lib = {}
    
    lib.networks = {}
    
    function lib.create(devices, name, resend)
        checkArg(1, devices, "table")
        checkArg(2, name, "string")
        local obj = {}
        obj.devices = devices
        obj.name = name
        obj.resend = resend
        obj.listens = {}
    
        --------------------------------------------------
    
        for i = 1, #obj.devices do
            local device = obj.devices[i]
            local proxy = component.proxy(device[1])
            device.bigModem = bigModem.create(device[1])
            if proxy.type == "modem" then
                device.isOpen = proxy.open(device[2])
            end
        end
    
        --------------------------------------------------
    
        local messagebuffer = {}
        local life = {}
    
        local function cleanBuffer()
            for key, value in pairs(life) do
                if computer.uptime() - value > 8 then
                    messagebuffer[key] = nil
                    life[key] = nil
                end
            end
        end
        obj.listens[#obj.listens + 1] = event.timer(1, cleanBuffer, math.huge)
    
        local function addcode(code)
            local index = su.generateRandomID()
            messagebuffer[index] = code or su.generateRandomID()
            life[index] = computer.uptime()
            return messagebuffer[index]
        end
    
        local function listen(_, this, _, port, _, objCode, messagetype, name, code, data)
            if not isType(messagetype, "string") or not isType(name, "string") or not isType(code, "string") then return end
            if su.inTable(messagebuffer, code) or name ~= obj.name or messagetype ~= "network" then return end
            local ok = false
            local device
            for i = 1, #obj.devices do
                device = obj.devices[i]
                if device[1] == this and (port == 0 or device[2] == port) and device.bigModem.objCode == objCode then
                    ok = true
                    break
                end
            end
            if not ok then return end
            addcode(code)
            local function resendPack()
                noAddress = this
                raw_send(obj.devices, obj.name, code, data, obj, true, port)
            end
            if device["resend"] == nil then
                if obj.resend then
                    resendPack()
                end
            elseif device["resend"] == true then
                resendPack()
            end
            local out = serialization.unserialize(data)
            event.push("network_message", obj.name, su.unpack(out))
        end
        table.insert(obj.listens, event.listen("big_message", listen))
    
        --------------------------------------------------
    
        function obj.send(...)
            local data = serialization.serialize({...})
            raw_send(obj.devices, obj.name, addcode(), data, obj)
        end
    
        lib.networks[#lib.networks + 1] = obj
        local thisIndex = #lib.networks
    
        function obj.kill()
            for i = 1, #obj.listens do event.cancel(obj.listens[i]) end
            for i = 1, #obj.devices do
                local device = obj.devices[i]
                device.bigModem.kill()
                if device["isOpen"] then
                    component.proxy(device[1]).close(device[2])
                end
            end
            table.remove(lib.networks, thisIndex)
        end
    
        return obj
    end
    
    function lib.getDevices(tunnels, modems, wiredModems, wirelessModems, modemsPort, modemsStrength)
        if not modemsPort then modemsPort = 88 end
        if not modemsStrength then modemsStrength = math.huge end
    
        ------------------------------------------------------
    
        local devices = {}
    
        if tunnels then
            for address in component.list("tunnel") do
                devices[#devices + 1] = {address}
            end
        end
        if wiredModems then
            for address in component.list("modem") do
                if component.invoke(address, "isWired") and not component.invoke(address, "isWireless") then
                    devices[#devices + 1] = {address, modemsPort, modemsStrength}
                end
            end
        end
        if wirelessModems then
            for address in component.list("modem") do
                if not component.invoke(address, "isWired") and component.invoke(address, "isWireless") then
                    devices[#devices + 1] = {address, modemsPort, modemsStrength}
                end
            end
        end
        if modems then
            for address in component.list("modem") do
                devices[#devices + 1] = {address, modemsPort, modemsStrength}
            end
        end
    
        return devices
    end
    
    function lib.getNetwork(name)
        for i = 1, #lib.networks do
            if lib.networks[i].name == name then
                return lib.networks[i]
            end
        end
    end
    
    return lib

     

     

    • Одобряю 1

  15. Баг: невозможно установить на read-only файловую систему, установщик не обрабатывает такой вариант.

    Просчёт интерфейса: невозможно выйти из установщика.

    Баг: попытался установить (архитектура Lua 5.3), получил

    Unrecoverable Error: /lib/core/boot.lua:84: boot/01_process.lua:80: attempt to call a nil value (field 'addHandle')
    Так что подтверждаю: теперь код программ защищён хорошо, потому что он не запускается (как минимум у меня).

     

    • Нравится 1
    • Ха-ха 3
    • Грусть 1

  16. @rootmaster Против слива исполняемого кода не поможет ничто, если ты этот код собираешься распространять.

     

    Каким образом достать код Lua из запускаемой программы? Секрет фирмы...

    Скрытый текст

    Например, можно подменить функцию load, чтобы она не только компилировала текстовый код Lua в байткод, но и записывала на диск тот код, который ей скормили.

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

     

    16 минут назад, rootmaster сказал:

    computer.pushSignal почьти некто не юзает

    Так и event.push не очень много кто и что использует.

     

    18 минут назад, rootmaster сказал:

    это прога для отладки и поиграться

    Я-то уже понял. Единственная проблема - почему тот, кто читает эту тему, узнаёт об этом только на 9 комментарии? :blink:

    • Нравится 5

  17. It's time to go deeper :)

     

    Насколько выявил анализ кода, эта программа при запуске заменяет библиотеки event, thread на свои; то же происходит с computer.beep.

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

    • Грусть 1

  18. В 04.03.2022 в 15:00, eu_tomat сказал:

    разделение кода и данных было условным

    Зря, что ли, фон Нейман свою архитектуру компьютеров создавал?)

     

    В 04.03.2022 в 15:00, eu_tomat сказал:

    если сильно захочется, то можно и на Lua написать какой-нибудь интерпретатор байт-кода

    Вот это-то как раз не сильно сложно; например, у меня есть три варианта виртуальной машины, исполняющей MBC (MovEMU Byte Code).

    (Единственная проблема - ни одна из машин не работает как надо, например, с переполнением чисел; мало того, все три ведут себя по-разному; но у все три относительно рабочие и поддерживают консольный ввод-вывод.)

     

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


  19. Скорее всего, просто не сохраняются никакие файлы на жёстких дисках OpenComputers.

     

    Из решений... ну, разве что запихивать весь код в EEPROM могу посоветовать.

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


  20. 2 минуты назад, prop сказал:

    я не вижу на уютном сервере для программирования плагины вообще и для привата в целом

    WorldGuard стоит.

     

    2 минуты назад, prop сказал:

    портянки здесь писать бесполезно "техническая администрация" их игнорирует

    Не совсем, например, в последнем варианте сборки Вольфрам скинул уже только папки mods и config.


  21. В 15.02.2022 в 21:32, ProgramCrafter сказал:

    Для тех, кому хочется сэкономить трафик, скидываю только моды с конфигами (48 МБ против 181): https://drive.google.com/file/d/1SS2yS5RiJJzUsqRO7ZTXQnzf4R2Wl34q/view?usp=sharing

    Рецепт таков:

    1. Скачиваем через свой любимый лаунчер Forge 1.7.10

    2. Распаковываем мой архив, кидаем папки mods и config в .minecraft

     

    Эти моды те же самые, что скидывал WolframoviyI.

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