From 2be8beb9104b8185886f36d68769bd25ce01aa08 Mon Sep 17 00:00:00 2001 From: Alexey Smirnov Date: Sun, 22 Mar 2026 21:35:07 +0300 Subject: [PATCH] lioshik, cahekska, kiruxalight tic tac toe beagle --- .../.be | 1 + .../CLAUDE.md | 14 + .../Makefile | 10 + .../README.md | 56 +++ .../index.html | 352 ++++++++++++++++++ .../proxy.py | 54 +++ 6 files changed, 487 insertions(+) create mode 100644 04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/.be create mode 100644 04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/CLAUDE.md create mode 100644 04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/Makefile create mode 100644 04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/README.md create mode 100644 04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/index.html create mode 100644 04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/proxy.py diff --git a/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/.be b/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/.be new file mode 100644 index 00000000..2acf7117 --- /dev/null +++ b/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/.be @@ -0,0 +1 @@ +//tictactoe/app \ No newline at end of file diff --git a/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/CLAUDE.md b/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/CLAUDE.md new file mode 100644 index 00000000..0bf40270 --- /dev/null +++ b/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/CLAUDE.md @@ -0,0 +1,14 @@ +Этот репозиторий создан для того чтобы написать простое веб приложение на JavaScript, которое реализует игру в крестики и нолики. Игра должна быть коллаборативной. + +Само по себе задание довольно простое. Но все осложняется тем, что нужно использовать кастомную систему контроля версий Beagle. +Это собственная разработка нашего преподавателя на курсе по децентрализованным системам (на этом курсе нам и задали задания с крестиками и ноликами). + +Тебе обязательно нужно прочитать эти две статьи чтобы понимать что это за система контроля версий +1. https://replicated.wiki/blog/partI.html +2. https://replicated.wiki/blog/partII.html + +Поскольку эта система контроля версий имеет HTTP-api, приложение должно быть как-бы "задеплоино" в эту систему контроля версий. То есть предполагается, что человек в браузере просто откроет ссылку в системе beagle на какой-то один файл (например index.html) и у него запуститься приложение. + +Важный нюанс: в качестве БД должен использоваться тоже beagle. То есть какие-то состояния игроков и/или игр тоже должны храниться внутри Beagle. + +Для того чтобы понять какими командами можно поднимать beagle сервер, и пользоваться им стоит изучить сам репозиторий с проектом https://github.com/gritzko/librdx. Вроде как в нем есть также какая-то библиотека, для того чтобы делать запросы в beagle репозиторий прямо из браузера. \ No newline at end of file diff --git a/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/Makefile b/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/Makefile new file mode 100644 index 00000000..22276391 --- /dev/null +++ b/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/Makefile @@ -0,0 +1,10 @@ +.PHONY: serve commit proxy + +serve: + be-srv 8080 + +proxy: + python3 proxy.py 9090 + +commit: + be post diff --git a/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/README.md b/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/README.md new file mode 100644 index 00000000..a8b21dde --- /dev/null +++ b/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/README.md @@ -0,0 +1,56 @@ +# Крестики-Нолики на Beagle + +Коллаборативная игра в крестики-нолики. В качестве хранилища и хостинга используется система контроля версий [Beagle](https://github.com/gritzko/librdx). + +## Зависимости + +- Собранный `be` и `be-srv` из [librdx](https://github.com/gritzko/librdx) (см. инструкцию по сборке в README репозитория) +- Python 3 + +## Быстрый старт + +### 1. Инициализация Beagle-репозитория + +```bash +be post //tictactoe/app +``` + +### 2. Коммит файлов в Beagle + +```bash +make commit +``` + +### 3. Запуск Beagle-сервера + +```bash +make serve +``` + +Сервер запустится на порту 8080. + +### 4. Запуск прокси (в отдельном терминале) + +```bash +make proxy +``` + +Прокси запустится на порту 9090. Он нужен потому что HTTP-парсер Beagle некорректно обрабатывает заголовки от браузера. + +### 5. Открыть в браузере + +``` +http://localhost:9090/index.html +``` + +Для игры вдвоём откройте эту ссылку в двух вкладках/браузерах. + +## Полезные команды + +```bash +# Посмотреть содержимое файла в Beagle +curl http://localhost:8080/game_index.txt + +# Посмотреть конкретную игру +curl http://localhost:8080/game_.txt +``` diff --git a/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/index.html b/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/index.html new file mode 100644 index 00000000..ff2a0641 --- /dev/null +++ b/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/index.html @@ -0,0 +1,352 @@ + + + + + + Крестики-Нолики + + + +
+

Крестики-Нолики

+ + +
+ +
+ +
+ + +
+

Привет, !

+ + +

Открытые игры:

+
    +
    + + +
    +
    +
    + +
    +
    + + + + diff --git a/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/proxy.py b/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/proxy.py new file mode 100644 index 00000000..5393b07a --- /dev/null +++ b/04-formats/tic-tac-toe-lioshik-caheska-kiruxalight/proxy.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +"""Proxy server that forwards requests to Beagle. + +Beagle's HTTP parser has issues with browser requests (too many headers). +This proxy strips unnecessary headers before forwarding. +""" + +import http.server +import urllib.request +import sys + +BEAGLE_PORT = 8080 +PROXY_PORT = int(sys.argv[1]) if len(sys.argv) > 1 else 9090 + + +class BeagleProxy(http.server.BaseHTTPRequestHandler): + def log_message(self, fmt, *args): + sys.stderr.write(f"{args[0]}\n") + + def do_GET(self): + self._forward() + + def do_POST(self): + self._forward() + + def _forward(self): + cl = int(self.headers.get("Content-Length", 0)) + body = self.rfile.read(cl) if cl > 0 else None + + req = urllib.request.Request( + f"http://localhost:{BEAGLE_PORT}{self.path}", + data=body, + method=self.command, + ) + + try: + resp = urllib.request.urlopen(req, timeout=120) + data = resp.read() + self.send_response(resp.status) + self.send_header("Content-Length", len(data)) + self.send_header("Connection", "close") + self.end_headers() + self.wfile.write(data) + except urllib.error.HTTPError as e: + self.send_response(e.code) + self.end_headers() + except Exception: + self.send_response(502) + self.end_headers() + + +if __name__ == "__main__": + print(f"Proxy listening on :{PROXY_PORT} -> Beagle :{BEAGLE_PORT}") + http.server.HTTPServer(("", PROXY_PORT), BeagleProxy).serve_forever()