chore: add PMD 7.8.0 and fix warnings/antipatterns

- build.gradle.kts: add pmd plugin with security/bestpractices ruleset (UnusedPrivateField, PreserveStackTrace, AvoidPrintStackTrace, CloseResource, etc), html/xml reports
- fix 8 deprecation warnings: Bukkit.getOfflinePlayer(String) suppressed via @SuppressWarnings(deprecation) in ColorCommandHandler, PrefixCommandHandler, GradientAdminCommand, PlayerUtil
- fix 9 try-resource warnings in IgnoreServiceTest via @SuppressWarnings({"try","PMD.UnusedLocalVariable"})
- PMD fixes: AvoidPrintStackTrace -> logger.log in BaseCommand, MuteHistoryManager, CustomCommandManager; CloseResource via try-with-resources in BaseConfig, GradientMessages, GradientDataManager, DiscordConfig; UnusedPrivateField removed plugin field in PlayerEventListener; MuteHistoryManager System.err -> logger
- verified: gradle clean build pmdMain pmdTest checkstyleMain checkstyleTest test shadowJar all green, zero javac warnings, no secrets found, antipatterns (Thread.sleep in async webhook/rate-limiter kept isolated, printStackTrace removed)
This commit is contained in:
loki5512344 2026-09-20 16:56:02 +02:00
parent 83e980d1bb
commit bd39118b14
Signed by: boba
GPG key ID: 253067914055423B
14 changed files with 85 additions and 34 deletions

View file

@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.logging.Level;
/**
* Базовый класс для всех команд плагина
@ -30,8 +31,7 @@ public abstract class BaseCommand implements CommandExecutor, TabCompleter {
try {
return executeCommand(sender, command, label, args);
} catch (Exception e) {
plugin.getLogger().severe("Ошибка в команде " + command.getName() + ": " + e.getMessage());
e.printStackTrace();
plugin.getLogger().log(Level.WARNING, "Ошибка в команде " + command.getName() + ": " + e.getMessage(), e);
sender.sendMessage("§cПроизошла ошибка при выполнении команды!");
return true;
}

View file

@ -68,13 +68,13 @@ public abstract class BaseConfig {
if (!configFile.exists()) {
try {
String resourcePath = inConfigFolder ? "config/" + fileName : fileName;
InputStream in = plugin.getResource(resourcePath);
if (in != null) {
Files.copy(in, configFile.toPath());
in.close();
plugin.getLogger().info("Created config file: " + (inConfigFolder ? "config/" : "") + fileName);
} else {
plugin.getLogger().warning("Resource not found: " + resourcePath);
try (InputStream in = plugin.getResource(resourcePath)) {
if (in != null) {
Files.copy(in, configFile.toPath());
plugin.getLogger().info("Created config file: " + (inConfigFolder ? "config/" : "") + fileName);
} else {
plugin.getLogger().warning("Resource not found: " + resourcePath);
}
}
} catch (Exception e) {
plugin.getLogger().warning("Failed to copy " + fileName + ": " + e.getMessage());

View file

@ -24,6 +24,8 @@ import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MuteHistoryManager {
@ -112,7 +114,7 @@ public class MuteHistoryManager {
}
moveIntoPlace(tmp);
} catch (IOException e) {
System.err.println("Failed to save mute history: " + e.getMessage());
Logger.getLogger(MuteHistoryManager.class.getName()).log(Level.WARNING, "Failed to save mute history", e);
} finally {
lock.unlock();
}
@ -140,7 +142,7 @@ public class MuteHistoryManager {
history.putAll(loaded);
}
} catch (IOException e) {
e.printStackTrace();
Logger.getLogger(MuteHistoryManager.class.getName()).log(Level.WARNING, "Failed to load mute history", e);
}
}
}

View file

@ -95,6 +95,7 @@ public class GradientAdminCommand implements CommandExecutor, TabCompleter {
sender.sendMessage("§e/aprefix updateall §7— обновить display names всех игроков");
}
@SuppressWarnings("deprecation")
private void handleInfo(CommandSender sender, String playerName, GradientMessages msg) {
OfflinePlayer target = Bukkit.getOfflinePlayer(playerName);
if (!target.hasPlayedBefore() && !target.isOnline()) {

View file

@ -29,6 +29,7 @@ public class ColorCommandHandler {
/**
* Установить цвет игроку
*/
@SuppressWarnings("deprecation")
public void handleSetColor(CommandSender sender, String[] args, GradientMessages msg) {
if (args.length < 3) {
sender.sendMessage("§cИспользование: /aprefix setcolor <игрок> <цвет1> [цвет2] ...");
@ -69,6 +70,7 @@ public class ColorCommandHandler {
/**
* Включить/выключить цвет
*/
@SuppressWarnings("deprecation")
public void handleColorToggle(CommandSender sender, String[] args, boolean enable, GradientMessages msg) {
if (args.length < 2) {
sender.sendMessage("§cИспользование: /aprefix " + (enable ? "coloron" : "coloroff") + " <игрок>");
@ -93,6 +95,7 @@ public class ColorCommandHandler {
/**
* Сбросить цвет
*/
@SuppressWarnings("deprecation")
public void handleResetColor(CommandSender sender, String[] args, GradientMessages msg) {
if (args.length < 2) {
sender.sendMessage("§cИспользование: /aprefix resetcolor <игрок>");

View file

@ -25,6 +25,7 @@ public class PrefixCommandHandler {
/**
* Установить префикс игроку
*/
@SuppressWarnings("deprecation")
public void handleSetPrefix(CommandSender sender, String[] args, GradientMessages msg) {
if (args.length < 3) {
sender.sendMessage("§cИспользование: /aprefix setprefix <игрок> <префикс>");
@ -65,6 +66,7 @@ public class PrefixCommandHandler {
/**
* Включить/выключить префикс
*/
@SuppressWarnings("deprecation")
public void handlePrefixToggle(CommandSender sender, String[] args, boolean enable, GradientMessages msg) {
if (args.length < 2) {
sender.sendMessage("§cИспользование: /aprefix " + (enable ? "prefixon" : "prefixoff") + " <игрок>");
@ -89,6 +91,7 @@ public class PrefixCommandHandler {
/**
* Сбросить префикс
*/
@SuppressWarnings("deprecation")
public void handleResetPrefix(CommandSender sender, String[] args, GradientMessages msg) {
if (args.length < 2) {
sender.sendMessage("§cИспользование: /aprefix resetprefix <игрок>");

View file

@ -37,11 +37,14 @@ public class GradientMessages {
}
messages = YamlConfiguration.loadConfiguration(messagesFile);
InputStream defStream = plugin.getResource("messages.yml");
if (defStream != null) {
YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(
new InputStreamReader(defStream, StandardCharsets.UTF_8));
messages.setDefaults(defConfig);
try (InputStream defStream = plugin.getResource("messages.yml")) {
if (defStream != null) {
YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(
new InputStreamReader(defStream, StandardCharsets.UTF_8));
messages.setDefaults(defConfig);
}
} catch (java.io.IOException e) {
plugin.getLogger().warning("Failed to load default messages.yml: " + e.getMessage());
}
}

View file

@ -104,18 +104,19 @@ public class GradientDataManager {
"SELECT prefix, colors, color_enabled, prefix_enabled, "
+ "prefix_purchased, last_color_change, last_prefix_change FROM gradient_data WHERE uuid = ?")) {
stmt.setString(1, uuid.toString());
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
data.setPrefix(rs.getString("prefix"));
String colorsStr = rs.getString("colors");
if (colorsStr != null && !colorsStr.isEmpty()) {
data.setColors(List.of(colorsStr.split(",")));
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
data.setPrefix(rs.getString("prefix"));
String colorsStr = rs.getString("colors");
if (colorsStr != null && !colorsStr.isEmpty()) {
data.setColors(List.of(colorsStr.split(",")));
}
data.setColorEnabled(rs.getBoolean("color_enabled"));
data.setPrefixEnabled(rs.getBoolean("prefix_enabled"));
data.setPrefixPurchased(rs.getBoolean("prefix_purchased"));
data.setLastColorChange(rs.getLong("last_color_change"));
data.setLastPrefixChange(rs.getLong("last_prefix_change"));
}
data.setColorEnabled(rs.getBoolean("color_enabled"));
data.setPrefixEnabled(rs.getBoolean("prefix_enabled"));
data.setPrefixPurchased(rs.getBoolean("prefix_purchased"));
data.setLastColorChange(rs.getLong("last_color_change"));
data.setLastPrefixChange(rs.getLong("last_prefix_change"));
}
} catch (SQLException e) {
plugin.getLogger().warning("Ошибка загрузки gradient данных: " + e.getMessage());

View file

@ -25,11 +25,9 @@ public class DiscordConfig {
File configFile = new File(configFolder, "discord.yml");
if (!configFile.exists()) {
try {
java.io.InputStream in = plugin.getResource("config/discord.yml");
try (java.io.InputStream in = plugin.getResource("config/discord.yml")) {
if (in != null) {
java.nio.file.Files.copy(in, configFile.toPath());
in.close();
}
} catch (Exception e) {
plugin.getLogger().warning("Failed to copy config/discord.yml: " + e.getMessage());

View file

@ -23,7 +23,6 @@ import org.bukkit.inventory.ItemStack;
* Слушатель событий игрока
*/
public class PlayerEventListener implements Listener {
private final LoChat plugin;
private final PlayerService playerService;
private final MessagingService messagingService;
private final NickService nickService;
@ -32,7 +31,6 @@ public class PlayerEventListener implements Listener {
public PlayerEventListener(LoChat plugin, PlayerService playerService, MessagingService messagingService,
NickService nickService, AdvancedMessageFilter advancedFilter) {
this.plugin = plugin;
this.playerService = playerService;
this.messagingService = messagingService;
this.nickService = nickService;

View file

@ -19,6 +19,7 @@ import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
public class CustomCommandManager {
@ -101,8 +102,7 @@ public class CustomCommandManager {
}
} catch (Exception e) {
plugin.getLogger().severe("Ошибка регистрации команды " + data.name() + ": " + e.getMessage());
e.printStackTrace();
plugin.getLogger().log(Level.WARNING, "Ошибка регистрации команды " + data.name() + ": " + e.getMessage(), e);
}
}

View file

@ -54,6 +54,7 @@ public final class PlayerUtil {
* @param name имя игрока
* @return UUID игрока или null если не найден
*/
@SuppressWarnings("deprecation")
public static UUID findPlayerUUID(String name) {
// Сначала ищем онлайн игрока
Player onlinePlayer = Bukkit.getPlayer(name);