# TODO - План реализации функций ## Правила разработки ### Архитектура и код: - KISS, DRY, SOLID принципы - Файлы максимум 150-200 строк, стараться делать 100 строк - В одной папке не больше 6 файлов - Не создавать новые MD файлы без необходимости - Разделение по доменам, а не по типам артефактов ### Принципы структуры: - Пакет = домен/фича, а не тип файла (не "команды/листенеры", а "profile/level/voice") - Каждая фича содержит свои команды, сервисы, репозитории - Единый слой персистентности через repository/ - Интеграции в отдельном пакете integration/ --- ## Рефакторинг структуры проекта ### Целевая оценка: 7/10 **Проблемы:** 1. `util/` - мусорная корзина (CooldownManager, RateLimiter, NekosLifeApi) 2. Два механизма персистентности (data/ и database/) без абстракции 3. `command/impl/entertainment/` - 23 файла в одном пакете 4. `exception/` - избыточный пакет для 2 файлов 5. `embed/` - presentation layer оторван от domain 6. `listener/` - смешаны разные ответственности 7. Техническое разделение вместо доменного 8. **LevelSystem - God Class (5/10):** - Нарушение SRP: хранение + кэширование + формулы + лидерборды + прогресс-бары - Прямая зависимость от JsonDataStore (нет интерфейса Repository) - O(n) на каждое сообщение (читает/пишет весь JSON) - Кэш messageTimestamps не персистентный (теряется при рестарте) - Рассогласование формул: комментарий говорит 200, код использует 100 - LevelUpResult и LevelProgress - вложенные классы вместо отдельных - getAllStats() возвращает mutable map (можно сломать консистентность) 9. **UserStats - анемичная модель (6/10):** - Сеттеры позволяют нарушить инварианты (setLevel(999) без XP) - incrementMessages() скрыто меняет lastMessageTime (side effect) - Поля lastMessageTime и lastVoiceJoin не используются системой - Нет equals/hashCode для использования в коллекциях ### Целевая структура (по доменам): ``` src/main/java/creator/loki/ ├── App.java # Точка входа (временно, потом в bootstrap/) │ ├── core/ # Ядро системы │ ├── BotInitializer │ ├── EventDispatcher │ ├── registry/ # Регистрация команд │ │ ├── CommandRegistry │ │ ├── SlashCommandRegistry │ │ ├── PrefixCommandRegistrar │ │ └── SlashCommandRegistrar │ ├── security/ # Безопасность и ограничения │ │ ├── RateLimiter # (из util/) │ │ └── CooldownManager # (из util/) │ └── exception/ # Глобальная обработка ошибок │ └── CommandExceptionHandler │ ├── command/ # Базовые интерфейсы команд │ ├── Command.java │ ├── CommandContext.java │ ├── CommandException.java # (из exception/) │ ├── SlashCommand.java │ ├── moderation/ # Модерация (3 файла) │ │ ├── BanCommand │ │ ├── KickCommand │ │ └── ClearCommand │ ├── entertainment/ # Развлечения │ │ ├── games/ # Игры (12 файлов) │ │ └── social/ # Взаимодействия (11 файлов) │ ├── utility/ # Утилиты (5 файлов) │ │ ├── HelpCommand │ │ ├── PingCommand │ │ ├── InfoCommand │ │ ├── AvatarCommand │ │ └── PollCommand │ └── system/ # Системные команды │ └── MetricsCommand # (из utility/) │ ├── feature/ # Крупные фичи/домены │ ├── level/ # Система уровней │ │ ├── LevelSystem │ │ ├── UserStats │ │ ├── LevelUtils # (из profile/) │ │ ├── RankCommand # (из command/stats/) │ │ ├── StatsCommand # (из command/stats/) │ │ ├── LevelUpNotifier # (из listener/) │ │ └── VoiceTracker # (из listener/) │ │ │ ├── profile/ # Профили пользователей │ │ ├── ProfileService │ │ ├── ProfileGenerator │ │ ├── ProfileData │ │ ├── ProfileCommand # (из command/utility/) │ │ └── ProfileEmbedFactory # (из embed/) │ │ │ ├── reputation/ # Система репутации │ │ ├── ReputationService # (логика из RepCommand) │ │ ├── RepCommand # (из command/stats/) │ │ ├── MinusRepCommand # (из command/stats/) │ │ └── RepTopCommand # (из command/stats/) │ │ │ ├── leaderboard/ # Таблица лидеров │ │ ├── LeaderboardCommand # (NewLeaderboardCommand) │ │ ├── LeaderboardService # (логика из команды) │ │ ├── LeaderboardFormatter │ │ ├── LeaderboardButtons │ │ └── LeaderboardButtonListener │ │ │ ├── voice/ # Личные голосовые каналы │ │ ├── VoiceChannelManager │ │ ├── VoiceChannelData │ │ ├── VoicePreset │ │ ├── VoiceSetupCommand # (из command/setup/) │ │ ├── VoiceChannelListener # (из listener/) │ │ └── VoiceButtonHandler # (из listener/) │ │ │ ├── counter/ # Счетчик участников │ │ ├── CounterManager │ │ ├── DailyStats │ │ ├── CounterSetupCommand # (из command/setup/) │ │ └── MemberCounterListener # (из listener/) │ │ │ └── role/ # Кастомные роли │ ├── CustomRoleManager │ ├── CreateRoleCommand # (из command/roles/) │ ├── DeleteRoleCommand # (из command/roles/) │ ├── EditRoleCommand # (из command/roles/) │ ├── MyRolesCommand # (из command/roles/) │ └── RoleCommandValidator # (из command/roles/) │ ├── event/ # Обработчики событий Discord │ ├── ReadyListener # (из listener/) │ ├── MessageListener # (из listener/) │ ├── SlashCommandListener # (из listener/) │ ├── HelpMenuHandler # (из listener/) │ └── ModerationLogger # (из listener/) │ ├── repository/ # Единый слой данных │ ├── UserRepository # Интерфейс │ ├── GuildConfigRepository # Интерфейс │ └── impl/ │ ├── JsonUserRepository # (из data/) │ └── SqliteConfigRepository # (из database/) │ ├── database/ # Инфраструктура БД │ ├── Database │ ├── DatabaseSchema │ └── DatabaseMigration │ ├── integration/ # Внешние API │ └── nekos/ │ └── NekosLifeApi # (из util/) │ ├── config/ # Конфигурация │ ├── BotConfig │ └── ConfigLoader │ ├── embed/ # Общие шаблоны embed │ ├── EmbedFactory │ └── EmbedTemplates │ ├── metrics/ # Метрики │ └── MetricsCollector │ └── di/ # Dependency Injection └── BotModule ``` ### План действий (этапы): #### Этап 1: Фундамент (делаем первым) **1. Создать repository/ (средний → высокий приоритет)** - [x] Создать `repository/` - [x] Создать интерфейс `repository/UserStatsRepository.java` - [x] Создать `repository/impl/` - [x] Создать `repository/impl/JsonUserStatsRepository.java` (обёртка над JsonDataStore) - [ ] Создать интерфейс `repository/GuildConfigRepository.java` - [ ] Рефакторить `database/ConfigRepository` → использовать интерфейс **2. Реорганизовать util/ (мусорная корзина)** - [x] Создать `core/security/` - [x] Переместить `util/CooldownManager` → `core/security/CooldownManager` - [x] Переместить `util/GlobalRateLimiter` → `core/security/RateLimiter` - [x] Создать `integration/nekos/` - [x] Переместить `util/NekosLifeApi` → `integration/nekos/NekosLifeApi` - [x] Удалить пустую папку `util/` - [x] Обновить все импорты в командах - [x] Добавить `UserStatsRepository` в `BotModule` **3. Удалить импорты AudioManager и мертвые ссылки** - [x] Удалить `import creator.loki.audio.AudioManager` из `BotInitializer` - [x] Удалить `import creator.loki.audio.AudioManager` из `PrefixCommandRegistrar` - [x] Удалить `import creator.loki.audio.AudioManager` из `SlashCommandRegistrar` - [x] Удалить параметр `AudioManager audioManager` из конструкторов - [x] Удалить поля `private final AudioManager audioManager` - [x] Удалить `registry.register(new TtsCommand(...))` из `PrefixCommandRegistrar` - [x] Удалить `registry.register(new TtsSlashCommand(...))` из `SlashCommandRegistrar` - [x] Исправить `registry.register(new NewLeaderboardCommand(...))` → использовать новый путь - [x] Удалить все `registry.register(new *SlashCommand(...))` из `SlashCommandRegistrar` - [x] Удалить `import creator.loki.command.slash.*` из `SlashCommandRegistrar` - [x] Проверить компиляцию: `gradle build` --- #### Этап 2: feature/level/ (зависит от Этапа 1) **4. Создать feature/level/domain/** - [x] Создать `feature/level/` - [x] Создать `feature/level/domain/` - [x] Создать `feature/level/domain/XpFormula.java` - [x] Вынести `LevelUpResult` из `LevelSystem` → `feature/level/domain/LevelUpResult.java` - [x] Вынести `LevelProgress` из `LevelSystem` → `feature/level/domain/LevelProgress.java` - [x] Переместить `level/UserStats` → `feature/level/domain/UserStats.java` - [x] **НЕ делать immutable сейчас** (Gson требует сеттеры, сделаем после Repository) - [x] Добавить `equals()` и `hashCode()` в `UserStats` - [x] Переименовать `incrementMessages()` → `recordMessage(long timestamp)` **5. Создать feature/level/service/** - [x] Создать `feature/level/service/` - [x] Создать `feature/level/service/MessageCooldownService.java` - [x] Создать `feature/level/service/LeaderboardService.java` - [x] Рефакторить `level/LevelSystem` → `feature/level/service/LevelService.java` - [x] Использовать `UserStatsRepository` вместо `JsonDataStore` - [x] Использовать `XpFormula` для вычислений - [x] Использовать `MessageCooldownService` для кулдаунов - [x] Убрать методы лидерборда (в `LeaderboardService`) - [x] Обновить все импорты UserStats на новый путь - [x] Удалить старый `level/UserStats.java` - [x] Добавить сервисы в `BotModule` **6. Переместить команды и листенеры в feature/level/** - [x] Переместить `command/impl/stats/RankCommand` → `feature/level/RankCommand` - [x] Переместить `command/impl/stats/StatsCommand` → `feature/level/StatsCommand` - [x] Переместить `listener/LevelUpNotifier` → `feature/level/LevelUpNotifier` - [x] Переместить `listener/VoiceTracker` → `feature/level/VoiceTracker` - [x] Обновить все импорты - [x] Обновить `BotInitializer`, `BotModule`, `PrefixCommandRegistrar` - [x] Обновить команды для использования `LevelService` вместо `LevelSystem` **7. Создать команду сброса уровней (миграция на новую систему)** - [ ] Создать `feature/level/ResetLevelsCommand.java`: - Только для администраторов - Подтверждение через кнопки (Да/Нет) - Сброс всех уровней и XP - Очистка таблицы `user_stats` в БД - Логирование действия - Уведомление в канал логов - Embed с предупреждением о необратимости - [ ] Зарегистрировать команду в `PrefixCommandRegistrar` - [ ] Добавить в категорию "Настройка" (только админы) --- #### Этап 3: Остальные feature/ (параллельно, независимо) **7. Создать feature/voice/ (голосовые каналы)** - [ ] Создать `feature/voice/` - [ ] Переместить `voice/VoiceChannelManager` → `feature/voice/` - [ ] Переместить `voice/VoiceChannelData` → `feature/voice/` - [ ] Переместить `voice/VoicePreset` → `feature/voice/` - [ ] Переместить `command/impl/setup/VoiceSetupCommand` → `feature/voice/` - [ ] Переместить `listener/VoiceChannelListener` → `feature/voice/` - [ ] Переместить `listener/VoiceButtonHandler` → `feature/voice/` - [ ] Удалить пустую папку `voice/` - [ ] Обновить импорты **8. Создать feature/counter/ (счетчик участников)** - [ ] Создать `feature/counter/` - [ ] Переместить `counter/CounterManager` → `feature/counter/` - [ ] Переместить `counter/DailyStats` → `feature/counter/` - [ ] Переместить `command/impl/setup/CounterSetupCommand` → `feature/counter/` - [ ] Переместить `listener/MemberCounterListener` → `feature/counter/` - [ ] Удалить пустую папку `counter/` - [ ] Обновить импорты **9. Создать feature/role/ (кастомные роли)** - [ ] Создать `feature/role/` - [ ] Переместить `role/CustomRoleManager` → `feature/role/` - [ ] Переместить `command/impl/roles/CreateRoleCommand` → `feature/role/` - [ ] Переместить `command/impl/roles/DeleteRoleCommand` → `feature/role/` - [ ] Переместить `command/impl/roles/EditRoleCommand` → `feature/role/` - [ ] Переместить `command/impl/roles/MyRolesCommand` → `feature/role/` - [ ] Переместить `command/impl/roles/RoleCommandValidator` → `feature/role/` - [ ] Удалить пустые папки `role/` и `command/impl/roles/` - [ ] Обновить импорты **10. Создать feature/reputation/ (система репутации)** - [ ] Создать `feature/reputation/` - [ ] Создать `feature/reputation/ReputationService.java` (вынести логику из команд) - [ ] Переместить `command/impl/stats/RepCommand` → `feature/reputation/` - [ ] Переместить `command/impl/stats/MinusRepCommand` → `feature/reputation/` - [ ] Переместить `command/impl/stats/RepTopCommand` → `feature/reputation/` - [ ] Рефакторить команды: использовать `ReputationService` - [ ] Обновить импорты **11. Создать feature/leaderboard/ (таблица лидеров)** - [ ] Создать `feature/leaderboard/` - [ ] Переместить `command/impl/stats/leaderboard/NewLeaderboardCommand` → `feature/leaderboard/LeaderboardCommand` - [ ] Переместить `command/impl/stats/leaderboard/LeaderboardFormatter` → `feature/leaderboard/` - [ ] Переместить `command/impl/stats/leaderboard/LeaderboardButtons` → `feature/leaderboard/` - [ ] Переместить `command/impl/stats/leaderboard/LeaderboardButtonListener` → `feature/leaderboard/` - [ ] Создать `feature/leaderboard/LeaderboardService.java` (использовать из level/) - [ ] Удалить пустую папку `command/impl/stats/` - [ ] Обновить импорты **12. Создать feature/profile/ (профили пользователей)** - [ ] Создать `feature/profile/` - [ ] Переместить `profile/ProfileService` → `feature/profile/` - [ ] Переместить `profile/ProfileGenerator` → `feature/profile/` - [ ] Переместить `profile/ProfileData` → `feature/profile/` - [ ] Переместить `command/impl/utility/ProfileCommand` → `feature/profile/` - [ ] Создать `feature/profile/ProfileEmbedFactory.java` (вынести из команды) - [ ] Удалить пустую папку `profile/` - [ ] Обновить импорты **13. Создать feature/metrics/ (метрики системы)** - [ ] Создать `feature/metrics/` - [ ] Переместить `metrics/MetricsCollector` → `feature/metrics/` - [ ] Переместить `command/impl/utility/MetricsCommand` → `feature/metrics/` - [ ] Создать `feature/metrics/MetricsService.java` (если нужна логика) - [ ] Удалить пустую папку `metrics/` - [ ] Обновить импорты --- #### Этап 4: Инфраструктура (после feature/) **14. Реорганизовать event/ (listener)** - [ ] Создать `event/` - [ ] Создать `event/gateway/` (JDA Gateway events) - [ ] Переместить `listener/ReadyListener` → `event/gateway/` - [ ] Переместить `listener/MessageListener` → `event/gateway/` - [ ] Создать `event/gateway/GuildListener.java` (member join/leave + moderation) - [ ] Переместить `listener/ModerationLogger` → `event/gateway/GuildListener` (или отдельно) - [ ] Создать `event/interaction/` (Button/Menu interactions) - [ ] Переместить `listener/SlashCommandListener` → `event/interaction/` - [ ] Переместить `listener/HelpMenuHandler` → `event/interaction/` - [ ] Удалить пустую папку `listener/` - [ ] Обновить импорты **15. Реорганизовать core/** - [ ] Создать `core/registry/` - [ ] Переместить `core/CommandRegistry` → `core/registry/` - [ ] Переместить `core/SlashCommandRegistry` → `core/registry/` - [ ] Переместить `core/PrefixCommandRegistrar` → `core/registry/` - [ ] Переместить `core/SlashCommandRegistrar` → `core/registry/` - [ ] Создать `core/exception/` - [ ] Переместить `exception/CommandExceptionHandler` → `core/exception/` - [ ] Переместить `exception/CommandException` → `command/CommandException` - [ ] Удалить пустую папку `exception/` - [ ] Обновить импорты **16. Почистить command/** - [ ] Переименовать `command/impl/entertainment/interaction/` → `command/entertainment/social/` - [ ] Удалить `command/impl/setup/` (команды перенесены в feature/) - [ ] Удалить `command/impl/utility/SwapCommand.java` (не используется) - [ ] Оставить в `command/` только: - Интерфейсы: `Command.java`, `CommandContext.java`, `SlashCommand.java`, `CommandException.java` - `command/moderation/` (если не выносим в feature/) - `command/entertainment/` (кросс-доменные развлечения) - `command/utility/` (HelpCommand, PingCommand, InfoCommand, AvatarCommand, PollCommand) **17. Вынести App.java из корня** - [ ] Создать `bootstrap/` - [ ] Создать `bootstrap/App.java` - [ ] Переместить логику инициализации из корневого `App.java` - [ ] Удалить корневой `App.java` - [ ] Обновить `build.gradle` (mainClass) --- #### Этап 5: Финальная полировка (опционально) **18. UserStats immutable (после Repository)** - [ ] Создать `UserStats.Builder` - [ ] Убрать public сеттеры (оставить package-private для Gson) - [ ] Добавить методы `addXP()`, `recordMessage()`, `addVoiceTime()` - [ ] Добавить `getLevel(XpFormula)` вместо внешних вычислений - [ ] Обновить `JsonUserStatsRepository` для работы с immutable **19. Обновить документацию** - [ ] Обновить `FEATURES.md` (убрать TTS, добавить новые фичи) - [ ] Обновить `README.md` (новая структура проекта) - [ ] Создать `ARCHITECTURE.md` (описание доменов и feature/) - [ ] Обновить комментарии в коде **20. Финальная проверка** - [ ] `gradle build` - компиляция без ошибок - [ ] Проверить все импорты - [ ] Проверить что нет папок с >6 файлами - [ ] Проверить что нет файлов >200 строк - [ ] Запустить бота и протестировать основные команды --- ## Рефакторинг кода (Code Quality) ### Убрать if-else леса в rating командах **Проблема:** Все rating команды (MustacheCommand, IqCommand, FatCommand, GayCommand, PpCommand, BoykisserCommand) содержат огромные if-else цепочки для определения уровня/комментария/цвета. **Пример плохого кода (MustacheCommand):** ```java String comment; Color color; if (mustacheLevel >= 1000) { comment = "🎩 ЛЕГЕНДАРНЫЕ УСИЩИ!"; color = new Color(255, 215, 0); } else if (mustacheLevel >= 80) { comment = "🧔 Роскошные усы!"; color = new Color(139, 69, 19); } else if (mustacheLevel >= 60) { comment = "👨 Хорошие усы"; color = new Color(160, 82, 45); } else if (mustacheLevel >= 40) { comment = "😊 Усики растут"; color = new Color(205, 133, 63); } else if (mustacheLevel >= 20) { comment = "🙂 Лёгкая щетина"; color = new Color(210, 180, 140); } else if (mustacheLevel > 0) { comment = "😐 Почти нет усов"; color = new Color(128, 128, 128); } else { comment = "🪒 Гладко выбрит"; color = new Color(200, 200, 200); } ``` **Решение:** Создать общий класс `RatingLevel` с конфигурацией уровней: ```java public class RatingLevel { private final int threshold; private final String comment; private final Color color; public static RatingLevel findLevel(int value, List levels) { return levels.stream() .filter(level -> value >= level.threshold) .findFirst() .orElse(levels.get(levels.size() - 1)); } } ``` **План действий:** - [ ] Создать `command/impl/entertainment/games/rating/RatingLevel.java` - [ ] Создать `command/impl/entertainment/games/rating/RatingConfig.java` с предустановленными конфигурациями - [ ] Рефакторить MustacheCommand - использовать RatingLevel - [ ] Рефакторить IqCommand - использовать RatingLevel - [ ] Рефакторить FatCommand - использовать RatingLevel - [ ] Рефакторить GayCommand - использовать RatingLevel (без уровней, только прогресс-бар) - [ ] Рефакторить PpCommand - использовать RatingLevel - [ ] Рефакторить BoykisserCommand - использовать RatingLevel - [ ] Проверить что все команды работают корректно - [ ] Удалить дублирующийся код **Приоритет:** Средний (улучшение качества кода) --- ## Основные задачи ### 1. ⚡ Переделать систему опыта (XP System Rework) **Текущая проблема:** - Формула: `XP = 100 * level^1.5` (слишком сложная) - XP за сообщение: 10 XP - XP за минуту в войсе: 5 XP - Cooldown на сообщения: 60 секунд **Новая система (из FEATURES.md):** - ✅ **Формула прогрессии:** `XP для следующего уровня = 200 * текущий_уровень` - Пример: уровень 1 → 2 требует 200 XP - Уровень 5 → 6 требует 1000 XP - Уровень 10 → 11 требует 2000 XP - ✅ **Голосовая активность:** - 1 XP каждую минуту нахождения в голосовом канале - Автоматическое отслеживание через `VoiceXpListener` - Уведомление при повышении уровня в войс-канале **Файлы для изменения:** - `src/main/java/creator/loki/level/LevelSystem.java` - изменить формулу - `src/main/java/creator/loki/listener/VoiceTracker.java` - изменить начисление XP - Добавить уведомления о level up в войсе **Статус:** ✅ **ГОТОВО** --- ### 2. 🎤 Система личных голосовых каналов (Voice Management System) **Концепция:** Пользователь заходит в специальный канал-триггер → бот автоматически создает личный войс-канал → перемещает пользователя туда → пишет сообщение в чат войса с настройками **Функционал:** #### 2.1 Автоматическое создание каналов - ✅ Создать `VoiceChannelManager` класс - ✅ Listener на вход в канал-триггер (например, "➕ Создать канал") - ✅ Автоматическое создание канала с именем пользователя - ✅ Перемещение пользователя в созданный канал - ✅ Выдача прав управления владельцу канала - ✅ Автоматическое удаление канала когда он пустой #### 2.2 Сообщение с настройками в чате войса При создании канала бот отправляет embed с кнопками: - 🔒 **Закрыть/Открыть** - переключение приватности - 👥 **Лимит** - установить лимит пользователей (0-99) - ✏️ **Переименовать** - изменить название канала - 🎨 **Битрейт** - изменить качество звука - 🚫 **Удалить** - удалить канал #### 2.3 Система пресетов - ✅ Сохранение настроек как пресет - ✅ Быстрое применение сохраненных настроек - ✅ Хранение в `data/voice_presets.json` **Структура данных:** ```json { "voice_channels": { "channel_id": { "owner_id": "user_id", "created_at": 1234567890, "settings": { "name": "Канал пользователя", "limit": 5, "bitrate": 64000, "locked": false } } }, "presets": { "user_id": [ { "name": "Gaming", "limit": 4, "bitrate": 96000 } ] } } ``` **Файлы для создания:** - `src/main/java/creator/loki/voice/VoiceChannelManager.java` - `src/main/java/creator/loki/voice/VoiceChannelData.java` - `src/main/java/creator/loki/voice/VoicePreset.java` - `src/main/java/creator/loki/listener/VoiceChannelListener.java` - `src/main/java/creator/loki/command/impl/voice/VoiceSettingsCommand.java` (для кнопок) **Статус:** ✅ **ГОТОВО** (базовая реализация, кнопки управления требуют обработчиков) --- ### 3. 📊 Счетчик участников (Member Counter) **Функционал:** - ✅ Обновление названия голосового канала с количеством участников - ✅ Формат: `【👥】Участники: 123` - ✅ Отслеживание дневной статистики: - Количество присоединившихся за день - Количество покинувших за день - Разница за 24 часа - ✅ Обновление каждые 5 минут - ✅ Сохранение статистики в `data/counter_data.json` **Структура данных:** ```json { "counter_channel_id": "1234567890", "daily_stats": { "date": "2026-05-11", "joined": 15, "left": 8, "difference": 7 }, "history": [ { "date": "2026-05-10", "joined": 20, "left": 12, "difference": 8 } ] } ``` **Файлы для создания:** - `src/main/java/creator/loki/listener/MemberCounterListener.java` - `src/main/java/creator/loki/counter/CounterManager.java` - `src/main/java/creator/loki/counter/DailyStats.java` **Статус:** 🔴 Не начато --- ## ✅ Что уже сделано ### ✅ Система опыта переделана - Новая формула: `XP для уровня N = 200 * N` - 1 XP за минуту в войсе - Обновление каждую минуту вместо 5 минут - Метод `addVoiceTime` теперь возвращает `LevelUpResult` для уведомлений ### ✅ Система личных войс-каналов (базовая) - `VoiceChannelManager` - управление каналами - `VoiceChannelListener` - автоматическое создание/удаление - `VoiceChannelData` и `VoicePreset` - модели данных - Автоматическое создание при входе в триггер-канал - Автоматическое удаление пустых каналов - Панель управления с кнопками (требуется обработчик кнопок) ### ✅ Счетчик участников - `CounterManager` - управление счетчиком - `MemberCounterListener` - отслеживание входов/выходов - `DailyStats` - дневная статистика - Обновление каждые 5 минут - История за 30 дней ### ✅ SQLite база данных + автомиграция - `Database` - менеджер SQLite - `DatabaseMigration` - автоматическая миграция из JSON - `ConfigRepository` - работа с конфигурацией - Все таблицы созданы автоматически - Миграция данных при первом запуске ### ✅ Команды настройки - `/voice-setup trigger` - установить канал-триггер - `/voice-setup category` - установить категорию - `/voice-setup text-channel` - установить текстовый канал - `/voice-setup info` - показать конфигурацию - `/counter-setup channel` - установить канал счетчика - `/counter-setup format` - установить формат - `/counter-setup info` - показать конфигурацию --- ## 🔧 Дополнительные улучшения ### 4. 🎨 Улучшение уведомлений о level up - ✅ Красивые embed сообщения при повышении уровня - ✅ Отправка в тот же канал где получен XP - ✅ Для войса - отправка в текстовый канал связанный с войсом - ✅ Показывать прогресс до следующего уровня **Статус:** 🔴 Не начато --- ### 5. 🛠️ Команды для настройки систем (Admin Commands) #### Voice System Setup: - `/voice-setup trigger ` - установить канал-триггер - `/voice-setup category ` - установить категорию для личных каналов - `/voice-setup text-channel ` - установить текстовый канал для уведомлений #### Counter Setup: - `/counter-setup channel ` - установить канал для счетчика - `/counter-setup format ` - изменить формат отображения - `/counter stats` - показать статистику за период **Статус:** 🔴 Не начато --- ## 📝 Приоритеты реализации ### Высокий приоритет (сделать в первую очередь): 1. ⚡ Переделать систему опыта (простая формула) 2. 🎤 Базовая система личных войс-каналов (создание/удаление) 3. 📊 Счетчик участников ### Средний приоритет: 4. 🎤 Настройки войс-каналов через кнопки 5. 🎨 Улучшение уведомлений о level up 6. 🎤 Система пресетов для войс-каналов ### Низкий приоритет: 7. 🛠️ Админ команды для настройки --- ## 🐛 Известные проблемы (Bugs to Fix) ### Критические: - [ ] Проверить корректность начисления XP в войсе - [ ] Убедиться что VoiceTracker правильно отслеживает время ### Некритические: - [ ] Удалить неиспользуемый logger в LevelSystem.java - [ ] Убрать ненужный @SuppressWarnings в LevelSystem.java --- ## 📚 Технические детали ### Зависимости: - JDA 5.0.0 (уже есть) - Guice для DI (уже есть) - Gson для JSON (уже есть) ### Конфигурация (добавить в config): ```yaml voice: trigger_channel_id: 1234567890 category_id: 1234567890 text_channel_id: 1234567890 auto_delete_empty: true counter: channel_id: 1234567890 update_interval: 300 # секунды format: "【👥】Участники: {count}" ``` --- ## ✅ Чеклист перед релизом - [ ] Все функции протестированы - [ ] Логирование работает корректно - [ ] Нет утечек памяти (проверить scheduler'ы) - [ ] Graceful shutdown для всех scheduler'ов - [ ] Документация обновлена - [ ] FEATURES.md актуализирован --- **Дата создания:** 2026-05-11 **Версия:** 1.0 **Автор:** Loki Bot Team