Зайду издалека. Мы тут нашей дружной семьёй из двух человек
периодически играем в копуктерные игры. В основном работает это
так: один из ПК является сервером (который запускается непосредственно
из клиента игры), а второй к нему подключается. В целом схема удобна
тем, что без всяких предварительных ласок позволяет начать исследовать
новый мир нашей компанией. Но крайне неудобна тем, что один ПК начинает
зависеть от другого ПК. Грубо говоря, делимся на слейва и
мастера, и слейв не может поиграть, если
мастер не в игре.
Очевидным решением становится выделение сервера игры на отдельный
физический сервер. Ну, вообще, есть платные варианты, в частности для
Minecraft их — пруд пруди. Но где бы я был, если бы сам себе не
развернул какой-то там сервер игры. Сидел бы без Celeron 5105 (на тот
момент) в кладовке над дверью, наверно.
Выяснилось, что сервер для игрушек довольно хорошо грузит процессор,
даже когда не обслуживает игроков. Если Paper в целом щадит ресурсы
своими оптимизациями (например, сотни однотипных предметов, выброшенных
под ноги, обсчитываются как будто это один предмет), то ванильный
сервер, необходимый для установки модификаций, прокаливал мой Celeron до
65 °C и выше. В простое, конечно, не так страшно, но благодаря
компоновке mini PC камешек ниже 50 °C опускался, только когда диск
отваливался, и все сервисы падали.
М-да, далековато я для раздела про портфолио начал. В целом,
сегодняшняя самоделка проста как три копейки, поэтому я могу
позволить потянуть хронометраж. Потерпите, ещё чуть-чуть осталось.
В целом, понятно, что сервер необязательно держать включенным всё
время: гаси, когда не играешь; поднимай, когда играешь. Ну, допустим, я
— погроммист — могу хоть с телефона запрыгнуть на сервер и
поднять сервис. Но играй я один — обошёлся бы без сервера. В целом, я
чуть было не завязался на restartor (предыдущий мой проект). Кнопки уже
есть, в сервисе ничего менять не нужно.
Но как же дёшево мне было написать простенький скрипт, который делает
элементарную задачу: слушает порт, принимает соединение, сразу его
разрывает и поднимает сервис. От азарта успеха я тут же добавил туда
проверку наличия пользователей на сервере, благо у Minecraft есть RCON,
который позволяет элементарным образом получить список игроков со
стороны, не заходя в игру. Оставалось обернуть это в цикл и вуаля:
сервер игры магическим образом поднимался (надо было потупить 10 секунд
в меню подключений клиента) и опускался спустя некоторое время после
выхода последнего игрока. Сколько киловатт он мне сэкономил — страшно
сказать, перерывы в игре могли длиться месяцами.
В целом, на этом история этого скрипта закончилась примерно на два
года, хотя субъективно кажется, что на вечность. Пока — что? Пока не
появилась вторая игра. Ну да, как видно из моего повествования, нечасто
я в такие игры соло играю. Ну, можно было бы скопипастить скрипт,
заменить все вхождения “Minecraft” на “Palworld” и забыть ещё на два
года. Но, опять же, где бы я был, если бы так сделал.
Хорошенько порефакторив этот скрипт с помощью нейро-болвана, я в
целом получил универсальный сервис, который способен закрыть мои будущие
потребности. Все переменные параметры вынесены в конфигурационный файл.
Для поддержки нового игрового сервера достаточно добавить новую секцию в
конфигурационный файл. Там нет чего-то специфичного конкретно для игр,
просто у меня пока не было нужды другие сервисы гасить за
неактивность.
К слову, в моей кладовке сейчас трудится Core Ultra 5 225 в
форм-факторе радиолы. Как-нибудь попозже я и о ней расскажу.
Wakepeka-ng
Как-то так получилось, что на запале от restartor'а я так сильно разогнался, что реанимировал свой старый проект — wakepeka. Приложение для умных часов, которое умеет включать и выключать PC с помощью Wake-on-LAN и удалённого исполнения команд на базе самого restartor. Больше про него особо нечего рассказывать, разве что про ощутимую боль от современных мобильных технологий: на реализацию одной этой кнопки ушло порядка пяти часов. Вся логика вышла в полчаса, если не считать время, потраченное на restartor.
Restartor
Сделать этот проект меня побудила лень. Лень разбираться с проблемами с моим прозрачным прокси, который периодически тупит. Чаще всего помогает перезапуск Tor, иногда приходится перезапускать всю свою связку Bind9+Squid+Privoxy в отдельном netns, т.к. они у меня одним unit'ом поднимаются. И сделать это не так-то просто, ведь ssh-ключ с телефона на сервер перекидывать мне тоже лень. То есть, я, условно, не дождавшись новых картинок в ленте Instagram'а, подключался ssh-клиентом к рабочему ПК, с него заходил на сервер и только тогда мог от руки вбить команды перезапуска.
Но вот сегодня я решил, что пора прекращать это терпеть, и будет круто перезапускать эти сервисы одной кнопкой. Лучше двумя, т.к. Tor перезапускается заметно быстрее моего монструозного unit'а, а закрывает вопрос в 90% случаев. В этот момент я и нарисовал приложенную схему:
Тут можно увидеть три домена данной схемы: WEB, в который я собрался тыкать пальцем, CLI, который должен быть мозгом всей схемы, и сами демоны, на которые я буду воздействовать на примере Tor. Стрелочками указано направление воздействия. Стрелочки, идущие в морду, обозначают сбор информации для отображения в самой морде, однако я пока не придумал: какую информацию я бы хотел видеть.
При подборе инструментов реализации я шёл по пути наименьшего сопротивления. Для WEB это хрестоматийный стек технологий: HTML, JS, CSS, PHP. По задумке, WEB должен получать мой клик и вызывать CLI с нужными аргументами. При этом весь WEB помещается в корневом каталоге виртуального веб-сервера.
Для CLI я использовал свой любимый инструмент для ситуаций, когда речь заходит про "высокая скорость разработки" и "взаимодействие с системой" — Python. Как видно на схеме, CLI попилен на две части. Сделано это по следующим причинам:
Упрощение интерфейса. Из PHP очень легко вызвать скрипт на Python, из Python очень легко обмениваться обычными TCP-пакетами с текстовыми командами.
Разграничение прав. Я не хочу запускать веб-сервер из-под суперпользователя.
Оставляю за собой право, всё-таки, использовать эту утилиту в консоли. Ведь, если я сижу с ПК, мне будет гораздо удобнее просто выполнить команду, чем целиться мышкой/пальцем по кнопкам и прочим свистулькам для педиков. А транспорт в виде TCP позволяет иметь CLIent на одной машине, а сервер — на другой.
Сам же сервер на Python запускается таким же unit'ом systemd и ждёт команды от клиентской части. Каждая команда сверяется со списком разрешённых к перезапуску демонов. Как только команда service отдаст контроль вызывающему скрипту, весть об успешности операции возвращается в морду тем же путём.
В целом, у этого pet-проекта есть потанцевал стать чем-то больше: его можно научить запускать самые разные команды, ещё и останется возможность их контроллировать, аутентифицировать и т.д. Правда, пока я не выкладывал исходники в открытый доступ. На всякий случай.
Видео я вам тоже не приготовил: не знаю что снимать. Но могу показать скриншоты:
CallMe
Честно говоря, мне уже самому кажется, что у меня навязчивая идея запихать телеграм-бота в любую мою поделку. Но это та утилитка, которая действительно мне нужна, как и торрент-оповещалка, например.
Суть утилитки: передаёте ей команду своего shell'а или путь к программе с нужными аргументами, она это исполняет и оповещает вас в чате телеграма.
Теперь на работе мне не нужно каждые полминуты проверять: а не собрался ли там проект. Просто жду оповещения и иду проверять свои правки.
Пока что утилитка только оповещает. В будущем хочу сделать stdout в чат, но к этому нужно будет подойти ответственно, т.к. если слать всё подряд, то после запуска того же make мы рискуем получить пару сотен непрочитанных сообщений в чате.
Работу утилитки можно посмотреть в ролике, а заглянуть под капот можно на гитхабе
Космические весы
Ещё один мой проектик, на этот раз на богомерзком C#. Он у меня какое-то время был этаким домашним прикладным язычком. Я никогда его особо не изучал, но если нужно написать что-то под Шиндоус, то это к нему. Хотя в какой-то момент я поставил Mono и... Сейчас не об этом.
Есть такие весы от Miezu, которые умеют в Bluetooth. И вот один мой предприимчивый знакомый решил сделать такой аппарат: встаёте на весы, а на экранчике появляются числа, соответствующие вашему весу, но на разных планетах Солнечной системы. Поэтому мне сунули копеечку и весы в зубы, и я пошёл писать Оо
Собственно, рассказывать особо нечего. Единственное, я очень круто выглядел, когда читал документацию по bluetooth. После того, как я понял, как это работает, я быстренько набросал примерчик на python. Потому, что могу. Но мне не хотелось оставлять это на python'е потому, что не имею опыт разработки на python'е под десктоп с графоном и т.д. Итак, так я пришёл к C#. В рамках традиции я, конечно же, не буду рассказывать про особенности реализации. Однако, в этот раз я не могу выложить ссылку на репу.
LogiLED: ambient light
Сейчас я сижу на Ubuntu. Ещё пару лет назад я пользовался ОС Шиндоус. А ещё я очень люблю компьютерную периферию. Из последнего последовало то, что я люблю устройства фирмы Logitech. А вот разработчики софта у них любят WinAPI. Поэтому определённый ряд устройств, купленных за много денег по функционалу превратились в обычные устройства. Целый экран, на который были выведены показания различных датчиков, превратился в светящийся кирпич с переходом на Ubuntu.
В какой-то момент я обнаружил, что моя клавиатура определяется двумя устройствами... И пробросил одно из них в виртуалку. И это сработало, заветный экранчик засветил часами. Но этого мало. Раньше я пользовался одним (кажется, польским) апплетом, который подстраивал подсветку клавиатуры в соответствие с тем, что происходит на экране. На экране трава — горит зелёный свет, на экране пустыня — клавиши загораются жёлтым. Но откуда программе в виртуалке знать, что у меня на экране основной системы?
Последнее время я достаточно много кодил в виду летней школы Eltex. А тут как бы допиливать модули ядра влом, а руки чешутся. И в какой-то момент... Да, я решил написать всё сам.
Недолго думая, я лёг спать, а на утро полез на просторы интернета в поисках алгоритмов определения доминантных цветов. Потому что SDK у Logitech довольно простое и понятное, интерфейсом предусмотрены даже какие-то эффекты (пульсация, мигание и т.д.), которые без труда можно было бы реализовать самому. Про захват картинки я вообще молчу: пара строчек с libX11.
И вот тут я не нашёл ничего подходящего. Узнал пару вещей, вроде того, что человек разные цвета воспринимает с разной чувствительностью. Это пригодилось при определении яркости. По итогу, лезть в статистику и матан я не решился и тупо взял среднее арифметическое от суммы векторов RGB. Это черевато тем, что, например, если картинка имеет в себе довольно много цветов, то на выходе мы рискуем получить белый. По поводу белого, кстати. Я решил убрать все оттенки от чёрного до белого. Во-первых: потому, что чёрный не светит, а во-вторых: потому, что если, например, поместить красную картинку в центр экрана, а вокруг всё залить, например, белым, то и на выходе получится белый цвет. В идеале, я хотел бы, чтобы алгоритм учитывал ещё и контрастность цвета. Например, если на тёмно-синем автомобиле декоративные элементы окрашены в яркий (красный, например) цвет, то я хотел бы получить на подсветку именно красный, а не бледно-скучно-синий.
Очередной проект, который появился, потому что был нужен — Telegram-бот для оповещения меня о скачанных мной торрентах. Репа здесь.
Вообще говоря, изначально идея принадлежала матери. Но, естественно, я сразу понял, что мне тоже нужна такая штука. Поэтому я решил не откладывать дело в долгий ящик, как остальные 100500 моих идей, а взять свой python в руки и таки реализовать это!
"Тык!" / Tap!
Вот тут, как говорится сейчас в "этих наших интернетах" настала действительно "жиза". Потому что следующий мой проектик появился именно потому, что он был нужен мне. Как и все, но в этот раз намного больше, чем обычно. Всё началось в университете, когда возникла такая дисциплина "вещания" докладов по очереди: один кликает слайд, другой читает. Когда этот другой садился, на место первого садился новый человек, а тот шёл рассказывать свой доклад.
Именно в ходе такого выступления я (потому что я придурковатый, видимо) начал говорить "тык" каждый раз, когда нужно переключать слайд. Это было той отправной точкой, когда меня начали слушать на докладах. Действительно, я уже не то что через одногруппников — я через конференцию с половиной своей кафедры (афигительно свёрстанный пруф тут и ниже скрином приложен)
Итак, суть в чём: предоставить сервис для показа презентаций. Да, подавляющая часть компьютеров, с которых показываются презентации имеют на себе установленную прогу PowerPoint, НО: я, например, как и 5% юзеров десктопов (юзверей линуха) не имею никакой возможности установить непосредственно на хост-систему Microsoft Office. Я обычно пользуюсь LibreOffice и прекрасно понимаю, что о 100%'ой совместимости с микромягким офисом можно не мечтать. Есть выход — юзать PDF. Но тут мы напарываемся на такой сук, что есть необходимость двигаться, махать руками, взаимодействовать с публикой и иметь возможность "тыкать" презентацию.
Тут поподробнее. Я много раз видел людей, которые втыкали донгл от собственной беспроводной мыши. Некоторые люди вспоминают о кликерах. Кликеры — действительно удобная вещь. Только видел я их исключительно в магазинах.
— Четыре телека?
— Да пожалуйста!
— Самый дешманский пульт для презентаций?
— Ога, а унитаз золотой не поставить?
Таким образом, я подвёл к основному функционалу данного сервиса — "тыканье" слайдов. Открываете страничку в браузере на проекторе, открываете страничку в браузере на телефоне — profit! Сделав свой телефон хостом на данном показе, гостевые устройства начинают повторять переключение слайдов. Ну, а когда вы можете переключать слайды на проекторе простым свайпом в телефоне, возникает вопрос: неужели все эти технологии пущены практически вникуда? Когда гостевым устройством может стать любой телефон или ноутбук в зале, неужели весь функционал в таком случае — смотреть презентацию на родном устройстве?
И тут я пришёл к выводу, что это — та точка, которая является просто бесконечным пространством для фантазии. Ну сёрьёзно: было бы прикольно, если бы слушатель, прежде чем задать вопрос, указал, что именно ему непонятно? "Тыкнул" бы себе в экран, а это нажатие увидели все. Интерактивная указка..? Наверно, так и назову.
Да и неплохо было бы засунуть конспект выступающему. Да ещё чтоб с "якорями", чтобы текст проматывался просто от перелистывания слайдов.
В какой-то момент мне надоело ждать пока включится мой комплюхтер. Не то что бы он сильно долго включается, тем более после перехода на линукс, всегда хочется просто сесть и начать делать то, что собирался.
Я нашёл выход в замечательной технологии Wake-on-LAN, но для неё, без проброса портов мне приходилось подключаться к роутеру по ssh. Дело решилось бы кучей готовых приложений под это дело: от send'еров "магических" пакетов, до ssh-кнопок. Но я же молодой программист. Я решил пойти своим путём. Добро пожаловать под кат.(когда-нибудь я его изобрету)
Собственно, Sony Add-ON SDK ещё можно найти на просторах интернетов, но я этот архивчик храню и оберегаю уже давно. Вообще говоря, я не очень люблю Java, поэтому особо не замарачивался и открыл проект из примеров. Он так и называется "HelloLayouts".
Решение использовать SSH пришло от того, что я так и делал, только ручками. Только потом мне пришла идея положить небольшой сервер на роутер. Но от неё я отказался. Много работы, а особой выгоды я не получу. Помогает мне в этом деле библиотека JSch. Сейчас авторизуюсь по ключу, раньше было по паролю. Но сейчас у меня отключена авторизация по паролю.
На этом можно закончить: я не особо распылялся и делал всё под свой конкретный случай. Чтобы такое выкатить в продакшн, нужно слишком сильно заморочиться, потому что для работоспособности сейчас должно сойтись множество звёзд(белый ip, роутер на openwrt/его форках). Не говоря о том, что надо будет переписывать приложение под Android Wear, потому что мои часы на своей ОС'и, и никогда не были особо популярными. Даже сейчас в плей маркете меньше 300 приложений для них, половина из коротых — циферблаты.
js-photo-slider
Как-то раз нам пригодился слайдер в лэндинг. Я заглянул в исходник странички и ужаснулся от того, сколько там фреймворков подключено. Да на моём телефоне такое грузилось бы вечность. В виду чего было решено взять и написать всё на "ванильном" JavaScript'е!
В JavaScript я чувствую себя более, чем уверенно, поэтому уселся делать свой слайдер. Увидеть его вы можете вот здесь, а так же у него имеется открытая репа здесь
К сожалению, на том лэндосе он нам не пригодился, но мой слайдер получил развитие: в частности, дикую оптимизацию DOM, в моём последующем проекте под названием "Тык!". Я давно не подходил к нему, но думаю, что и мой блог не обойдёт стороной эту фичу...