Fix:
Fixed fish item lore showing raw rarity level (e.g. "epic:90") instead of configured display name (e.g. "史诗") Fixed 100% charge being treated as overcharge (throw power became 0) Fixed hook floating effect task never terminating, causing task leaks Fixed hook trajectory task not tracked, unable to cancel on session end Fixed Particle API incompatibility on 1.21+ (extra parameter type mismatch) Fixed dangerZone array out of bounds in minigame (index 10 on size-10 array) Fixed severe performance issue: rod name parsed every tick in minigame Fixed duplicate session check missing in 2/3-argument startMinigame Fixed OP privilege escalation without try-finally in GUIAction Fixed fish selling losing items when player inventory is full Fixed ClassCastException from database Number types in GUI stats Fixed MySQL incompatibility: INSERT OR REPLACE and AUTOINCREMENT syntax Fixed getConnection() returning null causing NullPointerException (19 call sites) Fixed sellAllFish not collecting fish UUIDs for database cleanup Fixed clearAllCache clearing all players' cache on any player quit Fixed i✨idLocation always returning false, void fishing completely broken Fixed cleanupAndAnnounce callable twice, causing duplicate rewards Fixed PointsOnlyCompetition giving 1.0 points for fish not in fishList Fixed reflection method lookup every tick (now cached as static field) Fixed cross-world distance() call throwing IllegalArgumentException Fixed fishLevel.split NPE when fishLevel is null Fixed hookMaterial.toLowerCase NPE when database returns null Fixed isHookPassableBlock using hardcoded strings instead of Set lookup Fixed shared StringBuilder/Vector/Location instance fields causing thread safety issues Fixed new Random() created frequently instead of reusing instance field Fixed charge tick sound never playing due to millisecond precision mismatch Fixed checkAndConsumeBait setting null instead of AIR for empty offhand Fixed fishSize/maxSize division by zero when maxSize is 0 Fixed rare fish getting double bonus (10% forced + rareFishBonus) Fixed invincibility period only increasing progress, never decreasing Fixed minigame run() without exception protection, leaving zombie sessions Fixed displayGameUI dead code with identical if-else branches Fixed player offline not handled during minigame, causing exceptions Fixed getRodNameByPlayer returning null instead of default "wood" Fixed duplicate actualFishValue declaration in inner class Fixed HashMap concurrency issues in GUI (6 maps changed to ConcurrentHashMap) Fixed GUIType.valueOf() throwing uncaught IllegalArgumentException Fixed direct Material enum usage in GUI violating XSeries rules (14 places) Fixed itemsPerPage inconsistency between GUI methods (36 vs 28) Fixed sellFishItem using unnecessary reflection for PDC access Fixed sellFishItem returning 1 for item rewards without depositing Vault value Fixed displayNameToHookNameMap not updating on config reload Fixed e.printStackTrace() violating logging rules Fixed onInventoryClose clearing search keywords for all GUI types Fixed SlotMapping getBorderSlotCount wrong calculation for 27-slot GUI Fixed RewardPreview isItemDisplaySlot range too small (27 instead of 54) Fixed GUI_SIZE_6 = 6 not being a valid inventory size (changed to 54) Fixed SQL injection risk from columnName concatenation (added whitelist) Fixed logFishing/updatePlayerStats using connection field instead of getConnection() Fixed cache returning mutable list reference allowing external pollution Fixed cache cleanup running every write instead of every 100 writes Fixed updatePlayerStats using two database round trips instead of one Fixed getConfigurationSection() NPE in Config (5 places) Fixed non-debug AuraSkills log output in production Fixed Double.parseDouble without exception handling Fixed isDebugMode/setDebugMode config path inconsistency Fixed dead code in ensureFishAnimationSubConfigs Fixed duplicated fish filtering logic in getAvailableFish/getAvailableFishFromPool Fixed Material.FISHING_ROD direct enum usage in Config Fixed parseMaterial returning null without warning in ItemValue Fixed Y-axis movement not restricted during fishing Fixed durability calculation overflow when maxSingleLoss < baseLoss Fixed getRodCurrentDurability missing rodType null check Fixed hook Y velocity unlimited descent in water mechanic Fixed lava mechanic missing Y<=0 boundary check Fixed lava/void hook messages using wrong language key (hook_in_water) Fixed hasEquipmentEffect based on Lore text matching, exploitable by players Fixed Compete shared mutable StringBuilder/ArrayList fields Fixed Compete containsKey+put TOCTOU race condition Fixed scheduleRecurring array index out of bounds on malformed config Fixed competition notification tasks not tracked, can't be cancelled Fixed scheduledTasks memory leak (completed tasks never removed) Fixed CompetitionData non-atomic operations on counters Fixed AmountCompetition/SingleValueCompetition/TotalValueCompetition not checking fishList filter Fixed PointsOnlyCompetition value double-counting in point calculation Fixed BarColor/BarStyle parse errors silently swallowed without warning Fixed hardcoded Chinese string in Cmd instead of MessageManager Fixed getFishValueFromItem querying database every call without cache Fixed getItemValue() null check missing in Cmd Fixed sellAllFish item rewards given multiple times for stacked items Fixed setFishUUIDString using unnecessary reflection for PDC Fixed Material.matchMaterial() in Cmd violating XSeries rules Fixed addGlowEffect empty method and dead guiCache code removed
Add:
Added fishList filter check to AmountCompetition, SingleValueCompetition, TotalValueCompetition Added clearPlayerCache method to DB for single-player cache clearing Added hook_in_lava and hook_in_void language keys Added competition_invalid_duration language key Added CompetitionUtils.formatDuration shared utility Added columnName whitelist validation in DB Added fishValueCache in Cmd for database query optimization