ProgramCrafter
-
Публикации
245 -
Зарегистрирован
-
Посещение
-
Победитель дней
41
Сообщения, опубликованные пользователем ProgramCrafter
-
-
Хорошо, вот 62 строки: https://gist.github.com/ProgramCrafter/3b6a2faa6f4da3f74b0ca52b5aee4dc5
Самый базовый код, без обработки ошибок, но некоторое время может работать.
-
А что насчёт
В 14.04.2022 в 22:50, Taoshi сказал:наличие такой ссылки на программу, благодаря которой можно скачать
и запуститьеё без необходимости качать и распаковывать архивыа желательно и возможности посмотреть на код, не устанавливая его никуда?
-
4 часа назад, Progger_coder сказал:это надо несколько раз сканировать, и брать среднее значение?
Можно, но есть более интересный метод, его можно здесь посмотреть:
Вкратце: добавляемый OC шум может иметь только 256 разных значений. Можно перебрать плотность блока, вычислить, какой шум был добавлен, из этого получить тот байт, который для добавления шума используется. Если этот "байт" не целый или не лежит в интервале [-128; 128), то мы не угадали, и надо проверять какую-то другую плотность.
P.S.
4 часа назад, Progger_coder сказал:А вот скриншот просканированной пещеры
На мой вкус, стоило бы сделать какой-то ровный фон, вроде угля, глины или чего-то подобного. Но это уже мелочи
-
1
-
1
-
-
В конец библиотеки надо return data.
Потом стоит перезагрузить компьютер (или выполнить в интерпретаторе lua package.loaded['data'] = nil), чтобы старая библиотека была удалена из кэша.
-
1
-
-
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 ... -
3 часа назад, ProgramCrafter сказал:теории конечных автоматов с изменяющимися правилами ещё никто не создавал
Опс, я понял: если взять в качестве состояния не только текущую вершину, но и набор существующих на данный момент рёбер, то получится не менее конечный автомат, размер которого будет n * 2^(n^2/2). Теперь единственная проблема, что этот граф слишком большой, чтобы с ним по-нормальному работать, но как минимум, он не бесконечный. А значит, с ним можно работать, как с обычным...
-
16 часов назад, Taoshi сказал:А какие, кстати, задачи планируется решать на разрабатываемой архитектуре?
Например, ОС написать. Или портировать что-нибудь из линуксов, я вообще хочу попробовать написать транслятор x86 в movasm.
И будет наконец без помощи VirtualBox в майнкрафте серьёзная ОС.
-
16 часов назад, Taoshi сказал:А наличие возможности менять возвращаемое для поданной связки команда+данные содержимое реестра памяти открывает двери в по-своему увлекательный мир микропрограммирования
Да, насколько я знаю, теории конечных автоматов с изменяющимися правилами ещё никто не создавал.
(Кстати, может, именно поэтому не могут вывести "формулу всего" в физике?)
-
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 гаечным ключом сколько-то раз.
-
8 часов назад, eu_tomat сказал:А как ты планируешь реализовать доступ к периферии?
Пока единственная идея, которая у меня появлялась - использовать регистры io. io0 - индекс устройства, io - регистр для обмена данными.
Протокол обмена данными с разными компонентами надо, конечно, продумывать. Например, с дискетой или жёстким диском такой обмен данными будет очень медленным, по 8 байт за операцию. Но, например, роботу хватит.
-
Что это?
Пока разрабатывается 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
-
-
51 минуту назад, men_epto сказал:Код скопировал
В OpenComputers есть ограничение по количеству копируемых строк - максимум 256 строк копируется за один раз. (Это происходит из-за того, что ограничен размер очереди событий.) Поэтому придётся скопировать вторую половину кода отдельно.
-
По мотивам
Lua? ы серьёзно? Оно же будет запускаться любым компом, к которому будет подключено, то ли дело MovEMU Byte Code, запускаться будет только через виртуальную машину (на Lua, так уж и быть) или новую архитектуру OpenComputers (которая ещё не готова); там не будет TLWY, можно будет использовать sleep, не теряя события, и так далее...
-
2
-
-
И библиотека 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
-
-
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
-
-
Баг: невозможно установить на 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
-
-
@rootmaster Против слива исполняемого кода не поможет ничто, если ты этот код собираешься распространять.
Каким образом достать код Lua из запускаемой программы? Секрет фирмы...
Скрытый текстНапример, можно подменить функцию load, чтобы она не только компилировала текстовый код Lua в байткод, но и записывала на диск тот код, который ей скормили.
При этом можно сделать так, чтобы этот "мод для OpenOS" не мог перезагрузить компьютер и вернуть load в исходное состояние.
16 минут назад, rootmaster сказал:computer.pushSignal почьти некто не юзает
Так и event.push не очень много кто и что использует.
18 минут назад, rootmaster сказал:это прога для отладки и поиграться
Я-то уже понял. Единственная проблема - почему тот, кто читает эту тему, узнаёт об этом только на 9 комментарии?
-
5
-
-
It's time to go deeper
Насколько выявил анализ кода, эта программа при запуске заменяет библиотеки event, thread на свои; то же происходит с computer.beep.
Это позволяет управлять программами, запущенными после этого - а точнее, не давать им создавать свои события (хорошо, что никто не знает про computer.pushSignal), регистрировать слушателей, в любой момент приостанавливвать потоки - в общем, инструмент для тестов программ, наверно, был бы неплох.
-
1
-
-
В 04.03.2022 в 15:00, eu_tomat сказал:разделение кода и данных было условным
Зря, что ли, фон Нейман свою архитектуру компьютеров создавал?)
В 04.03.2022 в 15:00, eu_tomat сказал:если сильно захочется, то можно и на Lua написать какой-нибудь интерпретатор байт-кода
Вот это-то как раз не сильно сложно; например, у меня есть три варианта виртуальной машины, исполняющей MBC (MovEMU Byte Code).
(Единственная проблема - ни одна из машин не работает как надо, например, с переполнением чисел; мало того, все три ведут себя по-разному; но у все три относительно рабочие и поддерживают консольный ввод-вывод.)
А вот будет ли защитой изменение программой самой себя, сомнительно. Если найдётся хотя бы одна дыра в безопасности программы, итог может оказаться непредсказуемым.
-
Скорее всего, просто не сохраняются никакие файлы на жёстких дисках OpenComputers.
Из решений... ну, разве что запихивать весь код в EEPROM могу посоветовать.
Или использовать жёсткий диск в блочном режиме (опять нужен особый EEPROM, но это может хоть как-то работать).
-
2 минуты назад, prop сказал:я не вижу на уютном сервере для программирования плагины вообще и для привата в целом
WorldGuard стоит.
2 минуты назад, prop сказал:портянки здесь писать бесполезно "техническая администрация" их игнорирует
Не совсем, например, в последнем варианте сборки Вольфрам скинул уже только папки mods и config.
-
UUID фейкового игрока OpenComputers - (если WolframoviyI ничего не менял) 7e506b5d-2ccb-4ac4-a249-5624925b0c6
Цитата# The UUID to use for the global fake player needed for some mod
# interactions.
fakePlayerUuid: "7e506b5d-2ccb-4ac4-a249-5624925b0c67" -
21 час назад, Xytabich сказал:но ломать блоки - нет
Может, у привата не выставлено, чтобы мемберы могли ломать блоки, и это могут делать только владельцы?
-
В 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
-

Кеширование библиотек в OC
в Разные (отсортировать)
Опубликовано:
Вроде бы лучше библиотеки складывать в /usr/lib/<name>.lua, но это так, просто для красоты.
Новые тоже.
Офнуть проблематично, для этого надо (и надо бы, кстати) переписать require.
А выбросить библиотеку из кеша можно так: package.loaded[<name>] = nil