- Remove HardcoreMode (lose all rewards on fall) - Disable Elytra mode in default config - Add todo.md with 20 identified bugs - Fix 3 remaining bugs: checkPlayerFall continue, removeTrailBlocks sync, scoredBlocks clear on fall
8.9 KiB
8.9 KiB
LoParkour Bug Tracker
CRITICAL
1. ProfileValue.asInt/asDouble — NumberFormatException при пустой строке
- Файл:
Profile.java:57-58 - Описание:
Integer.parseInt(value)иDouble.parseDouble(value)падают при пустой строке"", которая возвращается по умолчанию при отсутствии ключа (new ProfileValue("")) - Фикс: Добавить дефолтное значение либо кидать понятное исключение, а не NFE
2. Bukkit.createBlockData — IllegalArgumentException при невалидном materialName
- Файл:
GeneratorProfileManager.java:133 - Описание: Если materialName из конфига невалидный (опечатка в generation.yml),
Bukkit.createBlockData()кинет исключение - Фикс: Валидировать materialName перед вызовом, либо ловить конкретно на строке 133
3. JumpDirector диагональный дрейф — heading никогда не выпрямляется
- Файл:
JumpDirector.java:87-99 - Описание:
getRecommendedHeading()всегда создаетVector(1,0,1)для X и Z границ. После нормализации heading становится диагональным и НИКОГДА не возвращается к осевому направлению - Фикс: Использовать
Vector(1,0,0)для X иVector(0,0,1)для Z. Сбрасывать heading на исходный при отсутствии границы
4. subList().clear() на synchronizedList(LinkedList) — повреждение node связей
- Файл:
GeneratorCleanup.java:50-56 - Описание:
history.subList(0, removeCount).clear()наCollections.synchronizedList(new LinkedList<>())— compound операция не атомарна. ConcurrentModificationException или повреждение связей - Фикс: Оборачивать в
synchronized(history)или использовать CopyOnWriteArrayList
5. Мультиплеер — runaway генерация блоков
- Файл:
PlayerInteractionHandler.java:116-118+LifecycleTickManager.java:89-97 - Описание: Каждый игрок триггерит
generate(1)при скоре. N игроков = N блоков/тик. maintainBlockLead добавляет еще. Положительная обратная связь - Фикс: Не больше 1 блока за тик независимо от числа игроков, кэп на maintainBlockLead
6. Система схематик полностью сломана
- Файл:
PlayerInteractionHandler.java:111-113+BlockPlacer.java:207-212 - Описание:
isSchematicEndBlockвозвращает true для ЛЮБОГО schematic блока. При входе в схематик сразу удаляется + блоки засчитываются как очки - Фикс:
isSchematicEndBlockдолжен проверять только ПОСЛЕДНИЙ блок схематика. Исключить schematic блоки из скоринга
7. Прыжки за границами валидации
- Файл:
JumpCalculator.java:101-114 - Описание: JumpOffsetGenerator генерирует offset до 5 блоков, total horizontal = sqrt(4²+5²)=6.4 при лимите 4.1. Retry-цикл не гарантирует валидность за 10 попыток
- Фикс: Ограничить randomOffset пределами валидатора:
maxRandomOffset = sqrt(maxHorizontal² - distance²)
HIGH
8. angleInY вращает offset относительно глобального Option.HEADING
- Файл:
JumpCalculator.java:105-113 - Описание: rotateAroundY использует разницу между текущим heading и Option.HEADING, а не между текущим и предыдущим heading. Блоки уходят вбок
- Фикс: Вращать offset относительно предыдущего heading
9. Дублирование canJump(Location) и canJump(Vector) — рассинхронизация
- Файл:
JumpValidator.java:73-161 - Описание: Два метода canJump. Location-версия учитывает slab-корректировку, Vector — нет
- Фикс: Убрать дублирование или добавить adjustment в Vector-версию
10. synchronizedList — итерации без синхронизации
- Файл:
GeneratorState.java:35 - Описание: Итерации по
history(cleanupDistantBlocks, historyContains, indexOfBlock) не обернуты вsynchronized. Пока все на main thread, но это хрупко - Фикс: Добавить
synchronized(history)на все итерации, либо убрать synchronizedList
11. heading.clone() без null-проверки
- Файл:
JumpCalculator.java:101-103 - Описание:
generator.state.heading.clone()упадет с NPE, если heading не инициализирован до первого вызова calculateJumpOffset - Фикс: Добавить null-guard: если heading == null, инициализировать из Option.HEADING
MEDIUM
12. BlockSelector.selectBlockData рекурсия при пустом списке стилей
- Файл:
BlockSelector.java:32-33 - Описание: Если style == null, код сбрасывает стиль на первый.
orElseThrow()упадет, если список пуст - Фикс: Проверка
if (styles.isEmpty()) return Material.STONE.createBlockData()
13. checkPlayerFall — break вместо continue
- Файл:
LifecycleTickManager.java:74-78 - Описание: При падении двух игроков в одном тике, второй пропускает обработку до следующего тика
- Фикс: Заменить break на continue
14. removeTrailBlocks сдвигает индексы истории
- Файл:
GeneratorCleanup.java:79-93 - Описание:
history.subList(startIndex, endIndex).clear()сдвигает индексы при параллельном вызове historyContains - Фикс: Защититься копированием или проверять синхронизацию
15. Дублирование isSlabMaterial
- Файл:
JumpValidator.java:67-71 - Описание: JumpValidator и BlockSelector имеют дублирующуюся логику определения slab. Рассинхронизация при изменениях
- Фикс: Вынести в общий утилитарный метод
16. DifficultyScore thresholds для льда (1.0/2.0) могут быть недостижимы
- Файл:
GeneratorProfileManager.java:57-69 - Описание: packed_ice добавляется при difficulty >= 1.0, blue_ice при >= 2.0. Многие конфиги не достигают этих значений. Лед не появляется
- Фикс: Нормализовать difficulty до предсказуемой шкалы или изменить thresholds
17. schematicBlocks — ArrayList без thread safety
- Файл:
GeneratorState.java:41 - Описание: schematicBlocks это plain ArrayList, без синхронизации, в отличие от history
- Фикс: Добавить синхронизацию или документировать main-thread-only
LOW
18. scoredBlocks HashSet не очищается при fall
- Файл:
ParkourPlayer.java:125-127 - Описание: HashSet растет бесконечно. При возрождении на тех же координатах не засчитает блоки
- Фикс: scoredBlocks.clear() при fall/reset
19. getFormattedTime() — Date(elapsed) хак
- Файл:
GeneratorStatistics.java:90-91 - Описание:
new Date(elapsed)— Date ожидает timestamp от 1970, а передается длительность. Сломается при >24ч - Фикс: Использовать Duration API для форматирования
20. isUnsafeParkourMaterial блокирует PUMPKIN и _BED без причины
- Файл:
BlockSelector.java:48-60 - Описание: PUMPKIN не имеет onPlace-сканирования соседей. _BED безопасны при setBlockData с флагом false
- Фикс: Убрать лишние исключения