Compare commits

..

4 Commits

Author SHA1 Message Date
relyay cab75a58f8
Merge pull request #9 from relyay/fix
Some fixes
2026-03-10 21:19:54 +03:00
Alexey Polyakov 4bd632e6df Мелкие правки 2026-03-10 18:21:59 +03:00
WowInceptionGood 32a88e8b05 Update README 2026-03-10 13:55:50 +00:00
Anatoliy Esherkin a2d6be7b94
Добавил причины для жалоб (#4)
* Добавил причины для жалоб

* Update static.py

---------

Co-authored-by: WowInceptionGood <143893762+WowInceptionGood@users.noreply.github.com>
2026-03-10 16:37:35 +03:00
6 changed files with 53 additions and 39 deletions

1
docs/proto/oneme_tcp.md Normal file
View File

@ -0,0 +1 @@
TODO

View File

@ -1,3 +1,10 @@
> [!Caution]
>
> Проект находится на ранней стадии разработки и вероятно полон багов.
>
> Использование в профессиональных средах не рекомендовано.
# OpenMAX
Эмулятор сервера MAX и ТамТам
@ -15,6 +22,8 @@ https://t.me/openmax_alerts
Клиент может быть практически любым, главное условие - чтобы он был совместим с официальным сервером (`api.oneme.ru` / `api.tamtam.chat`).
На данный момент с сервером может работать последняя версия MAX (26.7.1), однако все тесты проходят на версии 26.5.0.
# Установка
1. Склонируйте репозиторий

View File

@ -109,7 +109,15 @@ class Static:
### Причины для жалоб
COMPLAIN_REASONS = [
# TODO: Было бы очень замечательно заполнить этот лист причинами для жалоб
"Порнография или эротика",
"Экстремизм или терроризм",
"Фейк",
"Мошенничество",
"Нарушение авторского права",
"Шокирующий контент",
"Персональные данные",
"Незаконная услуга",
"Это законно, но надо удалить"
]
### Заглушка для папок
@ -160,4 +168,4 @@ class Static:
"SAFE_MODE": False,
"M_CALL_PUSH_NOTIFICATION": "ON",
"QUICK_REPLY": False
}
}

View File

@ -102,20 +102,14 @@ class Tools:
# Выносим результат в лист
chats.append(
{
"id": row.get("id"),
"type": row.get("type"),
"status": "ACTIVE",
"owner": row.get("owner"),
"participants": participants,
"lastMessage": message,
"lastEventTime": messageTime,
"lastDelayedUpdateTime": 0,
"lastFireDelayedErrorTime": 0,
"created": 1,
"joinTime": 1,
"modified": messageTime
}
self.generate_chat(
row.get("id"),
row.get("owner"),
row.get("type"),
participants,
message,
messageTime
)
)
# Получаем последнее сообщение из избранного
@ -123,24 +117,19 @@ class Tools:
senderId, db_pool
)
# ID избранного
chatId = senderId ^ senderId
# Хардкодим в лист чатов избранное
chats.append(
{
"id": 0,
"type": "DIALOG",
"status": "ACTIVE",
"owner": senderId,
"participants": {
str(senderId): 0 # if not messageTime else messageTime
},
"lastMessage": message,
"lastEventTime": messageTime,
"lastDelayedUpdateTime": 0,
"lastFireDelayedErrorTime": 0,
"created": 1,
"joinTime": 1,
"modified": messageTime
}
self.generate_chat(
chatId,
senderId,
"DIALOG",
[senderId],
message,
messageTime
)
)
return chats
@ -185,9 +174,11 @@ class Tools:
"time": int(row.get("time")),
"type": row.get("type"),
"sender": row.get("sender"),
"cid": int(row.get("cid")),
"text": row.get("text"),
"attaches": json.loads(row.get("attaches")),
# "reactionInfo": {}
"elements": json.loads(row.get("elements")),
"reactionInfo": {}
}
# Возвращаем

View File

@ -445,7 +445,7 @@ class Processors:
chatId = userId ^ senderId
# Если клиент хочет отправить сообщение в избранное,
# то выставляем ID чата 0
# то выставляем в качестве ID чата ID отправителя
# (А ещё используем это, если клиент вообще ничего не указал)
if chatId == 0 or not chatId:
chatId = senderId
@ -491,7 +491,8 @@ class Processors:
"sender": senderId,
"cid": cid,
"text": text,
"attaches": attaches
"attaches": attaches,
"elements": elements
}
# Отправляем событие всем участникам чата
@ -700,6 +701,9 @@ class Processors:
senderId, self.db_pool
)
# ID избранного
chatId = senderId ^ senderId
# Добавляем чат в список
chats.append(
self.tools.generate_chat(

View File

@ -1,4 +1,5 @@
import hashlib, secrets, random, time, logging, json
import hashlib, secrets, random, time, logging, json # PEP-8 по приколу сделан >_<
import re
from common.static import Static
from common.tools import Tools
from tamtam_tcp.proto import Proto
@ -76,17 +77,17 @@ class Processors:
return
# Извлекаем телефон из пакета
phone = payload.get("phone").replace("+", "").replace(" ", "").replace("-", "")
phone = re.sub(r'\D', '', payload.get("phone", "")) # Не хардкодим, через регулярки
# Генерируем токен с кодом
code = str(random.randint(000000, 999999))
code = f"{secrets.randbelow(1_000_000):06d}" # Старая версия ненадежна, могла отбросить ведущие нули или вообще интерпритировать как систему счисления с основанием 8
token = secrets.token_urlsafe(128)
# Хешируем
code_hash = hashlib.sha256(code.encode()).hexdigest()
token_hash = hashlib.sha256(token.encode()).hexdigest()
# Время истечения токена
# Срок жизни токена (5 минут)
expires = int(time.time()) + 300
# Ищем пользователя, и если он существует, сохраняем токен