- Создана доменная структура feature/level/ с разделением на domain/service - ынесены классы LevelUpResult, LevelProgress, UserStats, XpFormula - Созданы сервисы: LevelService, MessageCooldownService, LeaderboardService - еремещены команды и листенеры в feature/level/ - далены импорты AudioManager и мертвые ссылки на TTS - бновлены все тесты овая функциональность: - енератор красивых профильных карточек (RankCardGenerator) - оманда !profile для просмотра карточки с уровнем, XP, статистикой - оманда !stop для безопасной остановки бота (только админы) - обавлены ассеты: фоны, иконки, бейджи Технические улучшения: - ерсистентный кулдаун через UserStats.lastMessageTime - бобщенные методы лидерборда через Comparator - Graceful shutdown с сохранением всех данных - Fallback на заглушки если ассеты не загрузились
677 lines
33 KiB
Markdown
677 lines
33 KiB
Markdown
# 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 строк
|
||
- [ ] Запустить бота и протестировать основные команды
|
||
|
||
---
|
||
|
||
## Основные задачи
|
||
|
||
### 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 <channel>` - установить канал-триггер
|
||
- `/voice-setup category <category>` - установить категорию для личных каналов
|
||
- `/voice-setup text-channel <channel>` - установить текстовый канал для уведомлений
|
||
|
||
#### Counter Setup:
|
||
- `/counter-setup channel <voice-channel>` - установить канал для счетчика
|
||
- `/counter-setup format <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
|