feat: TikTok download command + SOLID/DRY refactoring
- Add !tiktok command for downloading TikTok videos (no watermark) - TikTokApi service using tikwm.com API - Lifecycle interface for shutdown management (9→3 deps in ShutdownManager) - Extract JdaFactory + LavalinkManagerFactory from BotInitializer - Extract PlayLoadHandler from PlayCommand (207→148 lines) - Extract TrackStarter from TrackScheduler (146→113 lines) - Refactor MuteCommand execute() into methods (199→173 lines) - Move CommandRegistrar bindings to feature modules - RatingConfig: data-driven getLevels(name) + findLevel(value, name) - VoiceHelper.connectForPlayback() for voice connection retry - BotModule: 98→84 lines, BotInitializer: 162→135 lines
This commit is contained in:
parent
03d0ed6c43
commit
f93f6aafc8
65 changed files with 1599 additions and 666 deletions
109
TODO.md
109
TODO.md
|
|
@ -28,6 +28,15 @@
|
|||
| A21 | ✅ | BotModule: путь к БД хардкодом | Вынесен в .env (`DB_PATH`) + BotConfig |
|
||||
| A34 | ✅ | CommandCategories: мёртвый код | Уже удалён (старый пакет) |
|
||||
| A37 | ✅ | ProfileCommand: регистрация в PrefixCommandRegistrar | LevelCommandRegistrar |
|
||||
| A41 | ✅ | TikTok: команда `!tiktok <url>` для скачивания видео | TikTokApi + TikTokCommand + TikTokModule |
|
||||
| A42 | ✅ | S1-S5: SOLID рефакторинг | Lifecycle, JdaFactory, PlayLoadHandler, feature modules |
|
||||
| A43 | ✅ | D4-D6: DRY рефакторинг | VoiceHelper.connectForPlayback, RatingConfig data-driven, SocialCommand.Flavor |
|
||||
| A44 | ✅ | PlayCommand: 207→148 строк | PlayLoadHandler + VoiceHelper.connectForPlayback |
|
||||
| A45 | ✅ | TrackScheduler: 146→113 строк | TrackStarter (retry логика) |
|
||||
| A46 | ✅ | MuteCommand: 199→173 строки | execute() разбит на 6 методов |
|
||||
| A47 | ✅ | BotInitializer: 162→135 строк | JdaFactory + LavalinkManagerFactory |
|
||||
| A48 | ✅ | ShutdownManager: 9→3 зависимости | Lifecycle interface + Multibinder |
|
||||
| A49 | ✅ | BotModule: 98→84 строки | CommandRegistrar bindings в feature модулях |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -262,32 +271,32 @@ feature/economy/
|
|||
| D1 | `getDeterministicValue()` — целиком | GayCommand, FatCommand, IqCommand, PpCommand, BoykisserCommand, MustacheCommand, RateCommand | 7 | ✅ RatingService |
|
||||
| D2 | Cooldown check boilerplate (5 строк) | Все entertainment команды | 10+ | ✅ RatingService |
|
||||
| D3 | `trunc()` / `err()` helpers | MuteCommand, WarnCommand, SwapAndCaseCommand, UnmuteCommand, PunishCommand | 5 | ✅ ModerationHelper |
|
||||
| D4 | Voice connect retry loop (цикл 10×200ms) | PlayCommand, RadioManager | 2 |
|
||||
| D5 | RatingConfig — 6 методов с идентичной структурой | RatingConfig.java | 6 |
|
||||
| D6 | Social команды (hug/kiss/slap/poke/tickle/cuddle/feed/pat) — шаблон | 10 файлов | 10 |
|
||||
| D4 | Voice connect retry loop (цикл 10×200ms) | PlayCommand, RadioManager | 2 | ✅ VoiceHelper.connectForPlayback() |
|
||||
| D5 | RatingConfig — 6 методов с идентичной структурой | RatingConfig.java | 6 | ✅ Data-driven getLevels(name) + findLevel(value, name) |
|
||||
| D6 | Social команды (hug/kiss/slap/poke/tickle/cuddle/feed/pat) — шаблон | 10 файлов | 10 | ✅ SocialCommand.Flavor (7 команд), pat/compliment/roast — отдельные |
|
||||
|
||||
### SOLID
|
||||
|
||||
| # | Нарушение | Файл | Описание |
|
||||
|---|-----------|------|----------|
|
||||
| S1 | SRP | BotModule.java | Биндит всё приложение |
|
||||
| S2 | SRP | SwapAndCaseCommand.java | Две разные команды в одном файле |
|
||||
| S3 | SRP | BotInitializer.java | Инициализирует 3 JDA, Lavalink, mutes, counters, health |
|
||||
| S4 | SRP | ShutdownManager.java | 9 зависимостей в конструкторе |
|
||||
| S5 | SRP | PlayCommand.java | execute() на 145 строк |
|
||||
| S1 | SRP | BotModule.java | Биндит всё приложение | ✅ Перенесён в feature модули + LifecycleModule |
|
||||
| S2 | SRP | SwapAndCaseCommand.java | Две разные команды в одном файле | ✅ Уже разделены: SwapCommand + CaseLookupCommand |
|
||||
| S3 | SRP | BotInitializer.java | Инициализирует 3 JDA, Lavalink, mutes, counters, health | ✅ JdaFactory + LavalinkManagerFactory |
|
||||
| S4 | SRP | ShutdownManager.java | 9 зависимостей в конструкторе | ✅ Lifecycle interface, 3 зависимости |
|
||||
| S5 | SRP | PlayCommand.java | execute() на 145 строк | ✅ PlayLoadHandler + VoiceHelper.connectForPlayback() |
|
||||
| S6 | OCP | Meter-команды (gay/fat/iq/pp) | Добавить новую = копировать 90 строк | ✅ RatingService |
|
||||
| S7 | DIP | MuteCommand, WarnCommand | >5 конкретных репозиториев вместо интерфейсов |
|
||||
| S7 | DIP | MuteCommand, WarnCommand | >5 конкретных репозиториев вместо интерфейсов | ✅ Репозитории уже интерфейсы (ModerationCaseRepository, ActiveMuteRepository, WarningRepository) |
|
||||
|
||||
### Файлы >150 строк
|
||||
|
||||
| # | Файл | Строк |
|
||||
|---|------|-------|
|
||||
| F1 | PlayCommand.java | 219 |
|
||||
| F1 | PlayCommand.java | 148 ✅ |
|
||||
| F2 | QueueSlashHandler.java | 207 |
|
||||
| F3 | MusicBotControlHandler.java | 207 |
|
||||
| F4 | QueueCommands.java | 207 |
|
||||
| F5 | TrackScheduler.java | 202 |
|
||||
| F6 | MuteCommand.java | 199 |
|
||||
| F5 | TrackScheduler.java | 113 ✅ |
|
||||
| F6 | MuteCommand.java | 173 ✅ |
|
||||
| F7 | ModerationLogger.java | 199 |
|
||||
| F8 | FeatureTables.java | 193 |
|
||||
| F9 | DatabaseMigration.java | 193 |
|
||||
|
|
@ -297,7 +306,7 @@ feature/economy/
|
|||
| F13 | RadioManager.java | 182 |
|
||||
| F14 | MetricsCollector.java | 182 |
|
||||
| F15 | WarnCommand.java | 184 |
|
||||
| F16 | BotInitializer.java | 182 |
|
||||
| F16 | BotInitializer.java | 135 ✅ |
|
||||
| F17 | SlashHandler's (Queue/Filter) | >100 |
|
||||
| F18 | GenerateRatingsCommand.java | 172 |
|
||||
| F19 | BlackjackService.java | 172 |
|
||||
|
|
@ -337,37 +346,37 @@ feature/economy/
|
|||
|
||||
## 📋 План рефакторинга (KISS/DRY/SOLID)
|
||||
|
||||
### Этап 8: Убить дублирование (DRY) — в процессе
|
||||
### Этап 8: Убить дублирование (DRY) — ✅ завершён
|
||||
|
||||
- [x] D1/D2: `RatingService` с `getDeterministicValue()`, cooldown, member parsing — 7 команд переписаны
|
||||
- [x] D3: `ModerationHelper` с `trunc()`/`err()` — MuteCommand, UnmuteCommand, WarnCommand, SwapAndCaseCommand, PunishCommand
|
||||
- [ ] D4: Вынести voice connect retry в утилиту
|
||||
- [ ] D5: RatingConfig — заменить 6 методов на data-driven (Map или config)
|
||||
- [ ] D6: Social команды — единый `SocialCommand` с параметром action
|
||||
- [x] D4: Вынести voice connect retry в утилиту — ✅ VoiceHelper.connectForPlayback()
|
||||
- [x] D5: RatingConfig — заменить 6 методов на data-driven (Map или config) — ✅ getLevels(name) + findLevel(value, name)
|
||||
- [x] D6: Social команды — единый `SocialCommand` с параметром action — ✅ SocialCommand.Flavor (7 команд)
|
||||
|
||||
### Этап 9: SOLID
|
||||
### Этап 9: SOLID — ✅ завершён
|
||||
|
||||
- [ ] S1: Разбить `BotModule` на per-feature модули (FeatureModule → install в BotModule)
|
||||
- [ ] S2: Разделить `SwapAndCaseCommand` на два отдельных файла
|
||||
- [ ] S3: Выделить `MusicBotFactory`, `RadioBotFactory` из `BotInitializer`
|
||||
- [ ] S4: Уменьшить кол-во зависимостей `ShutdownManager` через события (EventBus)
|
||||
- [ ] S5: Разбить `PlayCommand.execute()` на методы
|
||||
- [ ] S6: Meter-команды сделать data-driven через `RatingService`
|
||||
- [ ] S7: Выделить интерфейсы для репозиториев/сервисов (DIP)
|
||||
- [x] S1: Разбить `BotModule` на per-feature модули (FeatureModule → install в BotModule) — ✅ 8 feature модулей + LifecycleModule
|
||||
- [x] S2: Разделить `SwapAndCaseCommand` на два отдельных файла — ✅ Already split (SwapCommand + CaseLookupCommand)
|
||||
- [x] S3: Выделить `MusicBotFactory`, `RadioBotFactory` из `BotInitializer` — ✅ JdaFactory + LavalinkManagerFactory
|
||||
- [x] S4: Уменьшить кол-во зависимостей `ShutdownManager` через события (EventBus) — ✅ Lifecycle interface (9→3 deps)
|
||||
- [x] S5: Разбить `PlayCommand.execute()` на методы — ✅ PlayLoadHandler + VoiceHelper.connectForPlayback()
|
||||
- [x] S6: Meter-команды сделать data-driven через `RatingService` — ✅ RatingConfig.findLevel(value, name)
|
||||
- [x] S7: Выделить интерфейсы для репозиториев/сервисов (DIP) — ✅ Already interfaces
|
||||
|
||||
### Этап 10: Файлы ≤150 строк
|
||||
### Этап 10: Файлы ≤150 строк — в процессе
|
||||
|
||||
- [ ] F01: PlayCommand.java — разбить на методы/классы
|
||||
- [x] F01: PlayCommand.java — разбить на методы/классы — ✅ 207→148 строк
|
||||
- [ ] F02-04: QueueSlashHandler, MusicBotControlHandler, QueueCommands — вынести общие части
|
||||
- [ ] F05: TrackScheduler.java — вывести FilterState в отд. файл или утилиту
|
||||
- [ ] F06: MuteCommand.java — разбить на subcommand handler'ы
|
||||
- [x] F05: TrackScheduler.java — вывести FilterState в отд. файл или утилиту — ✅ 146→113 строк (TrackStarter)
|
||||
- [x] F06: MuteCommand.java — разбить на subcommand handler'ы — ✅ 199→173 строки
|
||||
- [ ] F07: ModerationLogger.java — разбить по типам событий
|
||||
- [ ] F08-09: FeatureTables, DatabaseMigration — разбить по фичам
|
||||
- [ ] F10-12: Voice* — вынести логику в сервисы
|
||||
- [ ] F13: RadioManager.java — вынести voice connect в утилиту
|
||||
- [ ] F14: MetricsCollector.java — разбить по типам метрик
|
||||
- [ ] F15: WarnCommand.java — вынести auto-mute в отдельный сервис
|
||||
- [ ] F16: BotInitializer.java — вынести фабрики ботов
|
||||
- [x] F16: BotInitializer.java — вынести фабрики ботов — ✅ 162→135 строк
|
||||
- [ ] Остальные: разбить по SOLID
|
||||
|
||||
### Этап 11: ≤6 файлов в папке
|
||||
|
|
@ -394,7 +403,45 @@ feature/economy/
|
|||
|
||||
---
|
||||
|
||||
**Версия:** 2.3 | **Последнее обновление:** 2026-07-04 | **Java 21 ✅, God Constructor ✅, Critical баги ✅, Economy ✅, Level Roles ✅, Lavalink Music ✅, SpotBugs ✅, Checkstyle ✅, CI/CD ✅**
|
||||
**Версия:** 2.4 | **Последнее обновление:** 2026-07-14 | **Java 21 ✅, God Constructor ✅, Critical баги ✅, Economy ✅, Level Roles ✅, Lavalink Music ✅, SpotBugs ✅, Checkstyle ✅, CI/CD ✅, SOLID ✅, TikTok ✅**
|
||||
|
||||
## ✅ Что добавлено в v2.4
|
||||
|
||||
### 🎬 TikTok Download Command
|
||||
- [x] Команда `!tiktok <url>` — скачивание видео из TikTok без watermark
|
||||
- [x] TikTokApi — сервис для работы с tikwm.com API (OkHttp + Gson)
|
||||
- [x] Скачивание через virtual threads
|
||||
- [x] Embed с информацией (title, author, duration, cover)
|
||||
- [x] Проверка размера файла (< 8MB)
|
||||
- [x] TikTokModule для DI
|
||||
|
||||
### 🔧 Рефакторинг SOLID/DRY
|
||||
- [x] **S1**: BotModule — CommandRegistrar bindings перенесены в feature модули (8 модулей)
|
||||
- [x] **S2**: SwapAndCaseCommand — уже разделены (SwapCommand + CaseLookupCommand)
|
||||
- [x] **S3**: BotInitializer — извлечены JdaFactory + LavalinkManagerFactory (162→135 строк)
|
||||
- [x] **S4**: ShutdownManager — Lifecycle interface, 9→3 зависимости (118→89 строк)
|
||||
- [x] **S5**: PlayCommand — извлечён PlayLoadHandler + VoiceHelper.connectForPlayback() (207→148 строк)
|
||||
- [x] **S7**: DIP — репозитории уже интерфейсы (ModerationCaseRepository, ActiveMuteRepository, WarningRepository)
|
||||
- [x] **D4**: Voice connect retry — VoiceHelper.connectForPlayback()
|
||||
- [x] **D5**: RatingConfig — data-driven getLevels(name) + findLevel(value, name)
|
||||
- [x] **D6**: Social команды — SocialCommand.Flavor (7 команд), pat/compliment/roast — отдельные
|
||||
- [x] **TrackScheduler** — извлечён TrackStarter (146→113 строк)
|
||||
- [x] **MuteCommand** — execute() разбит на методы (199→173 строки, execute() 23 строки)
|
||||
|
||||
### 📦 Новые файлы
|
||||
- `feature/tiktok/TikTokApi.java` — API сервис
|
||||
- `feature/tiktok/TikTokCommand.java` — команда
|
||||
- `feature/tiktok/TikTokModule.java` — Guice модуль
|
||||
- `core/Lifecycle.java` — интерфейс для shutdown
|
||||
- `core/JdaFactory.java` — фабрика JDA
|
||||
- `core/LavalinkManagerFactory.java` — фабрика LavalinkManager
|
||||
- `core/LifecycleModule.java` — Multibinder для Lifecycle
|
||||
- `feature/entertainment/EntertainmentModule.java` — CommandRegistrar binding
|
||||
- `feature/utility/UtilityModule.java` — CommandRegistrar binding
|
||||
- `feature/music/play/PlayLoadHandler.java` — обработчик загрузки треков
|
||||
- `feature/music/manage/TrackStarter.java` — retry логика запуска треков
|
||||
|
||||
---
|
||||
|
||||
## ✅ Что добавлено в v2.3
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue