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:
parent
6a4c8a7886
commit
e78d8a2de4
121 changed files with 1792 additions and 1301 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 если игрок онлайн
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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, "󙀸`" + content + "`");
|
||||
}
|
||||
matcher.appendTail(result);
|
||||
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue