feat: ефакторинг системы уровней + генератор профильных карточек
- Создана доменная структура 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 на заглушки если ассеты не загрузились
This commit is contained in:
parent
aa3388cd9e
commit
f460c59e2f
41 changed files with 1574 additions and 216 deletions
96
TODO.md
96
TODO.md
|
|
@ -197,74 +197,54 @@ src/main/java/creator/loki/
|
|||
- [x] Добавить `UserStatsRepository` в `BotModule`
|
||||
|
||||
**3. Удалить импорты AudioManager и мертвые ссылки**
|
||||
- [ ] Удалить `import creator.loki.audio.AudioManager` из `BotInitializer`
|
||||
- [ ] Удалить `import creator.loki.audio.AudioManager` из `PrefixCommandRegistrar`
|
||||
- [ ] Удалить `import creator.loki.audio.AudioManager` из `SlashCommandRegistrar`
|
||||
- [ ] Удалить параметр `AudioManager audioManager` из конструкторов
|
||||
- [ ] Удалить поля `private final AudioManager audioManager`
|
||||
- [ ] Удалить `registry.register(new TtsCommand(...))` из `PrefixCommandRegistrar`
|
||||
- [ ] Удалить `registry.register(new TtsSlashCommand(...))` из `SlashCommandRegistrar`
|
||||
- [ ] Исправить `registry.register(new NewLeaderboardCommand(...))` → использовать новый путь
|
||||
- [ ] Удалить все `registry.register(new *SlashCommand(...))` из `SlashCommandRegistrar`
|
||||
- [ ] Удалить `import creator.loki.command.slash.*` из `SlashCommandRegistrar`
|
||||
- [ ] Проверить компиляцию: `gradle build`
|
||||
- [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/**
|
||||
- [ ] Создать `feature/level/`
|
||||
- [ ] Создать `feature/level/domain/`
|
||||
- [ ] Создать `feature/level/domain/XpFormula.java`:
|
||||
```java
|
||||
public class XpFormula {
|
||||
private static final int XP_PER_LEVEL = 200;
|
||||
|
||||
// Исправленная формула: 200 * n * (n+1) / 2
|
||||
public int getTotalXPForLevel(int level) {
|
||||
return XP_PER_LEVEL * level * (level + 1) / 2;
|
||||
}
|
||||
|
||||
// Обратная формула с использованием XP_PER_LEVEL
|
||||
public int calculateLevel(int xp) {
|
||||
double discriminant = 1 + 8.0 * xp / XP_PER_LEVEL;
|
||||
return (int) Math.floor((-1 + Math.sqrt(discriminant)) / 2.0);
|
||||
}
|
||||
}
|
||||
```
|
||||
- [ ] Вынести `LevelUpResult` из `LevelSystem` → `feature/level/domain/LevelUpResult.java`
|
||||
- [ ] Вынести `LevelProgress` из `LevelSystem` → `feature/level/domain/LevelProgress.java`
|
||||
- [ ] Переместить `level/UserStats` → `feature/level/domain/UserStats.java`
|
||||
- [ ] **НЕ делать immutable сейчас** (Gson требует сеттеры, сделаем после Repository)
|
||||
- [ ] Добавить `equals()` и `hashCode()` в `UserStats`
|
||||
- [ ] Переименовать `incrementMessages()` → `recordMessage(long timestamp)`
|
||||
- [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/**
|
||||
- [ ] Создать `feature/level/service/`
|
||||
- [ ] Создать `feature/level/service/MessageCooldownService.java`:
|
||||
- Персистентный кулдаун через `UserStats.lastMessageTime`
|
||||
- Убрать `ConcurrentHashMap messageTimestamps`
|
||||
- [ ] Создать `feature/level/service/LeaderboardService.java`:
|
||||
- Вынести методы `getTopByLevel`, `getTopByMessages`, `getTopByVoice`
|
||||
- Обобщить через `Comparator<UserStats>`
|
||||
- [ ] Рефакторить `level/LevelSystem` → `feature/level/service/LevelService.java`:
|
||||
- Убрать God Class: только бизнес-логика начисления XP
|
||||
- Использовать `UserStatsRepository` вместо `JsonDataStore`
|
||||
- Использовать `XpFormula` для вычислений
|
||||
- Использовать `MessageCooldownService` для кулдаунов
|
||||
- Убрать методы лидерборда (в `LeaderboardService`)
|
||||
- Убрать `getAllStats()` (в Repository)
|
||||
- [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/**
|
||||
- [ ] Переместить `command/impl/stats/RankCommand` → `feature/level/RankCommand`
|
||||
- [ ] Переместить `command/impl/stats/StatsCommand` → `feature/level/StatsCommand`
|
||||
- [ ] Переместить `listener/LevelUpNotifier` → `feature/level/LevelUpNotifier`
|
||||
- [ ] Переместить `listener/VoiceTracker` → `feature/level/VoiceTracker`
|
||||
- [ ] Переместить `profile/LevelUtils` → `feature/level/LevelUtils` (если нужен)
|
||||
- [ ] Удалить пустую папку `level/`
|
||||
- [ ] Обновить все импорты
|
||||
- [ ] Обновить `BotInitializer`, `BotModule`, `PrefixCommandRegistrar`
|
||||
- [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`:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue