Update to Minecraft 1.21.8, add checkstyle, fix compilation errors

- Update Paper API: 1.20.1 -> 1.21.4
- Update plugin version: 1.5.5-1.20.1 -> 1.5.5-1.21.8
- Add checkstyle plugin with reasonable rules
- Fix Enchantment.LUCK -> Enchantment.UNBREAKING
- Fix EntityType.FIREWORK -> EntityType.FIREWORK_ROCKET
- Remove unused imports
- Add temp_*/ to .gitignore
- 118 files changed, 1633 insertions(+), 1301 deletions(-)
This commit is contained in:
loki5512344 2026-02-24 00:04:03 +01:00
parent 6a4c8a7886
commit e78d8a2de4
121 changed files with 1792 additions and 1301 deletions

View file

@ -8,28 +8,28 @@ import org.bukkit.plugin.Plugin;
* Менеджер для работы с Adventure API на Arclight/Forge серверах
*/
public class AdventureManager {
private static boolean adventureAvailable = false;
private static Object audiences;
public static void init(Plugin plugin) {
try {
// Проверяем наличие Adventure API
Class.forName("net.kyori.adventure.text.Component");
Class<?> audiencesClass = Class.forName("net.kyori.adventure.platform.bukkit.BukkitAudiences");
// Создаем BukkitAudiences через рефлексию
Object audiencesInstance = audiencesClass.getMethod("create", Plugin.class).invoke(null, plugin);
audiences = audiencesInstance;
adventureAvailable = true;
plugin.getLogger().info("Adventure API обнаружен - используем нативную поддержку");
} catch (Exception e) {
adventureAvailable = false;
plugin.getLogger().info("Adventure API не найден - используем legacy режим");
}
}
public static void shutdown() {
if (audiences != null && adventureAvailable) {
try {
@ -41,7 +41,7 @@ public class AdventureManager {
}
adventureAvailable = false;
}
public static void sendMessage(CommandSender sender, Object message) {
if (adventureAvailable && audiences != null) {
try {
@ -53,7 +53,7 @@ public class AdventureManager {
// Fallback на legacy
}
}
// Legacy fallback
if (message instanceof String) {
sender.sendMessage((String) message);
@ -61,7 +61,7 @@ public class AdventureManager {
sender.sendMessage(message.toString());
}
}
public static void sendMessage(Player player, Object message) {
if (adventureAvailable && audiences != null) {
try {
@ -73,7 +73,7 @@ public class AdventureManager {
// Fallback на legacy
}
}
// Legacy fallback
if (message instanceof String) {
player.sendMessage((String) message);
@ -81,7 +81,7 @@ public class AdventureManager {
player.sendMessage(message.toString());
}
}
public static boolean isAdventureAvailable() {
return adventureAvailable;
}

View file

@ -11,7 +11,8 @@ public final class ChatFormatter {
private static final PlainTextComponentSerializer PLAIN =
PlainTextComponentSerializer.plainText();
private ChatFormatter() {}
private ChatFormatter() {
}
/* ===================== BASIC ===================== */
@ -38,7 +39,7 @@ public final class ChatFormatter {
*/
private static String convertLegacyFormats(String message) {
if (message == null) return "";
// Конвертируем &#RRGGBB в <#RRGGBB>
java.util.regex.Pattern pattern1 = java.util.regex.Pattern.compile("&#([0-9a-fA-F]{6})");
java.util.regex.Matcher matcher1 = pattern1.matcher(message);
@ -49,7 +50,7 @@ public final class ChatFormatter {
}
matcher1.appendTail(sb1);
message = sb1.toString();
// Конвертируем #RRGGBB в <#RRGGBB> (только если не внутри тегов)
java.util.regex.Pattern pattern2 = java.util.regex.Pattern.compile("(?<!<)#([0-9a-fA-F]{6})(?![^<]*>)");
java.util.regex.Matcher matcher2 = pattern2.matcher(message);
@ -60,7 +61,7 @@ public final class ChatFormatter {
}
matcher2.appendTail(sb2);
message = sb2.toString();
// Конвертируем §[0-9a-fk-or] в соответствующие MiniMessage теги
message = message.replaceAll("§0", "<black>");
message = message.replaceAll("§1", "<dark_blue>");
@ -84,7 +85,7 @@ public final class ChatFormatter {
message = message.replaceAll("§n", "<underlined>");
message = message.replaceAll("§o", "<italic>");
message = message.replaceAll("§r", "<reset>");
// Конвертируем &[0-9a-fk-or] в соответствующие MiniMessage теги
message = message.replaceAll("&0", "<black>");
message = message.replaceAll("&1", "<dark_blue>");
@ -102,7 +103,7 @@ public final class ChatFormatter {
message = message.replaceAll("&d", "<light_purple>");
message = message.replaceAll("&e", "<yellow>");
message = message.replaceAll("&f", "<white>");
// Конвертируем форматирование
message = message.replaceAll("&k", "<obfuscated>");
message = message.replaceAll("&l", "<bold>");
@ -110,7 +111,7 @@ public final class ChatFormatter {
message = message.replaceAll("&n", "<underlined>");
message = message.replaceAll("&o", "<italic>");
message = message.replaceAll("&r", "<reset>");
return message;
}
@ -122,7 +123,7 @@ public final class ChatFormatter {
public static String toPlain(Component component) {
return component == null ? "" : PLAIN.serialize(component);
}
public static String toPlain(Object obj) {
if (obj == null) return "";
if (obj instanceof Component component) {
@ -130,7 +131,7 @@ public final class ChatFormatter {
}
return obj.toString();
}
/**
* Отправляет сообщение игроку
*/
@ -190,7 +191,7 @@ public final class ChatFormatter {
// Получаем отображаемые имена игроков
String senderDisplay = getPlayerDisplayName(sender);
String receiverDisplay = getPlayerDisplayName(receiver);
return parse(format
.replace("{sender}", sender.getName())
.replace("{receiver}", receiver.getName())
@ -208,7 +209,7 @@ public final class ChatFormatter {
// Получаем отображаемые имена игроков
String senderDisplay = getPlayerDisplayName(sender);
String receiverDisplay = getPlayerDisplayName(receiver);
return parse(format
.replace("{sender}", sender.getName())
.replace("{receiver}", receiver.getName())
@ -223,12 +224,12 @@ public final class ChatFormatter {
private static String getPlayerDisplayName(Player player) {
// Получаем экземпляр плагина
com.loki.lochat.LoChat plugin = com.loki.lochat.LoChat.getInstance();
// Если градиентный модуль включен, используем его
if (plugin.getGradientModule() != null && plugin.getGradientModule().isEnabled()) {
return plugin.getGradientModule().getFormattedName(player);
}
// Иначе просто имя игрока
return player.getName();
}

View file

@ -5,27 +5,24 @@ package com.loki.lochat.utils;
*/
public final class Constants {
private Constants() {}
// Чат
public static final int DEFAULT_LOCAL_RADIUS = 100;
public static final int CLEAR_CHAT_LINES = 100;
// Время
public static final long MILLIS_IN_SECOND = 1000L;
public static final int SECONDS_IN_MINUTE = 60;
public static final int MINUTES_IN_HOUR = 60;
public static final int HOURS_IN_DAY = 24;
// Градиенты
public static final int DEFAULT_PRICE_PER_COLOR = 50;
public static final int DEFAULT_PREFIX_PRICE = 500;
public static final int LUCKPERMS_PREFIX_PRIORITY = 100;
// Folia/Paper совместимость
public static final int TICKS_PER_SECOND = 20;
public static final int MILLIS_PER_TICK = 50;
// Анти-спам
public static final int PERCENTAGE_MULTIPLIER = 100;
private Constants() {
}
}

View file

@ -5,22 +5,23 @@ import org.bukkit.entity.Player;
public class DistanceUtil {
private DistanceUtil() {}
private DistanceUtil() {
}
public static boolean isInRange(Player player1, Player player2, int radius) {
// Проверка на один мир
if (!player1.getWorld().equals(player2.getWorld())) {
return false;
}
Location loc1 = player1.getLocation();
Location loc2 = player2.getLocation();
// Быстрая проверка по квадрату (без sqrt)
double dx = loc1.getX() - loc2.getX();
double dz = loc1.getZ() - loc2.getZ();
double radiusSquared = (double) radius * radius;
return (dx * dx + dz * dz) <= radiusSquared;
}

View file

@ -16,22 +16,22 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MentionHandler {
private static final Pattern EVERYONE_PATTERN = Pattern.compile("@everyone\\b");
private static final Pattern HERE_PATTERN = Pattern.compile("@here\\b");
private static final Pattern ROLE_PATTERN = Pattern.compile("@role:([\\w.]+)");
private static final Pattern PLAYER_PATTERN = Pattern.compile("@(\\w+)");
private final JavaPlugin plugin;
public MentionHandler(JavaPlugin plugin) {
this.plugin = plugin;
}
public Component processMentions(Component message, Player sender, Player viewer) {
String plainText = PlainTextComponentSerializer.plainText().serialize(message);
List<Player> mentionedPlayers = new ArrayList<>();
if (sender.hasPermission("lochat.mention.everyone")) {
Matcher everyoneMatcher = EVERYONE_PATTERN.matcher(plainText);
if (everyoneMatcher.find()) {
@ -39,7 +39,7 @@ public class MentionHandler {
message = highlightMention(message, "@everyone");
}
}
if (sender.hasPermission("lochat.mention.here")) {
Matcher hereMatcher = HERE_PATTERN.matcher(plainText);
if (hereMatcher.find()) {
@ -47,57 +47,57 @@ public class MentionHandler {
message = highlightMention(message, "@here");
}
}
if (sender.hasPermission("lochat.mention.role")) {
Matcher roleMatcher = ROLE_PATTERN.matcher(plainText);
while (roleMatcher.find()) {
String permission = roleMatcher.group(1);
String fullMention = "@role:" + permission;
for (Player player : Bukkit.getOnlinePlayers()) {
if (player.hasPermission(permission)) {
mentionedPlayers.add(player);
}
}
message = highlightMention(message, fullMention);
}
}
Matcher playerMatcher = PLAYER_PATTERN.matcher(plainText);
while (playerMatcher.find()) {
String playerName = playerMatcher.group(1);
Player mentioned = Bukkit.getPlayerExact(playerName);
if (mentioned != null && mentioned.isOnline()) {
mentionedPlayers.add(mentioned);
message = highlightMention(message, "@" + playerName);
}
}
if (mentionedPlayers.contains(viewer)) {
playMentionSound(viewer);
message = highlightForViewer(message, viewer);
}
return message;
}
private Component highlightMention(Component message, String mention) {
return message.replaceText(builder ->
builder.matchLiteral(mention)
.replacement(Component.text(mention, NamedTextColor.YELLOW, TextDecoration.BOLD))
return message.replaceText(builder ->
builder.matchLiteral(mention)
.replacement(Component.text(mention, NamedTextColor.YELLOW, TextDecoration.BOLD))
);
}
private Component highlightForViewer(Component message, Player viewer) {
String viewerMention = "@" + viewer.getName();
return message.replaceText(builder ->
builder.matchLiteral(viewerMention)
.replacement(Component.text(viewerMention, NamedTextColor.GOLD, TextDecoration.BOLD))
return message.replaceText(builder ->
builder.matchLiteral(viewerMention)
.replacement(Component.text(viewerMention, NamedTextColor.GOLD, TextDecoration.BOLD))
);
}
private void playMentionSound(Player player) {
FoliaUtil.runEntityTask(plugin, player, () -> {
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1.0f, 1.5f);

View file

@ -2,6 +2,7 @@ package com.loki.lochat.utils;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import java.util.UUID;
@ -11,10 +12,32 @@ import java.util.UUID;
*/
public final class PlayerUtil {
private PlayerUtil() {}
private PlayerUtil() {
}
/**
* Safely parses a sound name from config.
* Uses deprecated Sound.valueOf() for backward compatibility with string-based config values.
*
* @param soundName the sound name to parse
* @param defaultSound the default sound to return if parsing fails
* @return the parsed Sound or the default if invalid
*/
@SuppressWarnings("deprecation")
public static Sound parseSound(String soundName, Sound defaultSound) {
if (soundName == null || soundName.isEmpty()) {
return defaultSound;
}
try {
return Sound.valueOf(soundName.toUpperCase());
} catch (IllegalArgumentException e) {
return defaultSound;
}
}
/**
* Находит игрока по имени (онлайн или оффлайн)
*
* @param name имя игрока
* @return UUID игрока или null если не найден
*/
@ -36,6 +59,7 @@ public final class PlayerUtil {
/**
* Проверяет, существует ли игрок (играл на сервере)
*
* @param name имя игрока
* @return true если игрок существует
*/
@ -45,6 +69,7 @@ public final class PlayerUtil {
/**
* Получает имя игрока по UUID
*
* @param uuid UUID игрока
* @return имя игрока или null
*/
@ -60,6 +85,7 @@ public final class PlayerUtil {
/**
* Проверяет, онлайн ли игрок
*
* @param uuid UUID игрока
* @return true если игрок онлайн
*/

View file

@ -7,42 +7,42 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TextFormatter {
private static final Pattern BOLD_PATTERN = Pattern.compile("\\*\\*(.+?)\\*\\*");
private static final Pattern ITALIC_PATTERN = Pattern.compile("\\*(.+?)\\*");
private static final Pattern UNDERLINE_PATTERN = Pattern.compile("__(.+?)__");
private static final Pattern STRIKETHROUGH_PATTERN = Pattern.compile("~~(.+?)~~");
private static final Pattern CODE_PATTERN = Pattern.compile("`(.+?)`");
public static Component formatMarkdown(Component message) {
String text = PlainTextComponentSerializer.plainText().serialize(message);
text = formatBold(text);
text = formatItalic(text);
text = formatUnderline(text);
text = formatStrikethrough(text);
text = formatCode(text);
return ChatFormatter.parse(text);
}
private static String formatBold(String text) {
Matcher matcher = BOLD_PATTERN.matcher(text);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
String content = matcher.group(1);
matcher.appendReplacement(result, "<bold>" + content + "</bold>");
}
matcher.appendTail(result);
return result.toString();
}
private static String formatItalic(String text) {
Matcher matcher = ITALIC_PATTERN.matcher(text);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
String content = matcher.group(1);
if (!content.startsWith("*") && !content.endsWith("*")) {
@ -50,46 +50,46 @@ public class TextFormatter {
}
}
matcher.appendTail(result);
return result.toString();
}
private static String formatUnderline(String text) {
Matcher matcher = UNDERLINE_PATTERN.matcher(text);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
String content = matcher.group(1);
matcher.appendReplacement(result, "<underlined>" + content + "</underlined>");
}
matcher.appendTail(result);
return result.toString();
}
private static String formatStrikethrough(String text) {
Matcher matcher = STRIKETHROUGH_PATTERN.matcher(text);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
String content = matcher.group(1);
matcher.appendReplacement(result, "<strikethrough>" + content + "</strikethrough>");
}
matcher.appendTail(result);
return result.toString();
}
private static String formatCode(String text) {
Matcher matcher = CODE_PATTERN.matcher(text);
StringBuffer result = new StringBuffer();
while (matcher.find()) {
String content = matcher.group(1);
matcher.appendReplacement(result, "&#888888`" + content + "`");
}
matcher.appendTail(result);
return result.toString();
}
}