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
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -20,3 +20,6 @@ Thumbs.db
|
|||
|
||||
# Local config
|
||||
local.properties
|
||||
|
||||
# Temp folders
|
||||
temp_*/
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
plugins {
|
||||
java
|
||||
checkstyle
|
||||
}
|
||||
|
||||
group = "com.loki"
|
||||
version = "1.5.5-1.20.1"
|
||||
version = "1.5.5-1.21.8"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
|
|
@ -15,7 +16,7 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT")
|
||||
compileOnly("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
|
||||
compileOnly("me.clip:placeholderapi:2.11.6")
|
||||
compileOnly("org.black_ixx:playerpoints:3.2.7")
|
||||
compileOnly("net.luckperms:api:5.4")
|
||||
|
|
@ -24,7 +25,7 @@ dependencies {
|
|||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.10.0")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter-engine:5.10.0")
|
||||
testImplementation("org.mockito:mockito-core:5.11.0")
|
||||
testImplementation("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT")
|
||||
testImplementation("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
|
||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.10.0")
|
||||
}
|
||||
|
||||
|
|
@ -48,7 +49,21 @@ tasks.test {
|
|||
}
|
||||
|
||||
tasks.jar {
|
||||
archiveFileName.set("LoChat-1.5.5-1.20.1.jar")
|
||||
archiveFileName.set("LoChat-1.5.5-1.21.8.jar")
|
||||
from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) })
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "10.12.5"
|
||||
configFile = file("${rootDir}/config/checkstyle/checkstyle.xml")
|
||||
isIgnoreFailures = true
|
||||
maxWarnings = 999
|
||||
}
|
||||
|
||||
tasks.withType<Checkstyle> {
|
||||
reports {
|
||||
xml.required.set(false)
|
||||
html.required.set(true)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
83
config/checkstyle/README.md
Normal file
83
config/checkstyle/README.md
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# Checkstyle Configuration
|
||||
|
||||
Автоматическая проверка качества кода во время билда.
|
||||
|
||||
## Правила
|
||||
|
||||
### Размеры
|
||||
- **Файл**: максимум 150 строк
|
||||
- **Метод**: максимум 30 строк
|
||||
- **Строка**: максимум 120 символов
|
||||
- **Параметры**: максимум 5 параметров
|
||||
|
||||
### Сложность
|
||||
- **Cyclomatic Complexity**: максимум 10
|
||||
- **Вложенность if**: максимум 3 уровня
|
||||
- **Вложенность try**: максимум 2 уровня
|
||||
|
||||
### Качество кода
|
||||
- Нет дублирования строк (макс 2 повтора)
|
||||
- Нет магических чисел (кроме -1, 0, 1, 2, 3, 4, 5, 10, 20, 100)
|
||||
- Нет * импортов
|
||||
- Нет неиспользуемых импортов
|
||||
- Упрощение boolean выражений
|
||||
- equals() и hashCode() вместе
|
||||
|
||||
### Форматирование
|
||||
- Отступы: 4 пробела
|
||||
- Скобки обязательны для if/for/while
|
||||
- Один оператор на строку
|
||||
- Пробелы вокруг операторов
|
||||
|
||||
## Запуск проверки
|
||||
|
||||
```bash
|
||||
# Проверить весь проект
|
||||
./gradlew check
|
||||
|
||||
# Проверить только LoChat
|
||||
./gradlew checkstyleMain
|
||||
|
||||
# Проверить только LoHub
|
||||
./gradlew :lohub:checkstyleMain
|
||||
|
||||
# Проверить только LoVelocity
|
||||
./gradlew :lovelocity:checkstyleMain
|
||||
```
|
||||
|
||||
## Отчеты
|
||||
|
||||
После проверки отчеты доступны в:
|
||||
- `build/reports/checkstyle/main.html`
|
||||
- `lohub/build/reports/checkstyle/main.html`
|
||||
- `lovelocity/build/reports/checkstyle/main.html`
|
||||
|
||||
## Отключение проверки
|
||||
|
||||
Если нужно временно отключить проверку для конкретного файла:
|
||||
|
||||
```java
|
||||
// CHECKSTYLE:OFF
|
||||
public class MyClass {
|
||||
// код без проверки
|
||||
}
|
||||
// CHECKSTYLE:ON
|
||||
```
|
||||
|
||||
Или для конкретной строки:
|
||||
|
||||
```java
|
||||
private static final int MAGIC = 42; // CHECKSTYLE IGNORE MagicNumber
|
||||
```
|
||||
|
||||
## Интеграция с IDE
|
||||
|
||||
### IntelliJ IDEA
|
||||
1. Установить плагин "CheckStyle-IDEA"
|
||||
2. Settings → Tools → Checkstyle
|
||||
3. Добавить конфиг: `config/checkstyle/checkstyle.xml`
|
||||
4. Активировать проверку в реальном времени
|
||||
|
||||
### VS Code
|
||||
1. Установить расширение "Checkstyle for Java"
|
||||
2. Настроить путь к конфигу в settings.json
|
||||
73
config/checkstyle/checkstyle.xml
Normal file
73
config/checkstyle/checkstyle.xml
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||
|
||||
<module name="Checker">
|
||||
<property name="charset" value="UTF-8"/>
|
||||
<property name="severity" value="warning"/>
|
||||
<property name="fileExtensions" value="java"/>
|
||||
|
||||
<module name="FileLength">
|
||||
<property name="max" value="600"/>
|
||||
</module>
|
||||
|
||||
<module name="LineLength">
|
||||
<property name="max" value="140"/>
|
||||
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
|
||||
<module name="MethodLength">
|
||||
<property name="max" value="60"/>
|
||||
<property name="countEmpty" value="false"/>
|
||||
</module>
|
||||
|
||||
<module name="CyclomaticComplexity">
|
||||
<property name="max" value="15"/>
|
||||
</module>
|
||||
|
||||
<module name="ParameterNumber">
|
||||
<property name="max" value="7"/>
|
||||
</module>
|
||||
|
||||
<module name="NestedIfDepth">
|
||||
<property name="max" value="3"/>
|
||||
</module>
|
||||
|
||||
<module name="NestedTryDepth">
|
||||
<property name="max" value="2"/>
|
||||
</module>
|
||||
|
||||
|
||||
<module name="AvoidStarImport"/> <module name="UnusedImports"/>
|
||||
<module name="RedundantImport"/>
|
||||
|
||||
|
||||
<module name="PackageName">
|
||||
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
|
||||
</module>
|
||||
<module name="TypeName"/>
|
||||
<module name="MethodName"/>
|
||||
<module name="MemberName"/> <module name="ParameterName"/>
|
||||
<module name="LocalVariableName"/>
|
||||
<module name="ConstantName"/>
|
||||
|
||||
|
||||
<module name="NeedBraces"/>
|
||||
<module name="LeftCurly"/>
|
||||
<module name="RightCurly"/>
|
||||
|
||||
<module name="WhitespaceAround">
|
||||
<property name="allowEmptyConstructors" value="true"/>
|
||||
<property name="allowEmptyMethods" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="ModifierOrder"/> <module name="EmptyStatement"/>
|
||||
<module name="EqualsHashCode"/> <module name="SimplifyBooleanExpression"/>
|
||||
<module name="SimplifyBooleanReturn"/>
|
||||
<module name="StringLiteralEquality"/> <module name="DefaultComesLast"/> <module name="MultipleVariableDeclarations"/> <module name="FallThrough"/> <module name="HideUtilityClassConstructor"/>
|
||||
|
||||
</module>
|
||||
</module>
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
plugins {
|
||||
java
|
||||
checkstyle
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
|
@ -10,7 +11,7 @@ repositories {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("io.papermc.paper:paper-api:1.20.1-R0.1-SNAPSHOT")
|
||||
compileOnly("io.papermc.paper:paper-api:1.21.4-R0.1-SNAPSHOT")
|
||||
compileOnly("me.clip:placeholderapi:2.11.6")
|
||||
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.0.9")
|
||||
implementation("com.google.code.gson:gson:2.10.1")
|
||||
|
|
@ -21,8 +22,28 @@ dependencies {
|
|||
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.10.0")
|
||||
}
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
}
|
||||
|
||||
tasks.jar {
|
||||
archiveFileName.set("LoHub-1.5.5-1.20.1.jar")
|
||||
archiveFileName.set("LoHub-1.5.5-1.21.8.jar")
|
||||
from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) })
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "10.12.5"
|
||||
configFile = file("${rootProject.rootDir}/config/checkstyle/checkstyle.xml")
|
||||
isIgnoreFailures = false
|
||||
maxWarnings = 0
|
||||
}
|
||||
|
||||
tasks.withType<Checkstyle> {
|
||||
reports {
|
||||
xml.required.set(false)
|
||||
html.required.set(true)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,10 +29,14 @@ public class HubProtectionListener implements Listener {
|
|||
|
||||
@EventHandler
|
||||
public void onBlockBreak(BlockBreakEvent event) {
|
||||
if (!plugin.getConfigManager().isProtectionEnabled()) return;
|
||||
if (!plugin.getConfigManager().isProtectionEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (player.hasPermission("lohub.bypass.protection")) return;
|
||||
if (player.hasPermission("lohub.bypass.protection")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getConfigManager().isBlockBreakProtected()) {
|
||||
event.setCancelled(true);
|
||||
|
|
@ -41,10 +45,14 @@ public class HubProtectionListener implements Listener {
|
|||
|
||||
@EventHandler
|
||||
public void onBlockPlace(BlockPlaceEvent event) {
|
||||
if (!plugin.getConfigManager().isProtectionEnabled()) return;
|
||||
if (!plugin.getConfigManager().isProtectionEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (player.hasPermission("lohub.bypass.protection")) return;
|
||||
if (player.hasPermission("lohub.bypass.protection")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getConfigManager().isBlockPlaceProtected()) {
|
||||
event.setCancelled(true);
|
||||
|
|
@ -53,12 +61,20 @@ public class HubProtectionListener implements Listener {
|
|||
|
||||
@EventHandler
|
||||
public void onPvP(EntityDamageByEntityEvent event) {
|
||||
if (!plugin.getConfigManager().isProtectionEnabled()) return;
|
||||
if (!(event.getDamager() instanceof Player)) return;
|
||||
if (!(event.getEntity() instanceof Player)) return;
|
||||
if (!plugin.getConfigManager().isProtectionEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (!(event.getDamager() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
if (!(event.getEntity() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player damager = (Player) event.getDamager();
|
||||
if (damager.hasPermission("lohub.bypass.protection")) return;
|
||||
if (damager.hasPermission("lohub.bypass.protection")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getConfigManager().isPvPProtected()) {
|
||||
event.setCancelled(true);
|
||||
|
|
@ -67,10 +83,14 @@ public class HubProtectionListener implements Listener {
|
|||
|
||||
@EventHandler
|
||||
public void onItemDrop(PlayerDropItemEvent event) {
|
||||
if (!plugin.getConfigManager().isProtectionEnabled()) return;
|
||||
if (!plugin.getConfigManager().isProtectionEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (player.hasPermission("lohub.bypass.protection")) return;
|
||||
if (player.hasPermission("lohub.bypass.protection")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getConfigManager().isItemDropProtected()) {
|
||||
event.setCancelled(true);
|
||||
|
|
@ -79,10 +99,14 @@ public class HubProtectionListener implements Listener {
|
|||
|
||||
@EventHandler
|
||||
public void onItemPickup(PlayerPickupItemEvent event) {
|
||||
if (!plugin.getConfigManager().isProtectionEnabled()) return;
|
||||
if (!plugin.getConfigManager().isProtectionEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (player.hasPermission("lohub.bypass.protection")) return;
|
||||
if (player.hasPermission("lohub.bypass.protection")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getConfigManager().isItemPickupProtected()) {
|
||||
event.setCancelled(true);
|
||||
|
|
@ -91,11 +115,17 @@ public class HubProtectionListener implements Listener {
|
|||
|
||||
@EventHandler
|
||||
public void onFoodLevelChange(FoodLevelChangeEvent event) {
|
||||
if (!plugin.getConfigManager().isProtectionEnabled()) return;
|
||||
if (!(event.getEntity() instanceof Player)) return;
|
||||
if (!plugin.getConfigManager().isProtectionEnabled()) {
|
||||
return;
|
||||
}
|
||||
if (!(event.getEntity() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = (Player) event.getEntity();
|
||||
if (player.hasPermission("lohub.bypass.protection")) return;
|
||||
if (player.hasPermission("lohub.bypass.protection")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getConfigManager().isFoodLevelProtected()) {
|
||||
event.setCancelled(true);
|
||||
|
|
|
|||
|
|
@ -20,9 +20,33 @@ import org.bukkit.inventory.meta.FireworkMeta;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class PlayerJoinListener implements Listener {
|
||||
|
||||
private static final Map<String, Color> COLOR_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
COLOR_MAP.put("AQUA", Color.AQUA);
|
||||
COLOR_MAP.put("BLACK", Color.BLACK);
|
||||
COLOR_MAP.put("BLUE", Color.BLUE);
|
||||
COLOR_MAP.put("FUCHSIA", Color.FUCHSIA);
|
||||
COLOR_MAP.put("GRAY", Color.GRAY);
|
||||
COLOR_MAP.put("GREEN", Color.GREEN);
|
||||
COLOR_MAP.put("LIME", Color.LIME);
|
||||
COLOR_MAP.put("MAROON", Color.MAROON);
|
||||
COLOR_MAP.put("NAVY", Color.NAVY);
|
||||
COLOR_MAP.put("OLIVE", Color.OLIVE);
|
||||
COLOR_MAP.put("ORANGE", Color.ORANGE);
|
||||
COLOR_MAP.put("PURPLE", Color.PURPLE);
|
||||
COLOR_MAP.put("RED", Color.RED);
|
||||
COLOR_MAP.put("SILVER", Color.SILVER);
|
||||
COLOR_MAP.put("TEAL", Color.TEAL);
|
||||
COLOR_MAP.put("WHITE", Color.WHITE);
|
||||
COLOR_MAP.put("YELLOW", Color.YELLOW);
|
||||
}
|
||||
|
||||
private final LoHub plugin;
|
||||
|
||||
public PlayerJoinListener(LoHub plugin) {
|
||||
|
|
@ -140,7 +164,7 @@ public class PlayerJoinListener implements Listener {
|
|||
}
|
||||
|
||||
Location loc = player.getLocation();
|
||||
Firework firework = (Firework) loc.getWorld().spawnEntity(loc, EntityType.FIREWORK);
|
||||
Firework firework = (Firework) loc.getWorld().spawnEntity(loc, EntityType.FIREWORK_ROCKET);
|
||||
FireworkMeta meta = firework.getFireworkMeta();
|
||||
|
||||
String typeStr = plugin.getConfig().getString("join_settings.firework.type", "BALL_LARGE");
|
||||
|
|
@ -176,26 +200,7 @@ public class PlayerJoinListener implements Listener {
|
|||
}
|
||||
|
||||
private Color parseColor(String colorStr) {
|
||||
return switch (colorStr.toUpperCase()) {
|
||||
case "AQUA" -> Color.AQUA;
|
||||
case "BLACK" -> Color.BLACK;
|
||||
case "BLUE" -> Color.BLUE;
|
||||
case "FUCHSIA" -> Color.FUCHSIA;
|
||||
case "GRAY" -> Color.GRAY;
|
||||
case "GREEN" -> Color.GREEN;
|
||||
case "LIME" -> Color.LIME;
|
||||
case "MAROON" -> Color.MAROON;
|
||||
case "NAVY" -> Color.NAVY;
|
||||
case "OLIVE" -> Color.OLIVE;
|
||||
case "ORANGE" -> Color.ORANGE;
|
||||
case "PURPLE" -> Color.PURPLE;
|
||||
case "RED" -> Color.RED;
|
||||
case "SILVER" -> Color.SILVER;
|
||||
case "TEAL" -> Color.TEAL;
|
||||
case "WHITE" -> Color.WHITE;
|
||||
case "YELLOW" -> Color.YELLOW;
|
||||
default -> null;
|
||||
};
|
||||
return COLOR_MAP.get(colorStr.toUpperCase());
|
||||
}
|
||||
|
||||
private boolean isWorldDisabled(String worldName) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,16 @@ package com.loki.lohub.managers;
|
|||
import com.loki.lohub.LoHub;
|
||||
import com.loki.lohub.actions.Action;
|
||||
import com.loki.lohub.actions.ActionType;
|
||||
import com.loki.lohub.actions.impl.*;
|
||||
import com.loki.lohub.actions.impl.ActionbarAction;
|
||||
import com.loki.lohub.actions.impl.BroadcastAction;
|
||||
import com.loki.lohub.actions.impl.CloseAction;
|
||||
import com.loki.lohub.actions.impl.CommandAction;
|
||||
import com.loki.lohub.actions.impl.ConsoleAction;
|
||||
import com.loki.lohub.actions.impl.EffectAction;
|
||||
import com.loki.lohub.actions.impl.GamemodeAction;
|
||||
import com.loki.lohub.actions.impl.MessageAction;
|
||||
import com.loki.lohub.actions.impl.SoundAction;
|
||||
import com.loki.lohub.actions.impl.TitleAction;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -13,8 +22,8 @@ import java.util.regex.Pattern;
|
|||
|
||||
public class ActionManager {
|
||||
|
||||
private final LoHub plugin;
|
||||
private static final Pattern ACTION_PATTERN = Pattern.compile("\\[([A-Z]+)]\\s*(.*)");
|
||||
private final LoHub plugin;
|
||||
|
||||
public ActionManager(LoHub plugin) {
|
||||
this.plugin = plugin;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import com.loki.lohub.LoHub;
|
|||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldguard.WorldGuard;
|
||||
import com.sk89q.worldguard.protection.flags.Flags;
|
||||
import com.sk89q.worldguard.protection.flags.StateFlag;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
|
||||
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||
import com.sk89q.worldguard.protection.regions.RegionContainer;
|
||||
|
|
@ -12,8 +14,8 @@ import org.bukkit.World;
|
|||
|
||||
public class RegionManager {
|
||||
|
||||
private final LoHub plugin;
|
||||
private static final String HUB_REGION_NAME = "lohub_spawn";
|
||||
private final LoHub plugin;
|
||||
|
||||
public RegionManager(LoHub plugin) {
|
||||
this.plugin = plugin;
|
||||
|
|
@ -67,23 +69,7 @@ public class RegionManager {
|
|||
);
|
||||
|
||||
ProtectedCuboidRegion region = new ProtectedCuboidRegion(HUB_REGION_NAME, min, max);
|
||||
|
||||
region.setFlag(com.sk89q.worldguard.protection.flags.Flags.PVP,
|
||||
com.sk89q.worldguard.protection.flags.StateFlag.State.DENY);
|
||||
region.setFlag(com.sk89q.worldguard.protection.flags.Flags.BLOCK_BREAK,
|
||||
com.sk89q.worldguard.protection.flags.StateFlag.State.DENY);
|
||||
region.setFlag(com.sk89q.worldguard.protection.flags.Flags.BLOCK_PLACE,
|
||||
com.sk89q.worldguard.protection.flags.StateFlag.State.DENY);
|
||||
region.setFlag(com.sk89q.worldguard.protection.flags.Flags.DAMAGE_ANIMALS,
|
||||
com.sk89q.worldguard.protection.flags.StateFlag.State.DENY);
|
||||
region.setFlag(com.sk89q.worldguard.protection.flags.Flags.MOB_SPAWNING,
|
||||
com.sk89q.worldguard.protection.flags.StateFlag.State.DENY);
|
||||
region.setFlag(com.sk89q.worldguard.protection.flags.Flags.LEAF_DECAY,
|
||||
com.sk89q.worldguard.protection.flags.StateFlag.State.DENY);
|
||||
region.setFlag(com.sk89q.worldguard.protection.flags.Flags.ITEM_DROP,
|
||||
com.sk89q.worldguard.protection.flags.StateFlag.State.DENY);
|
||||
region.setFlag(com.sk89q.worldguard.protection.flags.Flags.ITEM_PICKUP,
|
||||
com.sk89q.worldguard.protection.flags.StateFlag.State.DENY);
|
||||
setRegionFlags(region);
|
||||
|
||||
wgRegionManager.addRegion(region);
|
||||
|
||||
|
|
@ -96,6 +82,17 @@ public class RegionManager {
|
|||
}
|
||||
}
|
||||
|
||||
private void setRegionFlags(ProtectedCuboidRegion region) {
|
||||
region.setFlag(Flags.PVP, StateFlag.State.DENY);
|
||||
region.setFlag(Flags.BLOCK_BREAK, StateFlag.State.DENY);
|
||||
region.setFlag(Flags.BLOCK_PLACE, StateFlag.State.DENY);
|
||||
region.setFlag(Flags.DAMAGE_ANIMALS, StateFlag.State.DENY);
|
||||
region.setFlag(Flags.MOB_SPAWNING, StateFlag.State.DENY);
|
||||
region.setFlag(Flags.LEAF_DECAY, StateFlag.State.DENY);
|
||||
region.setFlag(Flags.ITEM_DROP, StateFlag.State.DENY);
|
||||
region.setFlag(Flags.ITEM_PICKUP, StateFlag.State.DENY);
|
||||
}
|
||||
|
||||
public void deleteHubRegion() {
|
||||
if (!isWorldGuardAvailable()) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,10 @@ public class SpawnManager {
|
|||
}
|
||||
}
|
||||
|
||||
public Location getSpawn() {
|
||||
return spawnLocation;
|
||||
}
|
||||
|
||||
public void setSpawn(Location location) {
|
||||
this.spawnLocation = location;
|
||||
|
||||
|
|
@ -72,10 +76,6 @@ public class SpawnManager {
|
|||
}
|
||||
}
|
||||
|
||||
public Location getSpawn() {
|
||||
return spawnLocation;
|
||||
}
|
||||
|
||||
public void teleportToSpawn(Player player) {
|
||||
if (spawnLocation == null) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import org.bukkit.inventory.ItemStack;
|
|||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.inventory.meta.SkullMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
|
@ -69,7 +68,8 @@ public class ItemBuilder {
|
|||
section.getStringList("item_flags").forEach(flagName -> {
|
||||
try {
|
||||
builder.flag(ItemFlag.valueOf(flagName.toUpperCase()));
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ public class ItemBuilder {
|
|||
public ItemBuilder glow() {
|
||||
ItemMeta meta = itemStack.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.addEnchant(Enchantment.LUCK, 1, true);
|
||||
meta.addEnchant(Enchantment.UNBREAKING, 1, true);
|
||||
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
|
||||
itemStack.setItemMeta(meta);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ public class PlaceholderUtil {
|
|||
|
||||
private static boolean placeholderAPIEnabled = false;
|
||||
|
||||
private PlaceholderUtil() {
|
||||
// Utility class - prevent instantiation
|
||||
}
|
||||
|
||||
public static void init() {
|
||||
placeholderAPIEnabled = Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ public class TextUtil {
|
|||
|
||||
private static final Pattern HEX_PATTERN = Pattern.compile("&#([A-Fa-f0-9]{6})");
|
||||
|
||||
private TextUtil() {
|
||||
// Utility class - prevent instantiation
|
||||
}
|
||||
|
||||
public static String colorize(String text) {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return text;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
plugins {
|
||||
java
|
||||
checkstyle
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
|
@ -23,3 +24,17 @@ tasks.jar {
|
|||
from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) })
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = "10.12.5"
|
||||
configFile = file("${rootProject.rootDir}/config/checkstyle/checkstyle.xml")
|
||||
isIgnoreFailures = false
|
||||
maxWarnings = 0
|
||||
}
|
||||
|
||||
tasks.withType<Checkstyle> {
|
||||
reports {
|
||||
xml.required.set(false)
|
||||
html.required.set(true)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,11 @@ public final class LoChat extends JavaPlugin {
|
|||
private AutoMessageManager autoMessageManager;
|
||||
private CustomCommandManager customCommandManager;
|
||||
|
||||
// Геттеры
|
||||
public static LoChat getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
instance = this;
|
||||
|
|
@ -41,11 +46,11 @@ public final class LoChat extends JavaPlugin {
|
|||
messageConfig = new MessageConfig(this);
|
||||
|
||||
// Service Registry (SOLID DI) - с зависимостями
|
||||
serviceRegistry = new ServiceRegistry(this, configManager, messageConfig);
|
||||
serviceRegistry = ServiceRegistry.createWithDeps(this, configManager, messageConfig);
|
||||
getLogger().info("ServiceRegistry инициализирован (SOLID DI)");
|
||||
|
||||
// Менеджеры
|
||||
customCommandManager = new CustomCommandManager(this);
|
||||
customCommandManager = CustomCommandManager.create(this);
|
||||
autoMessageManager = new AutoMessageManager(this);
|
||||
|
||||
// Интеграции
|
||||
|
|
@ -152,11 +157,23 @@ public final class LoChat extends JavaPlugin {
|
|||
if (customCommandManager != null) customCommandManager.reload();
|
||||
}
|
||||
|
||||
// Геттеры
|
||||
public static LoChat getInstance() { return instance; }
|
||||
public ServiceRegistry getServiceRegistry() { return serviceRegistry; }
|
||||
public ConfigManager getConfigManager() { return configManager; }
|
||||
public MessageConfig getMessageConfig() { return messageConfig; }
|
||||
public GradientModule getGradientModule() { return gradientModule; }
|
||||
public CustomCommandManager getCustomCommandManager() { return customCommandManager; }
|
||||
public ServiceRegistry getServiceRegistry() {
|
||||
return serviceRegistry;
|
||||
}
|
||||
|
||||
public ConfigManager getConfigManager() {
|
||||
return configManager;
|
||||
}
|
||||
|
||||
public MessageConfig getMessageConfig() {
|
||||
return messageConfig;
|
||||
}
|
||||
|
||||
public GradientModule getGradientModule() {
|
||||
return gradientModule;
|
||||
}
|
||||
|
||||
public CustomCommandManager getCustomCommandManager() {
|
||||
return customCommandManager;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@ import org.bukkit.entity.Player;
|
|||
*/
|
||||
public interface ChatService {
|
||||
void sendGlobalMessage(Player sender, Object message);
|
||||
|
||||
void sendLocalMessage(Player sender, Object message);
|
||||
|
||||
boolean toggleGlobalChat(java.util.UUID player);
|
||||
|
||||
boolean isGlobalChatDisabled(java.util.UUID player);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@ import java.util.UUID;
|
|||
*/
|
||||
public interface CooldownService {
|
||||
boolean isOnCooldown(UUID player, String type, int cooldownSeconds);
|
||||
|
||||
int getRemainingCooldown(UUID player, String type, int cooldownSeconds);
|
||||
|
||||
void setCooldown(UUID player, String type);
|
||||
|
||||
void removeCooldown(UUID player);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import org.bukkit.entity.Player;
|
|||
public interface MessageFilter {
|
||||
/**
|
||||
* Применить фильтр к сообщению
|
||||
*
|
||||
* @return отфильтрованное сообщение или null если заблокировано
|
||||
*/
|
||||
Object apply(Player player, Object message, String plainMessage);
|
||||
|
|
|
|||
|
|
@ -7,9 +7,14 @@ import java.util.UUID;
|
|||
*/
|
||||
public interface MuteService {
|
||||
void mute(UUID uuid, String playerName, long duration, String reason, String mutedBy);
|
||||
|
||||
boolean unmute(UUID uuid, String unmutedBy);
|
||||
|
||||
boolean isMuted(UUID uuid);
|
||||
|
||||
long getRemainingTime(UUID uuid);
|
||||
|
||||
String formatTime(long millis);
|
||||
|
||||
long parseTime(String timeStr);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import org.bukkit.entity.Player;
|
|||
public interface MessageFilter {
|
||||
/**
|
||||
* Применить фильтр к сообщению
|
||||
*
|
||||
* @return true если сообщение прошло фильтр, false если заблокировано
|
||||
*/
|
||||
boolean apply(Player player, ChatMessage message);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,10 @@ import java.util.UUID;
|
|||
*/
|
||||
public interface ChatService {
|
||||
void sendGlobalMessage(Player sender, Object message);
|
||||
|
||||
void sendLocalMessage(Player sender, Object message);
|
||||
|
||||
boolean toggleGlobalChat(UUID player);
|
||||
|
||||
boolean isGlobalChatDisabled(UUID player);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,10 @@ import java.util.UUID;
|
|||
*/
|
||||
public interface CooldownService {
|
||||
boolean isOnCooldown(UUID player, String type, int cooldownSeconds);
|
||||
|
||||
int getRemainingCooldown(UUID player, String type, int cooldownSeconds);
|
||||
|
||||
void setCooldown(UUID player, String type);
|
||||
|
||||
void removeCooldown(UUID player);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,12 +14,14 @@ public interface IgnoreService {
|
|||
|
||||
/**
|
||||
* Добавляет игрока в список игнорируемых
|
||||
*
|
||||
* @return true если успешно добавлен
|
||||
*/
|
||||
boolean addIgnore(UUID player, UUID target);
|
||||
|
||||
/**
|
||||
* Удаляет игрока из списка игнорируемых
|
||||
*
|
||||
* @return true если успешно удалён
|
||||
*/
|
||||
boolean removeIgnore(UUID player, UUID target);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import java.util.Set;
|
|||
public interface MentionService {
|
||||
/**
|
||||
* Обрабатывает упоминания в сообщении
|
||||
*
|
||||
* @return сообщение с подсвеченными никами
|
||||
*/
|
||||
String processMentions(String message, Set<Player> mentionedPlayers);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import org.bukkit.entity.Player;
|
|||
public interface MessageService {
|
||||
/**
|
||||
* Обработать входящее сообщение чата
|
||||
*
|
||||
* @return true если сообщение обработано успешно
|
||||
*/
|
||||
boolean processMessage(Player player, String message);
|
||||
|
|
|
|||
|
|
@ -13,22 +13,30 @@ import java.util.UUID;
|
|||
public interface MuteService {
|
||||
// Основные операции
|
||||
void mute(UUID uuid, String playerName, long duration, String reason, String mutedBy);
|
||||
|
||||
boolean unmute(UUID uuid, String unmutedBy);
|
||||
|
||||
boolean isMuted(UUID uuid);
|
||||
|
||||
MuteData getMuteData(UUID uuid);
|
||||
|
||||
long getRemainingTime(UUID uuid);
|
||||
|
||||
// Утилиты времени
|
||||
String formatTime(long millis);
|
||||
|
||||
long parseTime(String timeStr);
|
||||
|
||||
// Права доступа
|
||||
long getMaxDuration(Player player);
|
||||
|
||||
boolean canMuteForDuration(Player player, long duration);
|
||||
|
||||
// История
|
||||
List<MuteData.MuteHistoryEntry> getPlayerHistory(UUID uuid);
|
||||
|
||||
List<MuteData.MuteHistoryEntry> getMutesByOperator(String operatorName);
|
||||
|
||||
UUID getUUIDByName(String name);
|
||||
|
||||
// Список активных мутов
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ public interface NickService {
|
|||
|
||||
/**
|
||||
* Устанавливает кастомный ник игроку
|
||||
*
|
||||
* @param player UUID игрока
|
||||
* @param nickname Новый ник (с поддержкой цветов и русских символов)
|
||||
* @return true если успешно, false если ник занят или невалиден
|
||||
|
|
@ -20,12 +21,14 @@ public interface NickService {
|
|||
|
||||
/**
|
||||
* Сбрасывает кастомный ник игрока
|
||||
*
|
||||
* @param player UUID игрока
|
||||
*/
|
||||
void resetNickname(UUID player);
|
||||
|
||||
/**
|
||||
* Получает кастомный ник игрока
|
||||
*
|
||||
* @param player UUID игрока
|
||||
* @return Optional с ником или empty если нет кастомного ника
|
||||
*/
|
||||
|
|
@ -33,6 +36,7 @@ public interface NickService {
|
|||
|
||||
/**
|
||||
* Проверяет занят ли ник
|
||||
*
|
||||
* @param nickname Ник для проверки
|
||||
* @return true если ник уже используется
|
||||
*/
|
||||
|
|
@ -40,6 +44,7 @@ public interface NickService {
|
|||
|
||||
/**
|
||||
* Валидирует ник (длина, символы)
|
||||
*
|
||||
* @param nickname Ник для проверки
|
||||
* @return true если ник валиден
|
||||
*/
|
||||
|
|
@ -47,6 +52,7 @@ public interface NickService {
|
|||
|
||||
/**
|
||||
* Обновляет displayName и tabName игрока
|
||||
*
|
||||
* @param player Игрок
|
||||
*/
|
||||
void updatePlayerDisplay(Player player);
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@ import java.util.UUID;
|
|||
*/
|
||||
public interface PlayerDataService {
|
||||
void clearPlayerData(UUID player);
|
||||
|
||||
void saveAll();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import org.bukkit.entity.Player;
|
|||
public interface SpyService {
|
||||
/**
|
||||
* Переключает режим шпиона для игрока
|
||||
*
|
||||
* @return true если шпион включен, false если выключен
|
||||
*/
|
||||
boolean toggleSpy(java.util.UUID player);
|
||||
|
|
|
|||
|
|
@ -9,17 +9,13 @@ import org.jetbrains.annotations.NotNull;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CustomCommand extends Command {
|
||||
public final class CustomCommand extends Command {
|
||||
|
||||
private final CustomCommandManager manager;
|
||||
|
||||
public CustomCommand(String name, CustomCommandManager manager) {
|
||||
super(name);
|
||||
this.manager = manager;
|
||||
init(name);
|
||||
}
|
||||
|
||||
private void init(String name) {
|
||||
this.setDescription("Кастомная команда LoChat");
|
||||
this.setUsage("/" + name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@ import org.jetbrains.annotations.NotNull;
|
|||
*/
|
||||
public class GlobalChatCommand implements CommandExecutor {
|
||||
|
||||
private static final MiniMessage MM = MiniMessage.miniMessage();
|
||||
private final LoChat plugin;
|
||||
private final ChatService chatService;
|
||||
private static final MiniMessage MM = MiniMessage.miniMessage();
|
||||
|
||||
public GlobalChatCommand(LoChat plugin) {
|
||||
this.plugin = plugin;
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ import java.util.List;
|
|||
|
||||
public class LoChatCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
private final LoChat plugin;
|
||||
private static final MiniMessage MM = MiniMessage.miniMessage();
|
||||
private final LoChat plugin;
|
||||
|
||||
public LoChatCommand(LoChat plugin) {
|
||||
this.plugin = plugin;
|
||||
|
|
@ -51,14 +51,15 @@ public class LoChatCommand implements CommandExecutor, TabCompleter {
|
|||
var commands = plugin.getCustomCommandManager().getCommands();
|
||||
sender.sendMessage(MM.deserialize("&#FFD700Кастомные команды (" + commands.size() + "):"));
|
||||
for (var cmd : commands.values()) {
|
||||
sender.sendMessage(MM.deserialize("&e/" + cmd.name + " 󅒐(" + cmd.type + ")"));
|
||||
if (!cmd.aliases.isEmpty()) {
|
||||
sender.sendMessage(MM.deserialize("󅒐 Алиасы: " + String.join(", ", cmd.aliases)));
|
||||
sender.sendMessage(MM.deserialize("&e/" + cmd.name() + " 󅒐(" + cmd.type() + ")"));
|
||||
if (!cmd.aliases().isEmpty()) {
|
||||
sender.sendMessage(MM.deserialize("󅒐 Алиасы: " + String.join(", ", cmd.aliases())));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
default -> sender.sendMessage(MM.deserialize("&#FF0000Неизвестная команда. Используйте /lochat для помощи."));
|
||||
default ->
|
||||
sender.sendMessage(MM.deserialize("&#FF0000Неизвестная команда. Используйте /lochat для помощи."));
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ import org.jetbrains.annotations.NotNull;
|
|||
*/
|
||||
public class LocalChatCommand implements CommandExecutor {
|
||||
|
||||
private static final MiniMessage MM = MiniMessage.miniMessage();
|
||||
private final LoChat plugin;
|
||||
private final ChatService chatService;
|
||||
private static final MiniMessage MM = MiniMessage.miniMessage();
|
||||
|
||||
public LocalChatCommand(LoChat plugin) {
|
||||
this.plugin = plugin;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.loki.lochat.api.service.IgnoreService;
|
|||
import com.loki.lochat.api.service.PMService;
|
||||
import com.loki.lochat.api.service.SpyService;
|
||||
import com.loki.lochat.utils.ChatFormatter;
|
||||
import com.loki.lochat.utils.PlayerUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.command.Command;
|
||||
|
|
@ -89,10 +90,10 @@ public class MsgCommand implements CommandExecutor {
|
|||
|
||||
// Звук для получателя
|
||||
if (plugin.getConfigManager().isPmSoundEnabled()) {
|
||||
try {
|
||||
Sound sound = Sound.valueOf(plugin.getConfigManager().getPmSoundType());
|
||||
Sound sound = PlayerUtil.parseSound(plugin.getConfigManager().getPmSoundType(), null);
|
||||
if (sound != null) {
|
||||
target.playSound(target.getLocation(), sound, 1.0f, 1.0f);
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
// Шпион
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.loki.lochat.api.service.IgnoreService;
|
|||
import com.loki.lochat.api.service.PMService;
|
||||
import com.loki.lochat.api.service.SpyService;
|
||||
import com.loki.lochat.utils.ChatFormatter;
|
||||
import com.loki.lochat.utils.PlayerUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.command.Command;
|
||||
|
|
@ -88,10 +89,10 @@ public class ReplyCommand implements CommandExecutor {
|
|||
|
||||
// Звук для получателя
|
||||
if (plugin.getConfigManager().isPmSoundEnabled()) {
|
||||
try {
|
||||
Sound sound = Sound.valueOf(plugin.getConfigManager().getPmSoundType());
|
||||
Sound sound = PlayerUtil.parseSound(plugin.getConfigManager().getPmSoundType(), null);
|
||||
if (sound != null) {
|
||||
target.playSound(target.getLocation(), sound, 1.0f, 1.0f);
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
// Шпион
|
||||
|
|
|
|||
|
|
@ -35,18 +35,18 @@ public class AdvancedMessageFilter {
|
|||
public FilterResult filterMessage(Player player, String message) {
|
||||
if (config.getBoolean("filters.url.enabled", true)) {
|
||||
FilterResult urlResult = filterUrls(player, message);
|
||||
if (!urlResult.isAllowed()) {
|
||||
if (!urlResult.allowed()) {
|
||||
return urlResult;
|
||||
}
|
||||
message = urlResult.getFilteredMessage();
|
||||
message = urlResult.filteredMessage();
|
||||
}
|
||||
|
||||
if (config.getBoolean("filters.ip.enabled", true)) {
|
||||
FilterResult ipResult = filterIPs(player, message);
|
||||
if (!ipResult.isAllowed()) {
|
||||
if (!ipResult.allowed()) {
|
||||
return ipResult;
|
||||
}
|
||||
message = ipResult.getFilteredMessage();
|
||||
message = ipResult.filteredMessage();
|
||||
}
|
||||
|
||||
if (config.getBoolean("filters.repeat.enabled", true)) {
|
||||
|
|
@ -138,27 +138,6 @@ public class AdvancedMessageFilter {
|
|||
return url;
|
||||
}
|
||||
|
||||
public static class FilterResult {
|
||||
private final boolean allowed;
|
||||
private final String filteredMessage;
|
||||
private final String blockReason;
|
||||
|
||||
public FilterResult(boolean allowed, String filteredMessage, String blockReason) {
|
||||
this.allowed = allowed;
|
||||
this.filteredMessage = filteredMessage;
|
||||
this.blockReason = blockReason;
|
||||
}
|
||||
|
||||
public boolean isAllowed() {
|
||||
return allowed;
|
||||
}
|
||||
|
||||
public String getFilteredMessage() {
|
||||
return filteredMessage;
|
||||
}
|
||||
|
||||
public String getBlockReason() {
|
||||
return blockReason;
|
||||
}
|
||||
public record FilterResult(boolean allowed, String filteredMessage, String blockReason) {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,22 +13,20 @@ public class ServiceRegistry {
|
|||
private final Map<Class<?>, Object> services = new HashMap<>();
|
||||
private final JavaPlugin plugin;
|
||||
|
||||
public ServiceRegistry(JavaPlugin plugin) {
|
||||
private ServiceRegistry(JavaPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
init();
|
||||
}
|
||||
|
||||
public ServiceRegistry(JavaPlugin plugin, ConfigManager configManager, MessageConfig messageConfig) {
|
||||
this.plugin = plugin;
|
||||
initWithDeps(configManager, messageConfig);
|
||||
public static ServiceRegistry create(JavaPlugin plugin) {
|
||||
ServiceRegistry registry = new ServiceRegistry(plugin);
|
||||
registry.registerServices();
|
||||
return registry;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
registerServices();
|
||||
}
|
||||
|
||||
private void initWithDeps(ConfigManager configManager, MessageConfig messageConfig) {
|
||||
registerServicesWithDeps(configManager, messageConfig);
|
||||
public static ServiceRegistry createWithDeps(JavaPlugin plugin, ConfigManager configManager, MessageConfig messageConfig) {
|
||||
ServiceRegistry registry = new ServiceRegistry(plugin);
|
||||
registry.registerServicesWithDeps(configManager, messageConfig);
|
||||
return registry;
|
||||
}
|
||||
|
||||
private void registerServices() {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.loki.lochat.core.service;
|
|||
|
||||
import com.loki.lochat.api.service.IgnoreService;
|
||||
import com.loki.lochat.gradient.util.FoliaUtil;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
|
|
@ -9,8 +10,6 @@ import java.io.IOException;
|
|||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
/**
|
||||
* Реализация сервиса игнорирования
|
||||
*/
|
||||
|
|
@ -39,13 +38,15 @@ public class IgnoreServiceImpl implements IgnoreService {
|
|||
for (String ignoredStr : ignoredList) {
|
||||
try {
|
||||
ignored.add(UUID.fromString(ignoredStr));
|
||||
} catch (Exception ignored2) {}
|
||||
} catch (Exception ignored2) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!ignored.isEmpty()) {
|
||||
ignoreMap.put(uuid, ignored);
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.loki.lochat.core.service;
|
|||
|
||||
import com.loki.lochat.api.service.MentionService;
|
||||
import com.loki.lochat.config.ConfigManager;
|
||||
import com.loki.lochat.utils.PlayerUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.entity.Player;
|
||||
|
|
@ -17,9 +18,8 @@ import java.util.regex.Pattern;
|
|||
* Реализация сервиса упоминаний
|
||||
*/
|
||||
public class MentionServiceImpl implements MentionService {
|
||||
private final ConfigManager configManager;
|
||||
private static final Pattern MENTION_PATTERN = Pattern.compile("@(\\w+)");
|
||||
|
||||
private final ConfigManager configManager;
|
||||
// Хранит для какого игрока какие части сообщения выделить
|
||||
private final Map<Player, Set<String>> highlightedNicks = new HashMap<>();
|
||||
|
||||
|
|
@ -104,12 +104,7 @@ public class MentionServiceImpl implements MentionService {
|
|||
}
|
||||
|
||||
String soundName = configManager.getMentionSoundType();
|
||||
Sound sound;
|
||||
try {
|
||||
sound = Sound.valueOf(soundName);
|
||||
} catch (IllegalArgumentException e) {
|
||||
sound = Sound.BLOCK_NOTE_BLOCK_PLING;
|
||||
}
|
||||
Sound sound = PlayerUtil.parseSound(soundName, Sound.BLOCK_NOTE_BLOCK_PLING);
|
||||
|
||||
for (Player player : players) {
|
||||
player.playSound(player.getLocation(), sound, 1.0f, 1.0f);
|
||||
|
|
@ -123,10 +118,10 @@ public class MentionServiceImpl implements MentionService {
|
|||
|
||||
if (isPlayerMentioned(message, viewer)) {
|
||||
String soundName = configManager.getMentionSoundType();
|
||||
try {
|
||||
Sound sound = Sound.valueOf(soundName);
|
||||
Sound sound = PlayerUtil.parseSound(soundName, null);
|
||||
if (sound != null) {
|
||||
viewer.playSound(viewer.getLocation(), sound, 1.0f, 1.0f);
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
package com.loki.lochat.core.service;
|
||||
|
||||
import com.loki.lochat.api.filter.MessageFilter;
|
||||
import com.loki.lochat.api.service.*;
|
||||
import com.loki.lochat.api.service.ChatService;
|
||||
import com.loki.lochat.api.service.CooldownService;
|
||||
import com.loki.lochat.api.service.MessageService;
|
||||
import com.loki.lochat.api.service.MuteService;
|
||||
import com.loki.lochat.core.filter.CooldownFilter;
|
||||
import com.loki.lochat.core.filter.MuteFilter;
|
||||
import com.loki.lochat.core.registry.ServiceRegistry;
|
||||
import com.loki.lochat.data.model.ChatMessage;
|
||||
import com.loki.lochat.utils.ChatFormatter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
|
|
|
|||
|
|
@ -231,13 +231,15 @@ public class MuteServiceImpl implements MuteService {
|
|||
if (!dataFile.exists()) return;
|
||||
|
||||
try (Reader reader = new FileReader(dataFile)) {
|
||||
Type type = new TypeToken<Map<String, MuteData>>(){}.getType();
|
||||
Type type = new TypeToken<Map<String, MuteData>>() {
|
||||
}.getType();
|
||||
Map<String, MuteData> loaded = gson.fromJson(reader, type);
|
||||
if (loaded != null) {
|
||||
loaded.forEach((key, value) -> {
|
||||
try {
|
||||
mutes.put(UUID.fromString(key), value);
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
|
@ -249,13 +251,15 @@ public class MuteServiceImpl implements MuteService {
|
|||
if (!historyFile.exists()) return;
|
||||
|
||||
try (Reader reader = new FileReader(historyFile)) {
|
||||
Type type = new TypeToken<Map<String, List<MuteData.MuteHistoryEntry>>>(){}.getType();
|
||||
Type type = new TypeToken<Map<String, List<MuteData.MuteHistoryEntry>>>() {
|
||||
}.getType();
|
||||
Map<String, List<MuteData.MuteHistoryEntry>> loaded = gson.fromJson(reader, type);
|
||||
if (loaded != null) {
|
||||
loaded.forEach((key, value) -> {
|
||||
try {
|
||||
history.put(UUID.fromString(key), new ArrayList<>(value));
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
|
|
|||
|
|
@ -12,22 +12,23 @@ import org.bukkit.plugin.java.JavaPlugin;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Реализация сервиса кастомных ников
|
||||
*/
|
||||
public class NickServiceImpl implements NickService {
|
||||
// Настройки
|
||||
private static final int MIN_LENGTH = 3;
|
||||
private static final int MAX_LENGTH = 16;
|
||||
private final JavaPlugin plugin;
|
||||
private final Map<UUID, String> nicknames = new ConcurrentHashMap<>();
|
||||
private final File dataFile;
|
||||
private FileConfiguration data;
|
||||
|
||||
// Настройки
|
||||
private static final int MIN_LENGTH = 3;
|
||||
private static final int MAX_LENGTH = 16;
|
||||
|
||||
public NickServiceImpl(JavaPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.dataFile = new File(plugin.getDataFolder(), "nicknames.yml");
|
||||
|
|
@ -154,11 +155,7 @@ public class NickServiceImpl implements NickService {
|
|||
}
|
||||
|
||||
// Проверка символов (разрешены буквы, цифры, _, русские буквы)
|
||||
if (!cleanNick.matches("[a-zA-Zа-яА-Я0-9_]+")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return cleanNick.matches("[a-zA-Zа-яА-Я0-9_]+");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ import org.bukkit.entity.Player;
|
|||
*/
|
||||
public class ChatMessage {
|
||||
private final Player sender;
|
||||
private String content;
|
||||
private final boolean isGlobal;
|
||||
private final long timestamp;
|
||||
private String content;
|
||||
|
||||
private ChatMessage(Player sender, String content, boolean isGlobal) {
|
||||
this.sender = sender;
|
||||
|
|
@ -30,10 +30,27 @@ public class ChatMessage {
|
|||
return new ChatMessage(sender, content, isGlobal);
|
||||
}
|
||||
|
||||
public Player getSender() { return sender; }
|
||||
public String getContent() { return content; }
|
||||
public void setContent(String content) { this.content = content; }
|
||||
public boolean isGlobal() { return isGlobal; }
|
||||
public long getTimestamp() { return timestamp; }
|
||||
public String getChatType() { return isGlobal ? "global" : "local"; }
|
||||
public Player getSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return isGlobal;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public String getChatType() {
|
||||
return isGlobal ? "global" : "local";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,14 +6,15 @@ import java.util.UUID;
|
|||
* Модель данных мута (Value Object)
|
||||
*/
|
||||
public class MuteData {
|
||||
private UUID uuid;
|
||||
private String playerName;
|
||||
public long endTime; // 0 = перманентный (public for JSON serialization)
|
||||
public String reason;
|
||||
public String mutedBy;
|
||||
public long mutedAt;
|
||||
private UUID uuid;
|
||||
private String playerName;
|
||||
|
||||
public MuteData() {} // For JSON deserialization
|
||||
public MuteData() {
|
||||
} // For JSON deserialization
|
||||
|
||||
public MuteData(UUID uuid, String playerName, long endTime, String reason, String mutedBy) {
|
||||
this.uuid = uuid;
|
||||
|
|
@ -32,13 +33,33 @@ public class MuteData {
|
|||
this.playerName = playerName;
|
||||
}
|
||||
|
||||
public UUID getUuid() { return uuid; }
|
||||
public String getPlayerName() { return playerName; }
|
||||
public long getEndTime() { return endTime; }
|
||||
public String getReason() { return reason; }
|
||||
public String getMutedBy() { return mutedBy; }
|
||||
public long getMutedAt() { return mutedAt; }
|
||||
public boolean isPermanent() { return endTime == 0; }
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public String getPlayerName() {
|
||||
return playerName;
|
||||
}
|
||||
|
||||
public long getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
public String getMutedBy() {
|
||||
return mutedBy;
|
||||
}
|
||||
|
||||
public long getMutedAt() {
|
||||
return mutedAt;
|
||||
}
|
||||
|
||||
public boolean isPermanent() {
|
||||
return endTime == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Запись истории мута
|
||||
|
|
@ -53,7 +74,8 @@ public class MuteData {
|
|||
public String unmutedBy;
|
||||
public long unmutedAt;
|
||||
|
||||
public MuteHistoryEntry() {} // For JSON deserialization
|
||||
public MuteHistoryEntry() {
|
||||
} // For JSON deserialization
|
||||
|
||||
public MuteHistoryEntry(String playerName, long duration, String reason,
|
||||
String mutedBy, long mutedAt, boolean unmuted,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ public class GradientModule {
|
|||
|
||||
/**
|
||||
* Инициализация модуля
|
||||
*
|
||||
* @return true если модуль успешно инициализирован
|
||||
*/
|
||||
public boolean init() {
|
||||
|
|
@ -141,6 +142,7 @@ public class GradientModule {
|
|||
|
||||
/**
|
||||
* Получает отформатированное имя игрока с градиентом и LuckPerms префиксом
|
||||
*
|
||||
* @param useTabFormat true для §x§... формата (TAB), false для &#RRGGBB
|
||||
*/
|
||||
private String getFormattedName(Player player, boolean useTabFormat) {
|
||||
|
|
@ -263,12 +265,35 @@ public class GradientModule {
|
|||
}
|
||||
|
||||
// Геттеры
|
||||
public JavaPlugin getPlugin() { return plugin; }
|
||||
public GradientConfig getConfig() { return config; }
|
||||
public GradientMessages getMessages() { return messages; }
|
||||
public GradientDataManager getDataManager() { return dataManager; }
|
||||
public GradientLuckPermsHook getLuckPermsHook() { return luckPermsHook; }
|
||||
public PlayerPointsAPI getPlayerPointsAPI() { return playerPointsAPI; }
|
||||
public boolean hasPlayerPoints() { return playerPointsAPI != null; }
|
||||
public boolean isEnabled() { return enabled; }
|
||||
public JavaPlugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public GradientConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public GradientMessages getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public GradientDataManager getDataManager() {
|
||||
return dataManager;
|
||||
}
|
||||
|
||||
public GradientLuckPermsHook getLuckPermsHook() {
|
||||
return luckPermsHook;
|
||||
}
|
||||
|
||||
public PlayerPointsAPI getPlayerPointsAPI() {
|
||||
return playerPointsAPI;
|
||||
}
|
||||
|
||||
public boolean hasPlayerPoints() {
|
||||
return playerPointsAPI != null;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@ import java.util.List;
|
|||
*/
|
||||
public class GradientAdminCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
private final GradientModule module;
|
||||
private static final List<String> PRESET_COLORS = Arrays.asList(
|
||||
"#FF0000", "#FF7F00", "#FFFF00", "#00FF00", "#0000FF", "#4B0082", "#9400D3"
|
||||
);
|
||||
private final GradientModule module;
|
||||
|
||||
public GradientAdminCommand(GradientModule module) {
|
||||
this.module = module;
|
||||
|
|
|
|||
|
|
@ -26,14 +26,13 @@ import java.util.function.BiFunction;
|
|||
*/
|
||||
public class GradientColorCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
private final GradientModule module;
|
||||
private final Map<String, BiFunction<Player, String[], Boolean>> subCommands = new HashMap<>();
|
||||
|
||||
private static final List<String> PRESET_COLORS = List.of(
|
||||
"#FF0000", "#FF7F00", "#FFFF00", "#00FF00", "#0000FF", "#4B0082", "#9400D3",
|
||||
"#FF69B4", "#00FFFF", "#FFD700", "#FFFFFF", "#000000"
|
||||
);
|
||||
private static final Set<String> SUB_COMMANDS = Set.of("on", "off", "reset", "copy");
|
||||
private final GradientModule module;
|
||||
private final Map<String, BiFunction<Player, String[], Boolean>> subCommands = new HashMap<>();
|
||||
|
||||
public GradientColorCommand(GradientModule module) {
|
||||
this.module = module;
|
||||
|
|
|
|||
|
|
@ -28,13 +28,12 @@ import java.util.regex.Pattern;
|
|||
*/
|
||||
public class GradientPrefixCommand implements CommandExecutor, TabCompleter {
|
||||
|
||||
private final GradientModule module;
|
||||
private final Map<String, BiFunction<Player, String[], Boolean>> subCommands = new HashMap<>();
|
||||
|
||||
private static final Pattern COLOR_CODE_PATTERN = Pattern.compile(
|
||||
"(?i)(&[0-9a-fk-or]|§[0-9a-fk-or]|#[0-9a-f]{6}|&#[0-9a-f]{6}|<#[0-9a-f]{6}>)");
|
||||
private static final Pattern ALLOWED_PREFIX_PATTERN = Pattern.compile("^[a-zA-Zа-яА-ЯёЁ0-9 _\\-]+$");
|
||||
private static final Set<String> SUB_COMMANDS = Set.of("on", "off", "reset");
|
||||
private final GradientModule module;
|
||||
private final Map<String, BiFunction<Player, String[], Boolean>> subCommands = new HashMap<>();
|
||||
|
||||
public GradientPrefixCommand(GradientModule module) {
|
||||
this.module = module;
|
||||
|
|
|
|||
|
|
@ -56,22 +56,69 @@ public class GradientConfig {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled() { return config.getBoolean("enabled", true); }
|
||||
public int getMaxColors() { return config.getInt("max-colors", 7); }
|
||||
public int getMinColors() { return config.getInt("min-colors", 1); }
|
||||
public int getPricePerColor() { return config.getInt("price-per-color", 50); }
|
||||
public int getPrefixPrice() { return config.getInt("prefix-price", 500); }
|
||||
public boolean isPrefixOneTimePurchase() { return config.getBoolean("prefix-one-time-purchase", true); }
|
||||
public int getColorCooldown() { return config.getInt("color-cooldown", 60); }
|
||||
public int getPrefixCooldown() { return config.getInt("prefix-cooldown", 300); }
|
||||
public int getMaxPrefixLength() { return config.getInt("max-prefix-length", 7); }
|
||||
public String getPrefixFormat() { return config.getString("prefix-format", "[{prefix}] "); }
|
||||
public boolean isGradientOnPrefix() { return config.getBoolean("gradient-on-prefix", true); }
|
||||
public boolean isGradientOnLuckPermsPrefix() { return config.getBoolean("gradient-on-luckperms-prefix", true); }
|
||||
public boolean isContinuousGradient() { return config.getBoolean("continuous-gradient", true); }
|
||||
public boolean isUseLegacyRgbFormat() { return config.getBoolean("use-legacy-rgb-format", true); }
|
||||
public String getStorageType() { return config.getString("storage-type", "YAML"); }
|
||||
public String getSqliteFile() { return config.getString("sqlite-file", "gradient-data.db"); }
|
||||
public boolean isEnabled() {
|
||||
return config.getBoolean("enabled", true);
|
||||
}
|
||||
|
||||
public int getMaxColors() {
|
||||
return config.getInt("max-colors", 7);
|
||||
}
|
||||
|
||||
public int getMinColors() {
|
||||
return config.getInt("min-colors", 1);
|
||||
}
|
||||
|
||||
public int getPricePerColor() {
|
||||
return config.getInt("price-per-color", 50);
|
||||
}
|
||||
|
||||
public int getPrefixPrice() {
|
||||
return config.getInt("prefix-price", 500);
|
||||
}
|
||||
|
||||
public boolean isPrefixOneTimePurchase() {
|
||||
return config.getBoolean("prefix-one-time-purchase", true);
|
||||
}
|
||||
|
||||
public int getColorCooldown() {
|
||||
return config.getInt("color-cooldown", 60);
|
||||
}
|
||||
|
||||
public int getPrefixCooldown() {
|
||||
return config.getInt("prefix-cooldown", 300);
|
||||
}
|
||||
|
||||
public int getMaxPrefixLength() {
|
||||
return config.getInt("max-prefix-length", 7);
|
||||
}
|
||||
|
||||
public String getPrefixFormat() {
|
||||
return config.getString("prefix-format", "[{prefix}] ");
|
||||
}
|
||||
|
||||
public boolean isGradientOnPrefix() {
|
||||
return config.getBoolean("gradient-on-prefix", true);
|
||||
}
|
||||
|
||||
public boolean isGradientOnLuckPermsPrefix() {
|
||||
return config.getBoolean("gradient-on-luckperms-prefix", true);
|
||||
}
|
||||
|
||||
public boolean isContinuousGradient() {
|
||||
return config.getBoolean("continuous-gradient", true);
|
||||
}
|
||||
|
||||
public boolean isUseLegacyRgbFormat() {
|
||||
return config.getBoolean("use-legacy-rgb-format", true);
|
||||
}
|
||||
|
||||
public String getStorageType() {
|
||||
return config.getString("storage-type", "YAML");
|
||||
}
|
||||
|
||||
public String getSqliteFile() {
|
||||
return config.getString("sqlite-file", "gradient-data.db");
|
||||
}
|
||||
|
||||
public List<String> getPrefixBlacklist() {
|
||||
return config.getStringList("prefix-blacklist");
|
||||
|
|
|
|||
|
|
@ -79,7 +79,8 @@ public class GradientDataManager {
|
|||
playerData.setLastColorChange(data.getLong(uuidStr + ".last-color-change", 0));
|
||||
playerData.setLastPrefixChange(data.getLong(uuidStr + ".last-prefix-change", 0));
|
||||
cache.put(uuid, playerData);
|
||||
} catch (IllegalArgumentException ignored) {}
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,25 +29,71 @@ public class GradientPlayerData {
|
|||
this.lastPrefixChange = 0;
|
||||
}
|
||||
|
||||
public UUID getUuid() { return uuid; }
|
||||
public String getPrefix() { return prefix; }
|
||||
public void setPrefix(String prefix) { this.prefix = prefix; }
|
||||
public List<String> getColors() { return colors; }
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public void setPrefix(String prefix) {
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
public List<String> getColors() {
|
||||
return colors;
|
||||
}
|
||||
|
||||
public void setColors(List<String> colors) {
|
||||
this.colors = colors != null ? new ArrayList<>(colors) : new ArrayList<>();
|
||||
}
|
||||
|
||||
public boolean hasPrefix() { return prefix != null && !prefix.isEmpty(); }
|
||||
public boolean hasColors() { return colors != null && !colors.isEmpty(); }
|
||||
public boolean isColorEnabled() { return colorEnabled; }
|
||||
public void setColorEnabled(boolean colorEnabled) { this.colorEnabled = colorEnabled; }
|
||||
public boolean isPrefixEnabled() { return prefixEnabled; }
|
||||
public void setPrefixEnabled(boolean prefixEnabled) { this.prefixEnabled = prefixEnabled; }
|
||||
public boolean isPrefixPurchased() { return prefixPurchased; }
|
||||
public void setPrefixPurchased(boolean prefixPurchased) { this.prefixPurchased = prefixPurchased; }
|
||||
public long getLastColorChange() { return lastColorChange; }
|
||||
public void setLastColorChange(long lastColorChange) { this.lastColorChange = lastColorChange; }
|
||||
public long getLastPrefixChange() { return lastPrefixChange; }
|
||||
public void setLastPrefixChange(long lastPrefixChange) { this.lastPrefixChange = lastPrefixChange; }
|
||||
public boolean hasPrefix() {
|
||||
return prefix != null && !prefix.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasColors() {
|
||||
return colors != null && !colors.isEmpty();
|
||||
}
|
||||
|
||||
public boolean isColorEnabled() {
|
||||
return colorEnabled;
|
||||
}
|
||||
|
||||
public void setColorEnabled(boolean colorEnabled) {
|
||||
this.colorEnabled = colorEnabled;
|
||||
}
|
||||
|
||||
public boolean isPrefixEnabled() {
|
||||
return prefixEnabled;
|
||||
}
|
||||
|
||||
public void setPrefixEnabled(boolean prefixEnabled) {
|
||||
this.prefixEnabled = prefixEnabled;
|
||||
}
|
||||
|
||||
public boolean isPrefixPurchased() {
|
||||
return prefixPurchased;
|
||||
}
|
||||
|
||||
public void setPrefixPurchased(boolean prefixPurchased) {
|
||||
this.prefixPurchased = prefixPurchased;
|
||||
}
|
||||
|
||||
public long getLastColorChange() {
|
||||
return lastColorChange;
|
||||
}
|
||||
|
||||
public void setLastColorChange(long lastColorChange) {
|
||||
this.lastColorChange = lastColorChange;
|
||||
}
|
||||
|
||||
public long getLastPrefixChange() {
|
||||
return lastPrefixChange;
|
||||
}
|
||||
|
||||
public void setLastPrefixChange(long lastPrefixChange) {
|
||||
this.lastPrefixChange = lastPrefixChange;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,21 +23,16 @@ import java.util.List;
|
|||
/**
|
||||
* GUI подтверждения для градиентного модуля
|
||||
*/
|
||||
public class GradientConfirmGUI implements InventoryHolder {
|
||||
|
||||
public enum ConfirmType {
|
||||
COLOR, PREFIX
|
||||
}
|
||||
public final class GradientConfirmGUI implements InventoryHolder {
|
||||
|
||||
private static final LegacyComponentSerializer SERIALIZER = LegacyComponentSerializer.builder()
|
||||
.character('&')
|
||||
.hexCharacter('#')
|
||||
.hexColors()
|
||||
.build();
|
||||
|
||||
private final GradientModule module;
|
||||
private final Player player;
|
||||
private final Inventory inventory;
|
||||
private Inventory inventory;
|
||||
private final ConfirmType type;
|
||||
private final List<String> colors;
|
||||
private final String prefix;
|
||||
|
|
@ -51,6 +46,10 @@ public class GradientConfirmGUI implements InventoryHolder {
|
|||
this.colors = colors;
|
||||
this.prefix = prefix;
|
||||
this.price = price;
|
||||
}
|
||||
|
||||
private void initInventory() {
|
||||
if (inventory != null) return;
|
||||
this.inventory = Bukkit.createInventory(this, 27,
|
||||
Component.text("Подтверждение", NamedTextColor.DARK_GRAY));
|
||||
setupItems();
|
||||
|
|
@ -187,14 +186,37 @@ public class GradientConfirmGUI implements InventoryHolder {
|
|||
}
|
||||
|
||||
public void open() {
|
||||
initInventory();
|
||||
player.openInventory(inventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Inventory getInventory() { return inventory; }
|
||||
public Player getPlayer() { return player; }
|
||||
public ConfirmType getType() { return type; }
|
||||
public List<String> getColors() { return colors; }
|
||||
public String getPrefix() { return prefix; }
|
||||
public int getPrice() { return price; }
|
||||
public @NotNull Inventory getInventory() {
|
||||
initInventory();
|
||||
return inventory;
|
||||
}
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
}
|
||||
|
||||
public ConfirmType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public List<String> getColors() {
|
||||
return colors;
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
return prefix;
|
||||
}
|
||||
|
||||
public int getPrice() {
|
||||
return price;
|
||||
}
|
||||
|
||||
public enum ConfirmType {
|
||||
COLOR, PREFIX
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,12 +19,11 @@ import java.util.Map;
|
|||
*/
|
||||
public class GradientGUIListener implements Listener {
|
||||
|
||||
private final GradientModule module;
|
||||
|
||||
private static final Map<GradientConfirmGUI.ConfirmType, String> PRICE_MSG_KEYS = Map.of(
|
||||
GradientConfirmGUI.ConfirmType.COLOR, "not-enough-points-color",
|
||||
GradientConfirmGUI.ConfirmType.PREFIX, "not-enough-points-prefix"
|
||||
);
|
||||
private final GradientModule module;
|
||||
|
||||
public GradientGUIListener(GradientModule module) {
|
||||
this.module = module;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ public final class DisplayNameUtil {
|
|||
.hexColors()
|
||||
.build();
|
||||
|
||||
private DisplayNameUtil() {}
|
||||
private DisplayNameUtil() {
|
||||
}
|
||||
|
||||
public static void updateDisplayName(GradientModule module, Player player, GradientPlayerData data) {
|
||||
GradientConfig cfg = module.getConfig();
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@ public final class FoliaUtil {
|
|||
IS_FOLIA = checkFolia();
|
||||
}
|
||||
|
||||
private FoliaUtil() {}
|
||||
private FoliaUtil() {
|
||||
}
|
||||
|
||||
private static boolean checkFolia() {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -5,15 +5,14 @@ package com.loki.lochat.gradient.util;
|
|||
*/
|
||||
public final class GradientConstants {
|
||||
|
||||
private GradientConstants() {}
|
||||
|
||||
public static final long MILLIS_PER_SECOND = 1000L;
|
||||
|
||||
// GUI слоты
|
||||
public static final int GUI_CONFIRM_SLOT = 11;
|
||||
public static final int GUI_CANCEL_SLOT = 15;
|
||||
public static final int GUI_PREVIEW_SLOT = 13;
|
||||
|
||||
// LuckPerms
|
||||
public static final int LUCKPERMS_PREFIX_PRIORITY = 100;
|
||||
|
||||
private GradientConstants() {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ public final class GradientUtil {
|
|||
|
||||
private static final Pattern HEX_PATTERN = Pattern.compile("^#[0-9A-Fa-f]{6}$");
|
||||
|
||||
private GradientUtil() {}
|
||||
private GradientUtil() {
|
||||
}
|
||||
|
||||
public static boolean isValidHex(String color) {
|
||||
return HEX_PATTERN.matcher(color).matches();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
package com.loki.lochat.integrations;
|
||||
|
||||
import com.loki.lochat.LoChat;
|
||||
import com.loki.lochat.api.service.*;
|
||||
import com.loki.lochat.api.service.ChatService;
|
||||
import com.loki.lochat.api.service.IgnoreService;
|
||||
import com.loki.lochat.api.service.PMService;
|
||||
import com.loki.lochat.api.service.SpyService;
|
||||
import com.loki.lochat.gradient.GradientModule;
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import org.bukkit.Bukkit;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ public class SkinsRestorerHook {
|
|||
|
||||
/**
|
||||
* Получает текстуру скина игрока
|
||||
*
|
||||
* @param player игрок
|
||||
* @return URL текстуры или null
|
||||
*/
|
||||
|
|
@ -72,6 +73,7 @@ public class SkinsRestorerHook {
|
|||
|
||||
/**
|
||||
* Получает URL головы игрока для отображения
|
||||
*
|
||||
* @param playerName имя игрока
|
||||
* @return URL головы
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@ import com.loki.lochat.core.filter.AdvancedMessageFilter;
|
|||
import com.loki.lochat.core.registry.ServiceRegistry;
|
||||
import com.loki.lochat.utils.MentionHandler;
|
||||
import com.loki.lochat.utils.TextFormatter;
|
||||
import io.papermc.paper.event.player.AsyncChatEvent;
|
||||
import io.papermc.paper.chat.ChatRenderer;
|
||||
import io.papermc.paper.event.player.AsyncChatEvent;
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
|
|
@ -47,13 +47,13 @@ public class ChatEventListener implements Listener {
|
|||
|
||||
AdvancedMessageFilter.FilterResult filterResult = advancedFilter.filterMessage(sender, message);
|
||||
|
||||
if (!filterResult.isAllowed()) {
|
||||
if (!filterResult.allowed()) {
|
||||
event.setCancelled(true);
|
||||
sender.sendMessage(com.loki.lochat.utils.ChatFormatter.parse(filterResult.getBlockReason()));
|
||||
sender.sendMessage(com.loki.lochat.utils.ChatFormatter.parse(filterResult.blockReason()));
|
||||
return;
|
||||
}
|
||||
|
||||
String filteredMessage = filterResult.getFilteredMessage();
|
||||
String filteredMessage = filterResult.filteredMessage();
|
||||
event.message(Component.text(filteredMessage));
|
||||
|
||||
event.renderer(new EnhancedChatRenderer(sender, event.message()));
|
||||
|
|
|
|||
|
|
@ -24,14 +24,15 @@ public class CustomCommandManager {
|
|||
private final LoChat plugin;
|
||||
private final Map<String, CustomCommandData> commands;
|
||||
|
||||
public CustomCommandManager(LoChat plugin) {
|
||||
private CustomCommandManager(LoChat plugin) {
|
||||
this.plugin = plugin;
|
||||
this.commands = new HashMap<>();
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
loadCommands();
|
||||
public static CustomCommandManager create(LoChat plugin) {
|
||||
CustomCommandManager manager = new CustomCommandManager(plugin);
|
||||
manager.loadCommands();
|
||||
return manager;
|
||||
}
|
||||
|
||||
private void loadCommands() {
|
||||
|
|
@ -263,22 +264,7 @@ public class CustomCommandManager {
|
|||
return commands;
|
||||
}
|
||||
|
||||
public static class CustomCommandData {
|
||||
public final String name;
|
||||
public final String permission;
|
||||
public final String message;
|
||||
public final List<String> aliases;
|
||||
public final String type;
|
||||
public final String target;
|
||||
|
||||
public CustomCommandData(String name, String permission, String message,
|
||||
List<String> aliases, String type, String target) {
|
||||
this.name = name;
|
||||
this.permission = permission;
|
||||
this.message = message;
|
||||
this.aliases = aliases;
|
||||
this.type = type;
|
||||
this.target = target;
|
||||
}
|
||||
public record CustomCommandData(String name, String permission, String message, List<String> aliases, String type,
|
||||
String target) {
|
||||
}
|
||||
}
|
||||
|
|
@ -17,9 +17,14 @@ public class EmojiManager {
|
|||
private boolean enabled;
|
||||
private boolean requirePermission;
|
||||
|
||||
public EmojiManager(LoChat plugin) {
|
||||
private EmojiManager(LoChat plugin) {
|
||||
this.plugin = plugin;
|
||||
load();
|
||||
}
|
||||
|
||||
public static EmojiManager create(LoChat plugin) {
|
||||
EmojiManager manager = new EmojiManager(plugin);
|
||||
manager.load();
|
||||
return manager;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public class FoliaUtil {
|
|||
|
||||
/**
|
||||
* Запускает глобальную повторяющуюся задачу
|
||||
*
|
||||
* @param plugin плагин
|
||||
* @param task задача
|
||||
* @param delayTicks задержка перед первым запуском (в тиках)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ public class TimeParser {
|
|||
|
||||
/**
|
||||
* Парсит строку времени в миллисекунды
|
||||
*
|
||||
* @param timeStr строка вида "1d", "2h", "30m", "60s"
|
||||
* @return миллисекунды или -1 при ошибке
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ public final class ChatFormatter {
|
|||
private static final PlainTextComponentSerializer PLAIN =
|
||||
PlainTextComponentSerializer.plainText();
|
||||
|
||||
private ChatFormatter() {}
|
||||
private ChatFormatter() {
|
||||
}
|
||||
|
||||
/* ===================== BASIC ===================== */
|
||||
|
||||
|
|
|
|||
|
|
@ -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,7 +5,8 @@ import org.bukkit.entity.Player;
|
|||
|
||||
public class DistanceUtil {
|
||||
|
||||
private DistanceUtil() {}
|
||||
private DistanceUtil() {
|
||||
}
|
||||
|
||||
public static boolean isInRange(Player player1, Player player2, int radius) {
|
||||
// Проверка на один мир
|
||||
|
|
|
|||
|
|
@ -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 если игрок онлайн
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue