mirror of
https://github.com/openmax-server/server.git
synced 2026-07-11 14:30:12 +03:00
fc6ec5eec5
* Различные фиксы (#14)
* Исключаем только ошибку валидации
* Небольшие правки вебсокета тамтама
* Теперь номера брутить чутка сложнее
* Авторизация теперь проверяется для некоторых команд
* Теперь проверяется orign у вебсокета тамтама
* Дополнил пример env
* Починил немного сокет тамтама
* Теперь все должно работать исправно
* Документация: описал про SESSION_INIT
* Update deviceId description in tamtam_ws.md
* feat: 16 опкод для обновления профиля
* feat: 23 опкод для регистрации, смс шлюз, докер
* SQLite: Ошибка
И вообще не юзайте sqlite пожалуйста, он баганный
* Серверный конфиг снова сломался
* Починил изменение профиля
* История сообщений (вроде как даже работает)
* Дополнил немного 48 опкод, и починил отдачу истории в избранном (избранное все равно не работает)
* Доделал авторизацию в ТамТаме
* Швырнул архитектуру, чтобы позже объединить контроллеры веба и сокета в одно, а также разделить процессоры
* Удалил tamtam.proto, поскольку нигде больше не используется
* Поделил процессоры в таме
* Коды стран
* Генерируем айди, за вместо того, чтобы писать его попорядку
* Вынес список участников чата в отдельную таблицу
* Теперь мы не должны отправлять 128 опкод самому себе. вроде
* ТамТам: реализация 32 опкода. Надеюсь, будет работать
* ТамТам: обработчик 5 и 1 опкода
* ТамТам: починил 32 опкод и добавил серверный конфиг. Избранное больше не добавляется в список чатов
MAX: починил 32 опкод
* TT: oops
* MAX: заглушка в 158 опкоде
* Common: поправил 1 прикол
* TamTam: websocket transport for web version
* TamTam && MAX: история (в мохе она вроде теперь получше работает)
* Правка контроллеров небольшая
* MAX: Разделил процессоры
* TG Bot: переписал на aiogram
* Common: фикс года
* Начальная реализация транспорта ws для max web и прочие улучшения
* Common: добавил сжатие lz4
* Исправление конфликтов
* TT: фикс вебсокета
* Fix OpenMAX mobile compatibility and Telegram auth fallback (#30)
* Fix OpenMAX mobile compatibility and Telegram auth fallback
* Common: Убрал скобку в конфиге
---------
Co-authored-by: Alexey Polyakov <starwear3000@mail.ru>
* MAX: заглушка для баннеров, правка пакета со списком жалоб, отдача контактов и прочие улучшения
* oops
* MAX: Рабочие баннеры
* MAX: обновление настроек приватности
* MAX: пуши через firebase (особо не тестил, вроде работает)
* MAX: Рефактор папок
* MAX: фикс версий < 25.8.0
* MAX: отдача черного списка
* Теперь ID пользователей идут по порядку, как и раньше
* MAX: создание папок
* MAX: oops
* MAX: добавление/удаление контактов, статусы
* MAX & TT: теперь в качестве страны локации используется настоящая страна пользователя, а также зафиксировал версии библиотек в зависимостях
* TT: ну вроде шире поддержка, а вообще обратная совместимость с максом клас
* oops
* TG Bot: возможность включения белого списка
* Решение проблемы обработки sigterm
* nothing
* fix
* TG Bot: fix
* TG Bot: fix username
* MAX && TT: общение в таме, и корректировки под веб морду
* MAX: Почистил серверный конфиг
* nothing
* MAX: web fix
* MAX: web fix 2
* oops
* nothing
* MAX: теперь для избранного не сравниваем айди с нулём
* Вынес sqlite в отдельный модуль
* MAX: блокировка и разблокировка контакта
* oops
* TT: тоже самое что в макс
* MAX && TT: обновление контакта
* MAX: добавление контакта по номеру телефона
* MAX: исправление уязвимости с избранными
* Генерируем айди пользователей рандомно (опять, да)
* update sql scheme
* Фикс сборки избранного
* Попытка починить историю (спойлер, нихуя не получилось)
* MAX: история таки заработала — cid/link/reactionInfo обязательны в схеме
Десктопный MAX подключается через TCP (mobile-протокол) и парсит
msgpack по фиксированной схеме. Если в сообщении выпадает любое из
полей — клиент молча обрывает соединение. После 87cfc19 как раз
такие условные `if elements: ...` / `if link: ...` (а link и
reaction_info там всегда были `{}`, то есть falsy) вырезали поля
из ответа CHAT_HISTORY и MSG_SEND, чем и сломали историю.
- src/common/tools.py: новый build_message_dict() — единая сборка
тела сообщения, где все поля (id, cid, time, type, sender, text,
attaches, elements, reactionInfo, link) присутствуют ВСЕГДА.
get_last_message переписан через него.
- src/oneme/processors/history.py: chat_history использует
build_message_dict вместо ручной логики с условными if-ками.
- src/oneme/processors/messages.py: msg_send.bodyMessage теперь
отдает cid / reactionInfo / link даже пустыми и приводит id
к int для mobile, str для web.
Цепная польза: auth.py LOGIN bootstrap (через generate_chats →
get_last_message) и search.py тоже теперь шлют корректную схему.
* MAX: bootstrap-история в LOGIN — клиент перестал думать что всё уже синканулось
В ответе LOGIN сервер слал messages: {} и chatMarker: 0. Десктопный
клиент в этом случае считает, что локальная история уже синхронизирована
со старого запуска, и НЕ отправляет CHAT_HISTORY (49) при открытии чата.
В окне видно только lastMessage из chats[], а вся реальная переписка —
ничерта.
- src/common/tools.py: collect_bootstrap_history(chatIds, ...) —
собирает карту {chatId: [последние N сообщений]}, в т.ч. избранное
под клиентским id = senderId ^ senderId.
- src/oneme/processors/auth.py: подсовываем эту карту в
payload.messages, chatMarker = текущее время вместо 0.
* fix(chat history): фикс
* fix(chat history): фикс
* fix(chat history): фикс
* fix(chat history): фикс
* fix(chat history): фикс
* fix(chat history): фикс
* fix(chat history): фикс
* MAX & TT: теперь полноценный чёрный список
* TT: регистрация через клиент
* Вроде как нормальные заглушки под ассеты
* maybe fixes
---------
Co-authored-by: WowInceptionGood <143893762+WowInceptionGood@users.noreply.github.com>
Co-authored-by: zavolo <me@kirillka.ru>
Co-authored-by: Aleksandr Kosachev <38947781+gohryt@users.noreply.github.com>
152 lines
4.5 KiB
Python
152 lines
4.5 KiB
Python
# Импортирование библиотек
|
|
import asyncio
|
|
import logging
|
|
import signal
|
|
import ssl
|
|
import sys
|
|
import traceback
|
|
|
|
from common.config import ServerConfig
|
|
from common.push import PushService
|
|
from common.sqlite import SQLitePoolCompat
|
|
from oneme.controller import OnemeController
|
|
from tamtam.controller import TTController
|
|
from telegrambot.controller import TelegramBotController
|
|
|
|
# Конфиг сервера
|
|
server_config = ServerConfig()
|
|
|
|
async def init_db():
|
|
"""Инициализация базы данных"""
|
|
|
|
db = {}
|
|
|
|
if server_config.db_type == "mysql":
|
|
import aiomysql
|
|
|
|
db = await aiomysql.create_pool(
|
|
host=server_config.db_host,
|
|
port=server_config.db_port,
|
|
user=server_config.db_user,
|
|
password=server_config.db_password,
|
|
db=server_config.db_name,
|
|
cursorclass=aiomysql.DictCursor,
|
|
autocommit=True,
|
|
)
|
|
elif server_config.db_type == "sqlite":
|
|
import aiosqlite
|
|
|
|
raw_db = await aiosqlite.connect(server_config.db_file, isolation_level=None)
|
|
raw_db.row_factory = aiosqlite.Row
|
|
db = SQLitePoolCompat(raw_db)
|
|
|
|
# Возвращаем
|
|
return db
|
|
|
|
|
|
def init_ssl():
|
|
"""Создание контекста SSL"""
|
|
# Создаем контекст SSL
|
|
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
|
ssl_context.load_cert_chain(server_config.certfile, server_config.keyfile)
|
|
|
|
# Возвращаем
|
|
return ssl_context
|
|
|
|
def set_logging():
|
|
"""Настройка уровня логирования"""
|
|
# Настройка уровня логирования
|
|
log_level = server_config.log_level
|
|
|
|
if log_level == "debug":
|
|
logging.basicConfig(level=logging.DEBUG)
|
|
elif log_level == "info":
|
|
logging.basicConfig(level=logging.INFO)
|
|
else:
|
|
logging.basicConfig(level=None)
|
|
|
|
|
|
async def main():
|
|
"""Запуск сервера"""
|
|
|
|
set_logging()
|
|
db = await init_db()
|
|
ssl_context = init_ssl()
|
|
clients = {}
|
|
push_service = PushService(server_config.firebase_credentials_path)
|
|
|
|
async def api_event(target, eventData):
|
|
target_clients = api.get("clients", {}).get(target, {}).get("clients", [])
|
|
|
|
for client in target_clients:
|
|
await controllers[client["protocol"]].event(target, client, eventData)
|
|
|
|
# Если у пользователя нет активных подключений
|
|
# и это новое сообщение - отсылаем пуш
|
|
if not target_clients and eventData.get("eventType") == "new_msg":
|
|
message = eventData.get("message", {})
|
|
sender_id = message.get("sender")
|
|
text = message.get("text", "")
|
|
chat_id = eventData.get("chatId", "")
|
|
msg_id = message.get("id", 0)
|
|
await push_service.send_to_user(
|
|
db, target,
|
|
sender_id=sender_id,
|
|
msg_id=msg_id,
|
|
chat_id=chat_id,
|
|
text=text,
|
|
)
|
|
|
|
api = {
|
|
"db": db,
|
|
"ssl": ssl_context,
|
|
"clients": clients,
|
|
"event": api_event,
|
|
"origins": server_config.origins,
|
|
}
|
|
|
|
controllers = {
|
|
"oneme": OnemeController(),
|
|
"tamtam": TTController(),
|
|
"telegrambot": TelegramBotController(),
|
|
}
|
|
|
|
api["telegram_bot"] = controllers["telegrambot"]
|
|
|
|
loop = asyncio.get_running_loop()
|
|
running_tasks = []
|
|
|
|
def _shutdown(sig):
|
|
logging.info(f"Получен сигнал {sig}, завершаем все задачи...")
|
|
for task in running_tasks:
|
|
task.cancel()
|
|
|
|
if sys.platform != "win32":
|
|
for sig in (signal.SIGTERM, signal.SIGINT):
|
|
loop.add_signal_handler(sig, _shutdown, sig)
|
|
|
|
coros = [controller.launch(api) for controller in controllers.values()]
|
|
running_tasks.extend(asyncio.create_task(coro) for coro in coros)
|
|
|
|
# Запускаем контроллеры
|
|
try:
|
|
await asyncio.gather(*running_tasks)
|
|
except asyncio.CancelledError:
|
|
logging.info("Все задачи завершены")
|
|
except Exception as e:
|
|
logging.error(
|
|
f"Произошла неизвестная ошибка: {e}"
|
|
)
|
|
traceback.print_exc()
|
|
finally:
|
|
if hasattr(db, 'close'):
|
|
db.close()
|
|
await db.wait_closed()
|
|
elif hasattr(db, 'connection') and hasattr(db.connection, 'close'):
|
|
await db.connection.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|
|
|