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

Stem: делаем сайт для управления светом используя только OpenComputers

Рекомендуемые сообщения

Некоторое время назад я публиковал программку - интернет-мост Stem.

Он очень простой в использовании, но к сожалению пока не лишен некоторых глюков.

 

А кроме того, у него есть недокументированные возможности.

Предлагаю сейчас поиграться с одной такой тайной фичей. Это будет интересно тем, кто немного знаком с HTML/CSS/JavaScript.

 

В чём суть?

Всё просто.

У Stem есть веб-клиент. То есть если вы зайдете по адресу https://stem.fomalhaut.me (например), вы увидите окно, которое пригласит вас ввести ID канала и початиться прямо с сайта.

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

Адрес этой странички будет выглядеть примерно так:

https://stem.fomalhaut.me/channel?id=test

Где test это ID вашего канала.

Когда робот будет вам отвечать, это будет видно в логе. Примерно так:

 

oiQnnAP.png

 

А теперь - тайная фича.

Находясь на страничке канала, как на скриншоте, вы можете приписать к адресу дополнительный флаг: &render=true.

Полный адрес станет выглядеть примерно так:

https://stem.fomalhaut.me/channel?id=test&render=true

И начиная с этого момента, все входящие сообщения от компьютера в OpenComputers будут не отрисовываться в лог, а попадать в JS функцию eval(...).

 

Что это значит?

Те кто имел дело с JS уже наверное поняли все последствия.

Но я поясню.

Это значит, что компьютер OpenComputers может прислать сообщение с JS кодом, и сайт Stem этот код выполнит.

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

 

Поиграем

Ничего вредоносного мы делать конечно сейчас не будем.

Вместо этого, традиционно, попробуем сделать так, что сайт Stem превратится в сайт для управления светом в нашем доме в Майнкрафте.

 

Шаг первый. Подготовим дом.

 

zSTZAHB.png

 

Тут всё просто - стандартный компьютер, с интернет картой, от него кабель к I/O блоку, а на блоке - подопытная лампа.

 

На компьютер ставим Stem.

Например, ставим HPM такой командой,

pastebin run vf6upeAN

И потом пишем:

hpm install stem

Нажимаем Enter и готово.

 

Шаг второй. Нам нужен сайт.

Усложнять не будем, и наш революционный дизайн будет выглядеть так:

 

F9Jeomn.png

 

Что нам нужно сделать, чтобы сайт Stem превратился в то что нам надо?

Методом тыка, через консоль браузера определяем, что достаточно выполнить такой код:

document.body.innerHTML = "
  <style>button:active { background: #fac700; }</style>
  <button onclick=\"sendMessage(\'toggle\')\">Toggle Light</button>
";
document.body.style.alignItems = "center";

Первой строкой мы просто заменяем всё содержимое тега <body> на то что нам надо. Я добавил еще немного косметики в виде стиля для кнопки. Вторая строка - тоже косметика, я просто поправил стиль на теге <body> чтобы кнопочка была посередине.

Один важный ньюанс - на кнопке повешено свойство onclick с кодом sendMessage("toggle").

Таким образом, когда пользователь тыкнет по кнопке, мы отправим сообщение обратно в OpenComputers.

Функцию sendMessage нам дает веб-клиент Stem. Ей можно безвозмездно пользоваться в своих целях.

 

Шаг третий. Соединяем это все вместе.

Теперь надо набросать программку для нашего компьютера в Майнкрафте, чтобы он выслал подготовленную JS-"бомбу" по нашему сигналу.

 

Эники, беники... выходит что-то такое:

local event = require('event')
local stem = require('stem')
local side = require('sides')
local com = require('component')
local redstone = com.isAvailable('redstone') and com.redstone or nil

local channel = "test"
local layout = [===[
  document.body.innerHTML = "\
    <style>button:active { background: #fac700; }</style>\
    <button onclick=\"sendMessage(\'toggle\')\">Toggle Light</button>\
  ";
  document.body.style.alignItems = "center";
]===]
local lampSide = side.top
local lampTurnedOn = false

print("Connecting to the #" .. channel .. " STEM channel...")
local server = stem.connect('stem.fomalhaut.me')
server:subscribe(channel)
print("Done.")
print("Press [q] to quit.")

while true do
  local name, a, b = event.pull()
  if name == "stem_message" then
    local message = b
    if message == "connect" then
      print("Someone wants to connect - sending the layout...")
      server:send(channel, layout)
    elseif message == "toggle" then
      if redstone ~= nil then
        if not lampTurnedOn then
          redstone.setOutput(lampSide, 16)
          lampTurnedOn = true
        else
          redstone.setOutput(lampSide, 0)
          lampTurnedOn = false
        end
      end
    end
  elseif name == "key_down" then
    local char = b
    if char == 113 then break end
  end
end

server:disconnect()

Я думаю тут большая часть очевидна и понятна.

Мы подключаемся к серверу Stem, подписываемся на нужный канал и внимательно слушаем входящие сообщения.

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

Этот код прилетит к пользователю, и, если пользователь смотрит страницу с включенной опцией render=true, код сработает и перерисует страницу.

Если опция будет отключена - он просто увидит код в логе, как простое сообщение.

 

Шаг четвертый. Тестируем.

Откроем наш канал по ссылке:

https://stem.fomalhaut.me/channel?id=test&render=true

Появится пустой лог.

Запустим программу в OpenComputers.

Она отрисует наше приветствие, что-то вроде:

Сonnecting to the #test STEM channel...
Done.
Press [q] to quit.

Теперь пишем на сайте команду connect.

Если мы все сделали правильно, и Stem не заглючил, интерфейс сайта исчез, и вместо него появилась наша кнопка.

Нажимаем её.

Вуаля! Дома зажегся свет.

 

eRkZWBH.png

 

Постскриптум

Это конечно же недокументированная хакерская фича, которую можно считать альфа-версией.

 

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

Если кто-нибудь предоставит мне сценарий (прямо по шагам), при котором 100% срабатывает баг - буду очень рад и пофиксить его будет легче.

 

С помощью описанной фишки можно придумать много хрени. Я показал самое простое что пришло в голову.

Уверен, ваша фантазия будет покруче моей )

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

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

Гость
Ответить в тему...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...