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

swg2you

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

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

  • Посещение

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

    20

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


  1. Из того,что я прочитал - такой демон может отвечать,к примеру,на автоматическое монтирование дисков(ивент peripheralAdded, на сколько я помню), автоматически прогружать в глобал АПИ компонентов(что бы каждый раз не писать modem=component.modem), работать корзиной и т.п. Вобщем - может быть не только вирусом. Часики swg тоже демон,в винде его бы назвали "служба гаджета часов"

    Службы, демоны, резиденты - каких только имен не наплодили для фоновых задач )

    • Нравится 2

  2. Захотелось мне найти значения безопасных цветов, чтобы разноцветные программы одинаково отображались на мониторах 2-го и 3-го уровня.
    Затем мне захотелось найти простую формулу для генерации палитры 6*8*5 + 16 оттенков серого, для мониторов 3-го уровня.
     
    В процессе изысканий родился инструмент Sipmle color tester или sicot.lua:

    local gpu=require('component').gpu
    local ev=require('event')
     
    local function setColor(f,b)
      gpu.setForeground(f)
      gpu.setBackground(b)
    end
     
    local w=0xFFFFFF
    require('term').clear()
    gpu.fill(1,1,80,12," ")
    gpu.set(27,1,'← click →')
    gpu.set(76,1,'ʕ▫ᴥ▫ʔ')
    gpu.set(69,3,'◄ Tier 2')
    gpu.set(69,5,'◄ Tier 3')
    gpu.set(69,6,'       ▼')
    local t=ev.timer(1,function() if math.random(6)==1 then setColor(w,0) gpu.set(76,1,'ʕ▪ᴥ▪ʔ') os.sleep(.05) gpu.set(76,1,'ʕ▫ᴥ▫ʔ') end end, math.huge)
     
    local function showcolor(c)
      for i=0,24 do
        local b=bit32.extract(c,i,1)
        setColor((1-b)*w, b*w)   
        gpu.set(24-i,1,tostring(b))
      end
      setColor(bit32.bxor(c,w), c)
      gpu.fill(1,3,24,3," ")
      gpu.set(9,4,'0x'..string.format('%06X',c))
      setColor(w,0)
      gpu.set(1,2,'└──┴┴──┘└──┴┴──┘└──┴┴──┘')
    end
     
    local color=math.random(w)
    showcolor(color)
     
    local s='SimpleColorTest'
    for i=1,#s do
      setColor(bit32.bxor(color,w), color)
      gpu.set(36+i*2,1,string.sub(s,i,i)..' ')
      color=math.random(w)
    end
     
    --Tier2: безопасная палитра, используйте эти цвета, чтобы ваша программа выглядела одинаково на мониторах 2-го и 3-го уровней
    palTier2={0x000000,0x333333,0x333399,0x336600,0x336699,0x33CC33,0x663300,0x6699FF,0x9933CC,0xCC66CC,0xCCCCCC,0xFF3333,0xFFCC33,0xFF6699,0xFFFF33,0xFFFFFF}
    for x=0,15 do
      setColor(w,palTier2[x+1]) 
      gpu.set(36+2*x, 3, '  ') 
    end
     
    --Tier3: 16 оттенков серого
    for y=0,0xF do 
      setColor(w,y*0x111111)
      gpu.set(36+y*2, 5, '  ')
    end
     
    --Tier3: большая палитра 6*8*5=240 комбинаций цветов
    for r=0,5 do
      for g=0,7 do
        for b=0,4 do
          setColor(w, r*0x330000 + g*0x2400 + b*0x3F)
          gpu.set(1+2*(b+g*5), 7+r, '  ')
        end 
      end
    end
     
    repeat
      local _,_,x,y,b=ev.pull('touch')
      local s,fg,bg=gpu.get(x,y)
      if y==1 and x<=24 then
        local bit=24-x
        color = bit32.bxor(color,2^bit)
        showcolor(color)
      else
        color=bg
        showcolor(color)
      end
    until b==1
    ev.cancel(t)
    setColor(w,0)
    require('term').clear()

     
    Так он выглядит не мониторе 3-го уровня:
    h_1435288264_1966583_3f083dc9e6.png

    А так, на мониторе 2-го уровня:
    h_1435288264_9615441_e723a8e3b8.png

    (Обратите внимание на то, что цвета ,безопасной палитры Tier 2 выглядят одинаково на обеих экранах!)

     

    На мониторе 1-го уровня он не выглядит никак.

     
    В нем можно кликать по битам, и по цветным квадратикам.
    (Только по медвежонку LiVi не кликайте, он этого не любит)
     
    Внутри кода, вы можете найти безопасную палитру в 16 цветов, и простую формулу генерации большой палитры.
     
    Код сырой и грубый, улучшать можно бесконечно. Навскидку:

    • Повесить резидентом, чтобы вызывался по хоткею, сохранял под собой экран, и выводился поверх.
    • Добавить кнопочку "вставить цвет", которая в таймере будет имитировать ввод цветового кода.
    • Переписать в виде библиотеки с выдачей/запросом/установкой цветов по индексу.
    • Добавить таблицу комбинаций цветов текста и фона, для наглядности.
    • Добавить определение цвета текста (а не только фона).
    • Добавить в библиотеку аналог ANSI цветовых кодов.
    • Научить LiVi танцевать.
    • Что-то еще.

    В процессе игры было обнаружено, что OC принудительно приводит цвета к стандартному значению. Т.е, какие бы вы цвета не писали, они будут приведены к 256 цветам в случае с  T3 и к 16 - в случае с Т2. Это есть очень хорошо для хранения экранов во всяких многооконных бодягах. В самом худшем случае (присутствие всех возможных цветов), хранение полной цветовой плоскости экрана T3, без сжатия, займет 16000 байт, а T2 - 2000 байт.
     
    Также была обнаружена дикость генерации 16 цветной палитры T2, кто найдет закономерность и простую формулу для генерации - тому печенька.
     
    Еще был обнаружен аномальный, странный, неучтенный, нестандартный цвет на T2. Кто найдет 17-й цвет - тому две печеньки, и цвет в подарок.

    • Нравится 4

  3. a=1 load(" print(a) load('print(a)')()",nil,nil,{print=print, load=load, a=2})()  

    Результат:

    2

    1

    Вывод: не хочешь давать доступ к руту - не разрешай в среде функцию load

     

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

     

    Убрать load - не вариант. Придется учитывать эту особенность и исправлять поведение кода на более каноничное. 

     

    upd:

    задал тот-же вопрос на стаковерфлоу, отвечают что если не указать среду лоад берет, цитирую: "very global environment" )

    будем глушить. OpenOs то надо в окошке запустить.


  4. В для первого load() ты указываешь переменную окружения, насколько я понял.

    Для второго - нет (используется "глобальное окружение").

    Поэтому, у них разные переменные а.

    Да, но блок

     

    [[

    print(a)

    load("print(a)")()

    ]]

     

    скомпилирован в среде e.

     

    Для этого блока глобальной средой является содержимое таблицы e. Т.е. все что находится в этом блоке не может видеть ничего кроме переданных функций print, load, заданной a и замыкающей _G.

     

    Получается что load() игнорируя принципы Lua и собственную среду выполнения - получает доступ к рутовому глобалу, мало того, дает этот доступ компилируемому блоку.

     

    На мой взгляд, это серьезный баг реализации, нарушающий общую концепцию изоляции сред в Lua. Либо я неверно понимаю эту концепцию.

     

    upd:

    если у кого-то установлен чистый Lua без майнкрафтов и прочих крафтов, прошу проверить, проявляется ли такой эффект там.


  5.  

    Да, действительно, выдает не то, что подразумевается. Но не 2,1 а 2, nil. Почему так происходит не в курсе, нужно видимо у самого Сангара спрашивать, либо копаться в реализации этого load() на гитхабе.

    nil - это я первую строчку в примере потерял.

    поправил пример.


  6. А можно я по теме? Считаю, что хранить картинку в виде сериализованной таблицы крайне не рационально. Куча лишних скобок, пробелов и запятых. Не хочешь подумать над более компактным форматом?

    Истина!

    Таблицы громоздки. Хранение одного большого экрана отожрет почти всю планку памяти тиер1, строкой хранить на несколько порядков компактнее.


  7. Ищи баг в программе :)

    Никаких препятствий там нет и быть не может. Скорее всего, твой робот уперся в задницу криперу. Ее он, кстати, может принять за воздух=)

    Заметил в шахтерских мирах одну особенность. Крипер, когда взрывается, визуально разрушает блоки. Но при попытке войти в этот блок, тебя выталкивает назад. Этакие прозрачные непроходимые блоки получаются.

     

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

     

    Такой вот баг.

     

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


  8. Такое происходит из-за биндинга, есть разница между статичным и динамичным.

    Не понял.

     

    load("print(a)") вызванный с параметрами "по умолчанию", должен компилировать блок "print(a)" в среде _G

    Поскольку для load("print(a)") глобальной средой является e, то ожидается что именно e будет средой для "print(a)"

     

    Но, почему-то, load берет среду из места в которое не должен иметь доступа.


  9. пример кода:

    a=1
    local e={print=print, load=load, a='2'}
    e._G=e
    load(
    [[
      print(a) 
      load("print(a)")()
    ]]
    , '', '', e)() 
    

    ожидается вывод:
    2
    2


    а в реальности:
    2
    1

     
    Проверял и под OpenOS и в чистой среде.
     
    Это баг или фича?


  10. 2 Fingercomp

     

    Мы пишем программы под ос выполняющуюся в интерпретаторе луа на эмулируемом модом железе внутри программы майнкрафт внутри джавы внутри ос внутри реального компьютера.

    Вам не кажется это странным?

     

    Одна причина, почему стоит писать свою ОС для этой матрешки:

    • Это интересно и познавательно.
    Поэтому пишите свои ОС, программы, игры, браузеры, редакторы, калькуляторы, файловые менеджеры, сервера, утилиты и библиотеки.

    А всех кто вам скажет, что это бессмысленно отвечайте, - Кактус!

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

  11. После h:close можно написать computer.beep.

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

    Тут либо делать поток thread, либо через подмену, либо посмотрев реализацию event.listen.

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

    local beep=event.timer(1, function() computer.beep(440) end, math.huge)

    а снаружи, добавить еще один, который будет слушать клавиатуру и по нажатию на клавишу делать

    if beep then event.cancel(beep) end

     

    upd:

    Итак, совместные усилия превратились в код нового, хорошего и правильного tsrmail.lua

    local port = 9
    
    if _tsrmail then
      io.write('tsrmail already loaded @ port ',_tsrmail)
    else
      local beep, cp, ev = false, require("computer"), require("event")
      require("component").modem.open(port)
    
      local function listener(...)
        local e={...}
        if e[4] == port then
          local h = io.open('@','a')	
          h:write('--', os.date(), ' from:', e[3], ' port:', e[4], '\n')
          h:write(table.concat(e,'\n',6))
          h:close()	
          if not beep then 
            beep=ev.timer(2, function() cp.beep(440) end, math.huge)
          end 
        end
      end
    
      local function unbeep()
        if beep then 
          ev.cancel(beep)
          beep=false 
        end
      end
    
      ev.listen("key_down", unbeep)
      ev.listen("modem_message", listener)
    
      io.write('tsrmail loaded @ port ', port)
      _G._tsrmail=port
    end
    

    Спасибо всем оппонентам, кто высказывался по делу:

    Zer0Galaxy за, -можно повесить слушателя на событие

    LeshaInc за, -покажу на примере

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

    Zer0Galaxy за, -можно еще порт и дистанцию прилепить

    NEO за, -лучше io используй

    И всем остальным за общее комментирование и множественные примеры.


  12. Достаточно написать функцию-обработчик, типа этого:

    Ох ты, набежали тут, примеров накидали ) я вообще-то с LeshaInc разговаривал ))

     

    Ну ладно, попробуйте event.listen повесить без OpenOS, и на этом закроем тему.


  13.  

    event=require"event"
    
    function listmsg(eventName, receiverAddress, senderAddress, port, distance, ...)
          local h = fs.open('@','a')	
          h:write('--'..os.date()..' From:'..senderAddress..'\n'..table.concat({...},'\n'))
          h:close()
    end
    
    event.listen("modem_message", listmsg)
    
    Как то так. Можно еще порт и дистанцию прилепить

     

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

  14. Компьютер наилучшей комплектации отправлен на Мадагаскар хомячкам до востребования.

    А какие еще интересные функции кроме __index и __newindex могут содержать метатаблицы?

    Первоисточник всего: http://www.lua.org/manual/5.2/manual.html#2.4

  15. Только их там не 6. Если ты напишешь m.broadcast(port, data1)---их будет шесть,а если ты напишешь m.broadcast(port, data1, data2)---их будет 7, и так далее

    Это мелочи, мы всегда можем написать

    local function listmsg(...)
      print(...)
    end
    event.listen("modem_message", listmsg)
    Главное суметь заставить работать это в фоне. Ждем LeshaInc, чтоб объяснил как это сделать.

     

    Листен всё держит в условном фоне

    Ты просто заменяешь event.pull на event.listen(event, function) и всё

    т.е. этот код выполнится, оставит слушателя работать, а я смогу тем временем запускать другие программы?

  16. Гоу к нам в Opennet http://computercraft.ru/topic/675-opennetoc-prodolzhenie/

    Если объеденяться, то твоя программа может сразу появляться у пользователя, а нам пригодятся твои идеи и реализации сетевых алгоритмов. У нас уже и адресная книга aka DNS есть, и пересылка порциями.

    Я смотрел, но OpenNet пока слишком сложна для моего понимания. Не вижу общей концепции.


  17. Через event.listen swg2you можешь повесить слушателя на modem_message. Вот если не знаешь его использование:

     

     

    event.listen(event: string, function: function) -- Теперь если он словит event который указан в первом аргументе будет выполнена функция со второго аргумента. Аргументы функции нужно передавать такие же, какие выдаст event.pull, т е шесть аргументов.

    Например:

    local function listmsg(_,_,_,_,_,msg)
        print(msg)
    end
    event.listen("modem_message", listmsg)
    Такой код будет ловить сообщения по всем открытым портам и выводить их на экран.

     

    Уоу, круто! 

    А как это запустить чтоб оно работало в фоне?


  18. Приз за решение проблемы ReadOnly-полей уходит к swg2you. Жду комплектацию компьютера и адрес куда его отправлять.

    Хотелось бы узнать про параметры (t,k,v) функции __newindex. А про функции rawget и rawset поподробнее.

    __newindex(t,k,v) - (новый индекс) вызовется если в таблицу t, несуществующему ключу k присвоить значение v

    v=rawget(t,k) и rawset(t,k,v) - позволяют получить/присвоить значение v напрямую, игнорируя всякие метаметоды

     

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


  19. Так где здесь  пересылка файлов? Эта штука абсолютно весь пойманный эфир (возможно не только 9-й порт) будет сыпать в один файл. И зачем переопределять функцию pullSignal если можно повесить слушателя на событие?

    Как ты верно подметил, если переименовать tsrmail обратно в tsrsniffer, то мы получим сетевой сниффер, который будет фоном перехватывать все! входящие пакеты на всех! портах и складывать их в файлик. )

     

    Более того, если удалить "=='modem_message'", то мы получим сниффер для всех событий.

     

    upd:

    моя не уметь на событие, моя уметь подменять pullSignal


  20. Модуль отправки: send.lua

    print('Use: send [<receiver-address>] < <filename> - for send filename,\nor: send [<receiver-address>] - for write, and Ctrl+C to send.')
    local port = 9
    local c = require("component")
    local m = c.proxy(c.list("modem")())
    local s, addr = io.read("*a"), ...
    if #s>0 then
      if addr then m.send(addr, port, s)
      else m.broadcast(port, s) end
      print('Sended: '..#s..' bytes')
    end
    

    и резидентный модуль приема: tsrmail.lua

    local port = 9
    if _tsrmail then
      print('tsrmail already loaded @ port '.._tsrmail)
    else
      local beep=0
      local c = require("component")
      local cp = require("computer")
      local fs = require("filesystem")
      local m=c.proxy(c.list("modem")())
      local pullSignal = cp.pullSignal
      cp.pullSignal = function (...)
        local e={pullSignal(...)}
        if e[1]=='modem_message' then 
          local h = fs.open('@','a')	
          h:write('--'..os.date()..' From:'..e[3]..'\n'..table.concat({table.unpack(e,6)},'\n'))
          h:close()
          beep=1
        elseif e[1]=='key_down' then
          beep=0
        elseif beep>0 then 
          cp.beep(440) 
        end
        beep=-beep
        return table.unpack(e)
      end
      m.open(port)
      print('tsrmail loaded @ port '..port)
      _G._tsrmail=port
    end
    

    сохранить на диск.

    tsrmail.lua - запустить, после чего она останется резидентным модулем в памяти, и слушая 9-й порт, будет складывать всю почту в файл "@" на диске.

     

    Пример использования:

     

    У пользователя Коли, и еще у кого-то, есть компьютер с сетевой картой, на котором работает резидентная tsrmail.lua.

     

    Программист Вася только что, получил на дискетке копию "TSR mail", запустил  tsrmail.lua, чтобы иметь возможность принимать почту, и ему не терпится заявить о себе всему миру. Он запускает send, читает две строчки справки, пишет пару строк сообщения (хеловорд конечно, что же еще может написать программист) и нажав Ctrl+C отправляет.

    h_1435093437_1413607_8e11bbb269.png

     

    Но пользователь Коля, как и другие пользователи "TSR mail" заняты своими делами: кормят коров, сажают желтые цветы и воюют с криперами. Хоть Колин компьютер и пищит "хозяин! почта пришла!", Коля далеко и не слышит.

     

    Программисту Васе не терпится пообщаться, он хочет чтобы ему тоже прислали что-то. Хоть простенький хелловорд.

     

    Немного поразмыслив, Вася соображает, что хелловорд это самодостаточная штука, и вовсе не располагает к ответам и общению. Заметив в первой строчке образец перенаправления ввода/вывода (а наш Вася программист, и знает всю мощь этого шаманства) он вновь запускает send отправляет сообщение и, поскольку под рукой больше ничего не нашлось, отправляет в сеть программку send.lua, направив содержимое send.lua во входной поток самой себя.

    h_1435093438_2556843_da3e02baed.png

     

    Пользователь Коля, проходив мимо компьютера, услышал писк и подошел проверить почту. Посмотрев стандартной командой cat @ содержимое файла @, с тремя сообщениями Васи, и пробурчав под нос, - Опять эти программеры фигней страдают, лучше бы коров покормили! - удалил сообщения командой rm @

    h_1435093438_8163746_5ffb3896af.png

     

    Если бы наш программист догадался прислать что-то поинтереснее, например новую версию пасьянса, то Коля может и сохранил бы его, переименовав mv @ pasians2.lua, и почистив edit pasians2.lua от лишних сообщений.

     

    Но к сожалению, это был не пасьянс.

    --==--

    P.S.

    Код quick and dirty, но зато simple and short. По хорошему, нужна обертка-интерфейc для send, которая будет хранить адресную книгу, дополняя адресатов из @, большие файлы пересылать порциями обходя ограничение на размер пакета, красиво показывать @ добавляя функции ответа и сохранения, ну и все такое. А в резидентный модуль неплохо бы добавить отклик "принял".

    • Нравится 3

  21. Так, а как сделать что бы таблица ro была не одна на всех, а своя для каждого экземпляра класса?

    Я далек от ООП, но думаю, что как-то так.

    setmetatable(obj1, {__index=ro1,__newindex=function(t,k,v) local _=rawget(ro1,k) or rawset(t,k,v) end})

    setmetatable(obj2, {__index=ro2,__newindex=function(t,k,v) local _=rawget(ro2,k) or rawset(t,k,v) end})

     

    Или по твоему коду:

    Class={a=1, b=2}
    
    function Class:new()
      local obj={c=3, d=4}
      local nc={}
      for k,v in pairs(self) do nc[k]=v end
      setmetatable(obj,{__index=nc,__newindex=function(t,k,v) local _=rawget(nc,k) or rawset(t,k,v) end})
      return obj
    end
    
    function Class:ShowFields()
      prn(self.a, self.b, self.c, self.d)
    end
    
    function Class:SetA(Val)
      rawset(self,'a',Val)
    end
    
    function Class:SetB(Val)
      rawset(self,'b',Val)
    end
    
    obj = Class:new() 
    obj2 = Class:new()
    
    obj:ShowFields()
    obj.a=5
    obj.b=6
    obj.c=7
    obj.d=8
    obj:ShowFields()
    obj:SetA(5)
    obj:SetB(6)
    obj:ShowFields()
    obj2:ShowFields()
    
    Если я правильно понял, что тебе от этого кода нужно.
×
×
  • Создать...