# TODO — LoChat Critical Fixes & Config Refactor > Дата: 17.03.2026 > Статус: ✅ КРИТИЧНЫЕ БАГИ ИСПРАВЛЕНЫ | ✅ РЕФАКТОРИНГ КОНФИГОВ ЗАВЕРШЁН --- ## ✅ ИСПРАВЛЕНО ### 1. ✅ УТЕЧКА ПАМЯТИ: Scheduled Tasks **Статус:** ИСПРАВЛЕНО - AutoMessageManager теперь сохраняет ссылку на task и отменяет в `stop()` - Добавлена проверка и отмена старой задачи перед созданием новой ### 2. ✅ УТЕЧКА ПАМЯТИ: Event Listeners **Статус:** ИСПРАВЛЕНО - Добавлен `HandlerList.unregisterAll(this)` в `LoChat.onDisable()` - Listeners корректно отменяются при выключении плагина ### 3. ✅ УТЕЧКА ПАМЯТИ: MuteHistoryManager **Статус:** ИСПРАВЛЕНО - Добавлен лимит MAX_HISTORY_PER_PLAYER = 50 записей - Старые записи автоматически удаляются ### 4. ✅ RACE CONDITION: AsyncChatEvent **Статус:** ИСПРАВЛЕНО - Добавлен try-catch для безопасной работы с Location в async - Кэшируются данные перед async операциями ### 5. ✅ КОМПИЛЯЦИЯ: EnhancedChatRenderer **Статус:** ИСПРАВЛЕНО - Исправлена переменная `appearanceCfg` → `cfg.getAppearanceConfig()` ### 6. ✅ РЕФАКТОРИНГ КОНФИГОВ **Статус:** ЗАВЕРШЁН - Создан базовый класс `BaseConfig` для избежания дублирования кода - Переименован `HardcodedMessages` → `MessagesConfig` - Все конфиги остались в папке `config/` для удобства - Структура: `plugins/LoChat/config/*.yml` - Правильное копирование файлов из `resources/config/` ### 7. ✅ ОТКЛЮЧЕНИЕ ЧАТОВ **Статус:** РЕАЛИЗОВАНО - Добавлена проверка `isGlobalEnabled()` и `isLocalEnabled()` - Игроки получают сообщение если чат отключен - Настройки в `config.yml`: `chat.global.enabled` и `chat.local.enabled` ### 8. ✅ БАГ: Пробел в табе между префиксом и ником **Статус:** ИСПРАВЛЕНО - Убрал `.stripTrailing()` из `DisplayNameUtil.buildColoredPrefix()` - Теперь пробел из `prefix-format: "[{prefix}] "` сохраняется - В табе отображается: `[Префикс] Ник` вместо `[Префикс]Ник` ### 9. ✅ РЕФАКТОРИНГ: Главный класс LoChat **Статус:** ЗАВЕРШЁН - Создан `PluginInitializer` - вся логика инициализации - Создан `PluginShutdown` - вся логика выключения - Главный класс сократился с 185 до 108 строк (42% уменьшение) - Следует Single Responsibility Principle ### 10. ✅ ЧИСТКА: Warnings и deprecated методы **Статус:** ИСПРАВЛЕНО - Заменил deprecated `Registry.SOUNDS.match()` на `Registry.SOUNDS.get(NamespacedKey)` (Paper API) - Удалил все неиспользуемые импорты - Убрал redundant interface `TabCompleter` из `RollCommand` - Проект собирается без ошибок --- ## 📁 СТРУКТУРА КОНФИГОВ ``` plugins/LoChat/ ├── config.yml # Основной конфиг ├── messages.yml # Сообщения игрокам ├── custom-commands.yml # Кастомные команды ├── config/ │ ├── appearance.yml # ✅ Внешний вид чата (AppearanceConfig) │ ├── messages.yml # ✅ Системные сообщения (MessagesConfig) │ ├── mute.yml # ✅ Настройки мутов (MuteConfig) │ ├── filters.yml # ✅ Фильтры сообщений (FiltersConfig) │ ├── sounds.yml # ✅ Звуки (SoundsConfig) │ ├── discord.yml # ✅ Discord интеграция (DiscordIntegration) │ ├── gradient.yml # ✅ Градиенты (GradientModule) │ ├── automessages.yml # Автосообщения │ ├── chat-formats.yml # Форматы чата │ ├── database.yml # База данных │ └── integrations.yml # Интеграции └── data/ ├── players.yml ├── mutes.json ├── filter-words.json └── ... ``` ### ✅ Подключенные конфиги: - `AppearanceConfig` - внешний вид чата, префиксы, цвета, эмодзи - `MessagesConfig` - все системные сообщения для игроков - `MuteConfig` - настройки системы мутов - `FiltersConfig` - все фильтры (капс, мат, реклама, флуд, спам) - `SoundsConfig` - звуковые эффекты - `DiscordIntegration` - Discord вебхуки - `GradientModule` - градиентные ники --- ## 🎯 АРХИТЕКТУРА ### BaseConfig Базовый класс для всех конфигов: - Автоматическое копирование из resources - Поддержка подпапок (config/) - Единый интерфейс load/reload/save - Избегает дублирования кода ### Конфиги наследуют BaseConfig: - `MessagesConfig` (config/messages.yml) - `AppearanceConfig` (config/appearance.yml) - Легко добавлять новые конфиги --- ## ✅ ЗАДАЧА ВЫПОЛНЕНА: Очистка config.yml ### ✅ РЕЗУЛЬТАТ: - Сократил config.yml с 300+ строк до 44 строк (85% уменьшение!) - Убрал дублирующиеся секции (filters, mentions, automessages, mute) - Убрал раздутые секции (custom-commands, data-storage) - Убрал пресеты градиентов - Оставил только базовые настройки (chat, hub, gradient, rp) - Проект собирается без ошибок ### 🔍 СТАТУС КОНФИГОВ: Все конфиги в config/ проверены и почищены: - ✅ appearance.yml (AppearanceConfig) - используется - ✅ messages.yml (MessagesConfig) - используется - ✅ mute.yml (MuteConfig) - используется - ✅ filters.yml (FiltersConfig) - используется - ✅ sounds.yml (SoundsConfig) - используется - ✅ discord.yml (DiscordIntegration) - используется - ❌ automessages.yml - удален (не использовался) - ❌ chat-formats.yml - удален (не использовался) - ❌ database.yml - удален (не использовался) - ❌ gradient.yml - удален (не использовался) - ❌ integrations.yml - удален (не использовался) --- ## ✅ ЗАДАЧА ВЫПОЛНЕНА: Thread-Safety для ConfigManager ### ✅ РЕЗУЛЬТАТ: - Добавлен `volatile` для всех конфигов (config, appearanceConfig, messagesConfig, muteConfig, filtersConfig, soundsConfig) - Метод `reload()` теперь `synchronized` для предотвращения race conditions - Все потоки теперь видят актуальную версию конфигов после reload - Проект собирается без ошибок ### 📝 ЧТО СДЕЛАНО: ```java // Было: private FileConfiguration config; private AppearanceConfig appearanceConfig; // Стало: private volatile FileConfiguration config; private volatile AppearanceConfig appearanceConfig; // И метод reload стал synchronized: public synchronized void reload() { ... } ``` **Зачем volatile:** - Гарантирует видимость изменений между потоками - Предотвращает кэширование значений в регистрах CPU - Обеспечивает happens-before relationship **Зачем synchronized:** - Предотвращает одновременный reload из разных потоков - Гарантирует атомарность операции перезагрузки --- ## 🔧 ОСТАЛОСЬ (НИЗКИЙ ПРИОРИТЕТ) ### ПРОИЗВОДИТЕЛЬНОСТЬ: Фильтры - Рассмотреть Aho-Corasick алгоритм для поиска матных слов - Добавить метрики производительности ### БЕЗОПАСНОСТЬ: Discord rate limiting - Добавить локальный rate limiter --- ## ✅ ИТОГ Все критичные баги исправлены. Плагин полностью готов к использованию. **Выполнено:** - ✅ Исправлены утечки памяти (tasks, listeners, history) - ✅ Исправлены race conditions - ✅ Рефакторинг конфигов (BaseConfig, MessagesConfig, FiltersConfig, SoundsConfig, MuteConfig) - ✅ Очистка config.yml (300+ → 52 строки) - ✅ Thread-safety для ConfigManager (volatile + synchronized) - ✅ Баг с пробелом в табе - ✅ Рефакторинг главного класса (185 → 108 строк) - ✅ Чистка warnings и deprecated методов - ✅ Режим единого чата (опционально через local.enabled: false) **Архитектура:** - SOLID принципы (ServiceRegistry, DI) - Чистый код (Single Responsibility) - Thread-safe reload - Минимальный главный класс Проект собирается без ошибок и готов к продакшену. --- ## 📋 ПЛАН ИСПРАВЛЕНИЯ КРИТИЧНЫХ БАГОВ ### Фаза 1: Утечки памяти (СРОЧНО) 1. **AutoMessageManager** - сохранять ссылку на task и отменять в `stop()` 2. **LoChat.onDisable()** - добавить `HandlerList.unregisterAll(this)` 3. **MuteHistoryManager** - ограничить размер истории (MAX 50 записей на игрока) ### Фаза 2: Race conditions 4. **ChatEventListener** - проверить `DistanceUtil.isInRange()` на async-safety 5. **ConfigManager** - использовать `volatile` для thread-safe reload ### Фаза 3: Компиляция 6. **EnhancedChatRenderer** - исправить `appearanceCfg` → `cfg.getAppearanceConfig()` --- ## 📋 ПЛАН ИСПРАВЛЕНИЯ КОНФИГОВ ### Вариант 1: Всё в config.yml (РЕКОМЕНДУЕТСЯ) Объединить все настройки в один `config.yml` с секциями. **Структура config.yml:** ```yaml config-version: 5 # Базовые настройки chat: global: enabled: true cooldown: 3 local: enabled: true radius: 100 cooldown: 1 pm: enabled: true sound: true # Внешний вид чата chat-appearance: prefixes: global: emoji: "✦" text: "GLOBAL" colors: - "#B798A8" - "#7858E9" separator: text: " ▶ " color: "#9878C9" local: emoji: "◆" text: "LOCAL" colors: - "#9878C9" - "#7858E9" separator: text: " ▶ " color: "#8B6BD6" hover: enabled: true format: - "ẲE9▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬" - "&#B798A8✦ &f{player}" - "" - "⚖C9⏱ &fПинг: ẲE9{ping}ms" - "⚖C9♥ &fЗдоровье: ẲE9{health}/20" - "⚖C9🍖 &fГолод: ẲE9{food}/20" - "" - "ẲE9▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬▬" - "&#B798A8✦ &fНажми чтобы написать" emojis: ":heart:": "❤" ":star:": "★" ":diamond:": "◆" # Сообщения messages: mute: player-muted: "⚖C9Игрок ẲE9{player} ⚖C9замучен на ẲE9{time}" muted-message: "&#CF6679Вы замучены на ẲE9{time}\n&#B798A8Причина: &f{reason}" local-chat: nobody-heard: "⚖C9Вас никто не услышал" cooldown: message: "&#B798A8Подождите ẲE9{remaining} &#B798A8сек" # RP команды rp: radius: 100 cooldowns: me: 3 try: 5 do: 3 roll: 2 # Градиенты gradient: enabled: true presets: fire: ["#FF4500", "#FF6347", "#FFD700"] ocean: ["#00CED1", "#1E90FF", "#4169E1"] ``` **Файлы для изменения:** 1. `src/main/resources/config.yml` - объединить все настройки 2. `src/main/java/com/loki/lochat/config/ConfigManager.java` - убрать AppearanceConfig и HardcodedMessages 3. `src/main/java/com/loki/lochat/renderer/EnhancedChatRenderer.java` - читать из ConfigManager напрямую 4. Удалить `src/main/java/com/loki/lochat/config/AppearanceConfig.java` 5. Удалить `src/main/java/com/loki/lochat/config/HardcodedMessages.java` 6. Удалить все файлы из `src/main/resources/config/` --- ### Вариант 2: Отдельные файлы в корне resources Переместить конфиги в корень `resources/` и создавать их вручную. **Структура:** ``` src/main/resources/ ├── config.yml # Основной конфиг ├── chat-appearance.yml # Внешний вид ├── messages.yml # Сообщения ├── gradient-config.yml # Градиенты └── custom-commands.yml # Кастомные команды ``` **Файлы для изменения:** 1. Переместить все из `config/` в корень `resources/` 2. `AppearanceConfig.java` - изменить путь с `config/chat-appearance.yml` на `chat-appearance.yml` 3. `HardcodedMessages.java` - изменить путь с `config/hardcoded-messages.yml` на `messages.yml` 4. Убрать создание папки `config/` в коде --- ## 🎯 РЕКОМЕНДАЦИЯ **Использовать Вариант 1** - один большой `config.yml`: - ✅ Всё в одном месте - ✅ Гарантированно работает - ✅ Проще для пользователей - ✅ Меньше файлов - ✅ Только hex-цвета (&#FFD700) --- ## 📝 ЧЕКЛИСТ ВЫПОЛНЕНИЯ ### Шаг 1: Подготовка - [ ] Сохранить текущие настройки из всех конфигов - [ ] Создать бэкап проекта ### Шаг 2: Объединение конфигов - [ ] Скопировать все секции из `config/chat-appearance.yml` в `config.yml` - [ ] Скопировать все секции из `config/hardcoded-messages.yml` в `config.yml` - [ ] Заменить все ``, `` на hex-цвета `&#FF0000` - [ ] Проверить отступы YAML ### Шаг 3: Изменение кода - [ ] `ConfigManager.java` - убрать `AppearanceConfig` и `HardcodedMessages` - [ ] `ConfigManager.java` - добавить методы для чтения всех настроек из `config.yml` - [ ] `EnhancedChatRenderer.java` - заменить `cfg.getAppearanceConfig()` на прямые вызовы - [ ] Удалить `AppearanceConfig.java` - [ ] Удалить `HardcodedMessages.java` ### Шаг 4: Очистка - [ ] Удалить папку `src/main/resources/config/` - [ ] Удалить неиспользуемые импорты ### Шаг 5: Тестирование - [ ] `./gradlew clean build -x test` - [ ] Проверить что jar собирается - [ ] Запустить на тестовом сервере - [ ] Проверить что `config.yml` создаётся - [ ] Проверить что все настройки работают --- ## 🔧 ТЕКУЩЕЕ СОСТОЯНИЕ **Проблемные файлы:** - `src/main/java/com/loki/lochat/renderer/EnhancedChatRenderer.java` - ошибки компиляции - `src/main/java/com/loki/lochat/config/ConfigManager.java` - неполный рефакторинг **Что работает:** - Базовые настройки чата - Градиенты - RP команды с кулдаунами **Что НЕ работает:** - Файлы из `config/` не копируются на сервер - Префиксы чата (читаются из несуществующих файлов) - Hover подсказки - Эмодзи замены --- ## 📌 ВАЖНО - Использовать ТОЛЬКО hex-цвета: `&#FFD700` - НЕ использовать MiniMessage: ``, `` - Все настройки в `config.yml` - Простая и понятная структура