feat(lohub): Add complete configuration system with 6 config files
- Added messages.yml for all plugin messages with customizable prefix - Added commands.yml for custom commands (discord, website, store, rules, heal, clearinventory) - Added serverselector.yml for GUI server selector menu - Added data.yml for persistent data storage (chat_locked, spawn location) - Updated ConfigManager to load all config files - Updated ChatLockManager to use data.yml instead of chatlock.dat - Updated SpawnManager to use data.yml instead of spawn.yml - Updated all commands to use messages.yml - Updated listeners to use messages.yml - Removed duplicate config files from root directory - Added CONFIG_GUIDE.md documentation
This commit is contained in:
parent
102341bb2c
commit
1e5e8d8638
36 changed files with 1580 additions and 544 deletions
|
|
@ -5,7 +5,9 @@ import com.loki.lohub.listeners.HubProtectionListener;
|
|||
import com.loki.lohub.listeners.PlayerJoinListener;
|
||||
import com.loki.lohub.managers.ActionManager;
|
||||
import com.loki.lohub.managers.AnnouncementManager;
|
||||
import com.loki.lohub.managers.ChatLockManager;
|
||||
import com.loki.lohub.managers.CooldownManager;
|
||||
import com.loki.lohub.managers.CustomCommandManager;
|
||||
import com.loki.lohub.managers.HotbarManager;
|
||||
import com.loki.lohub.managers.PlayerHiderManager;
|
||||
import com.loki.lohub.managers.RegionManager;
|
||||
|
|
@ -27,6 +29,8 @@ public class LoHub extends JavaPlugin {
|
|||
private ScoreboardManager scoreboardManager;
|
||||
private TablistManager tablistManager;
|
||||
private AnnouncementManager announcementManager;
|
||||
private ChatLockManager chatLockManager;
|
||||
private CustomCommandManager customCommandManager;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
|
@ -46,6 +50,8 @@ public class LoHub extends JavaPlugin {
|
|||
this.scoreboardManager = new ScoreboardManager(this);
|
||||
this.tablistManager = new TablistManager(this);
|
||||
this.announcementManager = new AnnouncementManager(this);
|
||||
this.chatLockManager = new ChatLockManager(this);
|
||||
this.customCommandManager = new CustomCommandManager(this);
|
||||
|
||||
registerListeners();
|
||||
registerCommands();
|
||||
|
|
@ -73,12 +79,15 @@ public class LoHub extends JavaPlugin {
|
|||
getServer().getPluginManager().registerEvents(new com.loki.lohub.listeners.HotbarListener(this), this);
|
||||
getServer().getPluginManager().registerEvents(new com.loki.lohub.listeners.LaunchpadListener(this), this);
|
||||
getServer().getPluginManager().registerEvents(new com.loki.lohub.listeners.DoubleJumpListener(this), this);
|
||||
getServer().getPluginManager().registerEvents(new com.loki.lohub.listeners.ChatLockListener(this), this);
|
||||
getServer().getPluginManager().registerEvents(new com.loki.lohub.listeners.CustomCommandListener(this), this);
|
||||
}
|
||||
|
||||
private void registerCommands() {
|
||||
getCommand("hub").setExecutor(new com.loki.lohub.commands.HubCommand(this));
|
||||
getCommand("sethub").setExecutor(new com.loki.lohub.commands.SetHubCommand(this));
|
||||
getCommand("lohub").setExecutor(new com.loki.lohub.commands.LoHubCommand(this));
|
||||
getCommand("chatlock").setExecutor(new com.loki.lohub.commands.ChatLockCommand(this));
|
||||
}
|
||||
|
||||
public ConfigManager getConfigManager() {
|
||||
|
|
@ -120,4 +129,12 @@ public class LoHub extends JavaPlugin {
|
|||
public AnnouncementManager getAnnouncementManager() {
|
||||
return announcementManager;
|
||||
}
|
||||
|
||||
public ChatLockManager getChatLockManager() {
|
||||
return chatLockManager;
|
||||
}
|
||||
|
||||
public CustomCommandManager getCustomCommandManager() {
|
||||
return customCommandManager;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
package com.loki.lohub.commands;
|
||||
|
||||
import com.loki.lohub.LoHub;
|
||||
import com.loki.lohub.utils.TextUtil;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ChatLockCommand implements CommandExecutor {
|
||||
|
||||
private final LoHub plugin;
|
||||
|
||||
public ChatLockCommand(LoHub plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command,
|
||||
@NotNull String label, @NotNull String[] args) {
|
||||
if (!sender.hasPermission("lohub.chatlock")) {
|
||||
sender.sendMessage(TextUtil.colorize(plugin.getConfigManager().getMessage("general.no-permission")));
|
||||
return true;
|
||||
}
|
||||
|
||||
plugin.getChatLockManager().toggle();
|
||||
boolean locked = plugin.getChatLockManager().isChatLocked();
|
||||
|
||||
String message = locked
|
||||
? plugin.getConfigManager().getMessage("chat.lock-enabled")
|
||||
: plugin.getConfigManager().getMessage("chat.lock-disabled");
|
||||
|
||||
sender.sendMessage(TextUtil.colorize(message));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -18,17 +18,17 @@ public class HubCommand implements CommandExecutor {
|
|||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendMessage(TextUtil.colorize("&cThis command is only for players!"));
|
||||
sender.sendMessage(TextUtil.colorize(plugin.getConfigManager().getMessage("general.players-only")));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (plugin.getSpawnManager().getSpawn() == null) {
|
||||
player.sendMessage(TextUtil.colorize(plugin.getConfig().getString("messages.no-spawn")));
|
||||
player.sendMessage(TextUtil.colorize(plugin.getConfigManager().getMessage("spawn.no-spawn")));
|
||||
return true;
|
||||
}
|
||||
|
||||
plugin.getSpawnManager().teleportToSpawn(player);
|
||||
player.sendMessage(TextUtil.colorize(plugin.getConfig().getString("messages.spawn-teleport")));
|
||||
player.sendMessage(TextUtil.colorize(plugin.getConfigManager().getMessage("spawn.teleport")));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,13 +17,13 @@ public class LoHubCommand implements CommandExecutor {
|
|||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!sender.hasPermission("lohub.admin")) {
|
||||
sender.sendMessage(TextUtil.colorize(plugin.getConfig().getString("messages.no-permission")));
|
||||
sender.sendMessage(TextUtil.colorize(plugin.getConfigManager().getMessage("general.no-permission")));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (args.length == 0) {
|
||||
sender.sendMessage(TextUtil.colorize("&7LoHub v" + plugin.getDescription().getVersion()));
|
||||
sender.sendMessage(TextUtil.colorize("&7Use: &e/lohub reload"));
|
||||
sender.sendMessage(TextUtil.colorize(plugin.getConfigManager().getMessage("commands.usage-lohub")));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ public class LoHubCommand implements CommandExecutor {
|
|||
plugin.getTablistManager().stop();
|
||||
plugin.getScoreboardManager().start();
|
||||
plugin.getTablistManager().start();
|
||||
sender.sendMessage(TextUtil.colorize("&aConfiguration reloaded!"));
|
||||
sender.sendMessage(TextUtil.colorize(plugin.getConfigManager().getMessage("general.config-reloaded")));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,25 +18,21 @@ public class SetHubCommand implements CommandExecutor {
|
|||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (!(sender instanceof Player player)) {
|
||||
sender.sendMessage(TextUtil.colorize("&cThis command is only for players!"));
|
||||
sender.sendMessage(TextUtil.colorize(plugin.getConfigManager().getMessage("general.players-only")));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!player.hasPermission("lohub.admin")) {
|
||||
player.sendMessage(TextUtil.colorize(plugin.getConfig().getString("messages.no-permission")));
|
||||
player.sendMessage(TextUtil.colorize(plugin.getConfigManager().getMessage("general.no-permission")));
|
||||
return true;
|
||||
}
|
||||
|
||||
plugin.getSpawnManager().setSpawn(player.getLocation());
|
||||
player.sendMessage(TextUtil.colorize(plugin.getConfig().getString("messages.spawn-set")));
|
||||
player.sendMessage(TextUtil.colorize(plugin.getConfigManager().getMessage("spawn.set")));
|
||||
|
||||
plugin.getRegionManager().deleteHubRegion();
|
||||
plugin.getRegionManager().createHubRegion();
|
||||
|
||||
if (plugin.getConfig().getBoolean("worldguard.auto-create-region")) {
|
||||
player.sendMessage(TextUtil.colorize(plugin.getConfig().getString("messages.region-created")));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
21
lohub/src/main/java/com/loki/lohub/common/ConfigHelper.java
Normal file
21
lohub/src/main/java/com/loki/lohub/common/ConfigHelper.java
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
package com.loki.lohub.common;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
public final class ConfigHelper {
|
||||
|
||||
private ConfigHelper() {
|
||||
}
|
||||
|
||||
public static boolean isEnabled(FileConfiguration config, String path) {
|
||||
return config.getBoolean(path + ".enabled", true);
|
||||
}
|
||||
|
||||
public static double getPower(FileConfiguration config, String path, String key, double defaultValue) {
|
||||
return config.getDouble(path + "." + key, defaultValue);
|
||||
}
|
||||
|
||||
public static int getCooldown(FileConfiguration config, String path, int defaultValue) {
|
||||
return config.getInt(path + ".cooldown", defaultValue);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.loki.lohub.common;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class GameModeHelper {
|
||||
|
||||
private GameModeHelper() {
|
||||
}
|
||||
|
||||
public static boolean isCreativeOrSpectator(Player player) {
|
||||
GameMode mode = player.getGameMode();
|
||||
return mode == GameMode.CREATIVE || mode == GameMode.SPECTATOR;
|
||||
}
|
||||
}
|
||||
16
lohub/src/main/java/com/loki/lohub/common/LaunchHelper.java
Normal file
16
lohub/src/main/java/com/loki/lohub/common/LaunchHelper.java
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
package com.loki.lohub.common;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
public final class LaunchHelper {
|
||||
|
||||
private LaunchHelper() {
|
||||
}
|
||||
|
||||
public static void launch(Player player, double power, double powerY) {
|
||||
Vector velocity = player.getLocation().getDirection().multiply(power);
|
||||
velocity.setY(powerY);
|
||||
player.setVelocity(velocity);
|
||||
}
|
||||
}
|
||||
24
lohub/src/main/java/com/loki/lohub/common/TextFormatter.java
Normal file
24
lohub/src/main/java/com/loki/lohub/common/TextFormatter.java
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package com.loki.lohub.common;
|
||||
|
||||
import com.loki.lohub.utils.PlaceholderUtil;
|
||||
import com.loki.lohub.utils.TextUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class TextFormatter {
|
||||
|
||||
private TextFormatter() {
|
||||
}
|
||||
|
||||
public static String format(String text, Player player) {
|
||||
return TextUtil.colorize(PlaceholderUtil.parse(text, player));
|
||||
}
|
||||
|
||||
public static String joinLines(List<String> lines, Player player, String separator) {
|
||||
return lines.stream()
|
||||
.map(line -> format(line, player))
|
||||
.collect(Collectors.joining(separator));
|
||||
}
|
||||
}
|
||||
|
|
@ -2,26 +2,155 @@ package com.loki.lohub.config;
|
|||
|
||||
import com.loki.lohub.LoHub;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
|
||||
public class ConfigManager {
|
||||
|
||||
private final LoHub plugin;
|
||||
private FileConfiguration config;
|
||||
private FileConfiguration messages;
|
||||
private FileConfiguration commands;
|
||||
private FileConfiguration serverSelector;
|
||||
private FileConfiguration data;
|
||||
private File messagesFile;
|
||||
private File commandsFile;
|
||||
private File serverSelectorFile;
|
||||
private File dataFile;
|
||||
|
||||
public ConfigManager(LoHub plugin) {
|
||||
this.plugin = plugin;
|
||||
this.config = plugin.getConfig();
|
||||
loadMessages();
|
||||
loadCommands();
|
||||
loadServerSelector();
|
||||
loadData();
|
||||
}
|
||||
|
||||
private void loadMessages() {
|
||||
messagesFile = new File(plugin.getDataFolder(), "messages.yml");
|
||||
|
||||
if (!messagesFile.exists()) {
|
||||
try {
|
||||
messagesFile.getParentFile().mkdirs();
|
||||
InputStream in = plugin.getResource("messages.yml");
|
||||
if (in != null) {
|
||||
Files.copy(in, messagesFile.toPath());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Could not create messages.yml!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
messages = YamlConfiguration.loadConfiguration(messagesFile);
|
||||
}
|
||||
|
||||
private void loadCommands() {
|
||||
commandsFile = new File(plugin.getDataFolder(), "commands.yml");
|
||||
|
||||
if (!commandsFile.exists()) {
|
||||
try {
|
||||
commandsFile.getParentFile().mkdirs();
|
||||
InputStream in = plugin.getResource("commands.yml");
|
||||
if (in != null) {
|
||||
Files.copy(in, commandsFile.toPath());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Could not create commands.yml!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
commands = YamlConfiguration.loadConfiguration(commandsFile);
|
||||
}
|
||||
|
||||
private void loadServerSelector() {
|
||||
serverSelectorFile = new File(plugin.getDataFolder(), "serverselector.yml");
|
||||
|
||||
if (!serverSelectorFile.exists()) {
|
||||
try {
|
||||
serverSelectorFile.getParentFile().mkdirs();
|
||||
InputStream in = plugin.getResource("serverselector.yml");
|
||||
if (in != null) {
|
||||
Files.copy(in, serverSelectorFile.toPath());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Could not create serverselector.yml!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
serverSelector = YamlConfiguration.loadConfiguration(serverSelectorFile);
|
||||
}
|
||||
|
||||
private void loadData() {
|
||||
dataFile = new File(plugin.getDataFolder(), "data.yml");
|
||||
|
||||
if (!dataFile.exists()) {
|
||||
try {
|
||||
dataFile.getParentFile().mkdirs();
|
||||
InputStream in = plugin.getResource("data.yml");
|
||||
if (in != null) {
|
||||
Files.copy(in, dataFile.toPath());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Could not create data.yml!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
data = YamlConfiguration.loadConfiguration(dataFile);
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
plugin.reloadConfig();
|
||||
this.config = plugin.getConfig();
|
||||
loadMessages();
|
||||
loadCommands();
|
||||
loadServerSelector();
|
||||
loadData();
|
||||
}
|
||||
|
||||
public FileConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public FileConfiguration getMessages() {
|
||||
return messages;
|
||||
}
|
||||
|
||||
public FileConfiguration getCommands() {
|
||||
return commands;
|
||||
}
|
||||
|
||||
public FileConfiguration getServerSelector() {
|
||||
return serverSelector;
|
||||
}
|
||||
|
||||
public FileConfiguration getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void saveData() {
|
||||
try {
|
||||
data.save(dataFile);
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Could not save data.yml!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String getMessage(String path) {
|
||||
String message = messages.getString(path, "&#FF6B6BMessage not found: " + path);
|
||||
String prefix = messages.getString("prefix", "�D4FF[LoHub] ");
|
||||
return message.replace("{prefix}", prefix);
|
||||
}
|
||||
|
||||
public boolean isProtectionEnabled() {
|
||||
return config.getBoolean("protection.enabled", true);
|
||||
}
|
||||
|
|
|
|||
104
lohub/src/main/java/com/loki/lohub/features/FireworkHandler.java
Normal file
104
lohub/src/main/java/com/loki/lohub/features/FireworkHandler.java
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
package com.loki.lohub.features;
|
||||
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.FireworkEffect;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.meta.FireworkMeta;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class FireworkHandler {
|
||||
|
||||
private static final Map<String, Color> COLOR_MAP = new HashMap<>();
|
||||
private static final String CONFIG_PATH = "join_settings.firework";
|
||||
|
||||
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 FireworkHandler() {
|
||||
}
|
||||
|
||||
public static void spawn(Player player, FileConfiguration config) {
|
||||
if (!config.getBoolean(CONFIG_PATH + ".enabled", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldSkip(player, config)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Location loc = player.getLocation();
|
||||
Firework firework = (Firework) loc.getWorld().spawnEntity(loc, EntityType.FIREWORK_ROCKET);
|
||||
FireworkMeta meta = firework.getFireworkMeta();
|
||||
|
||||
meta.addEffect(buildEffect(config));
|
||||
meta.setPower(config.getInt(CONFIG_PATH + ".power", 1));
|
||||
firework.setFireworkMeta(meta);
|
||||
}
|
||||
|
||||
private static boolean shouldSkip(Player player, FileConfiguration config) {
|
||||
boolean firstJoinOnly = config.getBoolean(CONFIG_PATH + ".first_join_only", true);
|
||||
return firstJoinOnly && player.hasPlayedBefore();
|
||||
}
|
||||
|
||||
private static FireworkEffect buildEffect(FileConfiguration config) {
|
||||
FireworkEffect.Type type = getType(config);
|
||||
List<Color> colors = getColors(config);
|
||||
|
||||
return FireworkEffect.builder()
|
||||
.with(type)
|
||||
.withColor(colors)
|
||||
.flicker(config.getBoolean(CONFIG_PATH + ".flicker", true))
|
||||
.trail(config.getBoolean(CONFIG_PATH + ".trail", true))
|
||||
.build();
|
||||
}
|
||||
|
||||
private static FireworkEffect.Type getType(FileConfiguration config) {
|
||||
String typeStr = config.getString(CONFIG_PATH + ".type", "BALL_LARGE");
|
||||
try {
|
||||
return FireworkEffect.Type.valueOf(typeStr);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return FireworkEffect.Type.BALL_LARGE;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Color> getColors(FileConfiguration config) {
|
||||
List<Color> colors = new ArrayList<>();
|
||||
for (String colorStr : config.getStringList(CONFIG_PATH + ".colors")) {
|
||||
Color color = COLOR_MAP.get(colorStr.toUpperCase());
|
||||
if (color != null) {
|
||||
colors.add(color);
|
||||
}
|
||||
}
|
||||
|
||||
if (colors.isEmpty()) {
|
||||
colors.add(Color.AQUA);
|
||||
}
|
||||
|
||||
return colors;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package com.loki.lohub.features;
|
||||
|
||||
import com.loki.lohub.utils.TextUtil;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
public final class JoinMessageHandler {
|
||||
|
||||
private static final String CONFIG_PATH = "join_leave_messages";
|
||||
|
||||
private JoinMessageHandler() {
|
||||
}
|
||||
|
||||
public static void handleJoin(PlayerJoinEvent event, Player player, FileConfiguration config) {
|
||||
if (!config.getBoolean(CONFIG_PATH + ".enabled", true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String message = config.getString(CONFIG_PATH + ".join_message", "");
|
||||
if (message.isEmpty()) {
|
||||
event.joinMessage(null);
|
||||
} else {
|
||||
String formatted = TextUtil.colorize(message.replace("%player%", player.getName()));
|
||||
event.joinMessage(Component.text(formatted));
|
||||
}
|
||||
}
|
||||
|
||||
public static void handleQuit(PlayerQuitEvent event, Player player, FileConfiguration config) {
|
||||
if (!config.getBoolean(CONFIG_PATH + ".enabled", true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String message = config.getString(CONFIG_PATH + ".quit_message", "");
|
||||
if (message.isEmpty()) {
|
||||
event.quitMessage(null);
|
||||
} else {
|
||||
String formatted = TextUtil.colorize(message.replace("%player%", player.getName()));
|
||||
event.quitMessage(Component.text(formatted));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package com.loki.lohub.features;
|
||||
|
||||
import com.loki.lohub.LoHub;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public final class JoinSettingsHandler {
|
||||
|
||||
private static final String CONFIG_PATH = "join_settings";
|
||||
|
||||
private JoinSettingsHandler() {
|
||||
}
|
||||
|
||||
public static void apply(Player player, LoHub plugin) {
|
||||
FileConfiguration config = plugin.getConfig();
|
||||
|
||||
teleportToSpawn(player, plugin, config);
|
||||
healPlayer(player, config);
|
||||
extinguishPlayer(player, config);
|
||||
clearInventory(player, config);
|
||||
giveItems(player, plugin);
|
||||
}
|
||||
|
||||
private static void teleportToSpawn(Player player, LoHub plugin, FileConfiguration config) {
|
||||
if (!config.getBoolean(CONFIG_PATH + ".spawn_join", true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Location spawn = plugin.getSpawnManager().getSpawn();
|
||||
if (spawn != null) {
|
||||
player.teleport(spawn);
|
||||
}
|
||||
}
|
||||
|
||||
private static void healPlayer(Player player, FileConfiguration config) {
|
||||
if (!config.getBoolean(CONFIG_PATH + ".heal", true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
player.setHealth(player.getMaxHealth());
|
||||
player.setFoodLevel(20);
|
||||
player.setSaturation(20);
|
||||
}
|
||||
|
||||
private static void extinguishPlayer(Player player, FileConfiguration config) {
|
||||
if (config.getBoolean(CONFIG_PATH + ".extinguish", true)) {
|
||||
player.setFireTicks(0);
|
||||
}
|
||||
}
|
||||
|
||||
private static void clearInventory(Player player, FileConfiguration config) {
|
||||
if (config.getBoolean(CONFIG_PATH + ".clear_inventory", false)) {
|
||||
player.getInventory().clear();
|
||||
}
|
||||
}
|
||||
|
||||
private static void giveItems(Player player, LoHub plugin) {
|
||||
plugin.getHotbarManager().giveItems(player);
|
||||
plugin.getPlayerHiderManager().giveItem(player);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package com.loki.lohub.listeners;
|
||||
|
||||
import com.loki.lohub.LoHub;
|
||||
import com.loki.lohub.utils.TextUtil;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.AsyncPlayerChatEvent;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ChatLockListener implements Listener {
|
||||
|
||||
private static final List<String> BLOCKED_COMMANDS = Arrays.asList(
|
||||
"me", "msg", "tell", "w", "whisper", "pm", "dm",
|
||||
"reply", "r", "say", "minecraft:me", "minecraft:msg",
|
||||
"minecraft:tell", "bukkit:me", "bukkit:msg", "bukkit:tell"
|
||||
);
|
||||
|
||||
private final LoHub plugin;
|
||||
|
||||
public ChatLockListener(LoHub plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerChat(AsyncPlayerChatEvent event) {
|
||||
if (!plugin.getChatLockManager().isChatLocked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (player.hasPermission("lohub.chatlock.bypass")) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
player.sendMessage(Component.text(TextUtil.colorize(plugin.getConfigManager().getMessage("chat.locked"))));
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
|
||||
if (!plugin.getChatLockManager().isChatLocked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (player.hasPermission("lohub.chatlock.bypass")) {
|
||||
return;
|
||||
}
|
||||
|
||||
String command = event.getMessage().toLowerCase().substring(1);
|
||||
String baseCommand = command.split(" ")[0];
|
||||
|
||||
if (isBlockedCommand(baseCommand)) {
|
||||
event.setCancelled(true);
|
||||
player.sendMessage(Component.text(TextUtil.colorize(plugin.getConfigManager().getMessage("chat.locked"))));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isBlockedCommand(String command) {
|
||||
return BLOCKED_COMMANDS.stream().anyMatch(blocked -> command.equals(blocked));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.loki.lohub.listeners;
|
||||
|
||||
import com.loki.lohub.LoHub;
|
||||
import com.loki.lohub.managers.CustomCommandManager;
|
||||
import com.loki.lohub.utils.TextUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
|
||||
public class CustomCommandListener implements Listener {
|
||||
|
||||
private final LoHub plugin;
|
||||
|
||||
public CustomCommandListener(LoHub plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL)
|
||||
public void onPlayerCommand(PlayerCommandPreprocessEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
String message = event.getMessage().toLowerCase();
|
||||
|
||||
if (!message.startsWith("/")) {
|
||||
return;
|
||||
}
|
||||
|
||||
String command = message.substring(1).split(" ")[0];
|
||||
CustomCommandManager.CustomCommand customCommand = plugin.getCustomCommandManager().getCommand(command);
|
||||
|
||||
if (customCommand == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
if (customCommand.permission() != null && !customCommand.permission().isEmpty()) {
|
||||
if (!player.hasPermission(customCommand.permission())) {
|
||||
player.sendMessage(TextUtil.colorize(plugin.getConfig().getString("messages.no-permission")));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getActionManager().executeActions(player, customCommand.actions(), false);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,22 @@
|
|||
package com.loki.lohub.listeners;
|
||||
|
||||
import com.loki.lohub.LoHub;
|
||||
import org.bukkit.GameMode;
|
||||
import com.loki.lohub.common.ConfigHelper;
|
||||
import com.loki.lohub.common.GameModeHelper;
|
||||
import com.loki.lohub.common.LaunchHelper;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.event.player.PlayerToggleFlightEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DoubleJumpListener implements Listener {
|
||||
|
||||
private static final String CONFIG_PATH = "double_jump";
|
||||
private static final String COOLDOWN_KEY = "double_jump";
|
||||
|
||||
private final LoHub plugin;
|
||||
|
||||
public DoubleJumpListener(LoHub plugin) {
|
||||
|
|
@ -21,13 +25,13 @@ public class DoubleJumpListener implements Listener {
|
|||
|
||||
@EventHandler
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
if (!plugin.getConfig().getBoolean("double_jump.enabled", true)) {
|
||||
if (!ConfigHelper.isEnabled(plugin.getConfig(), CONFIG_PATH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
|
||||
if (GameModeHelper.isCreativeOrSpectator(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -41,38 +45,45 @@ public class DoubleJumpListener implements Listener {
|
|||
|
||||
@EventHandler
|
||||
public void onPlayerToggleFlight(PlayerToggleFlightEvent event) {
|
||||
if (!plugin.getConfig().getBoolean("double_jump.enabled", true)) {
|
||||
if (!ConfigHelper.isEnabled(plugin.getConfig(), CONFIG_PATH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
|
||||
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
|
||||
if (GameModeHelper.isCreativeOrSpectator(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getCooldownManager().hasCooldown("double_jump", player.getUniqueId())) {
|
||||
event.setCancelled(true);
|
||||
player.setAllowFlight(false);
|
||||
player.setFlying(false);
|
||||
if (plugin.getCooldownManager().hasCooldown(COOLDOWN_KEY, player.getUniqueId())) {
|
||||
cancelFlight(event, player);
|
||||
return;
|
||||
}
|
||||
|
||||
cancelFlight(event, player);
|
||||
performDoubleJump(player);
|
||||
}
|
||||
|
||||
private void cancelFlight(PlayerToggleFlightEvent event, Player player) {
|
||||
event.setCancelled(true);
|
||||
player.setAllowFlight(false);
|
||||
player.setFlying(false);
|
||||
}
|
||||
|
||||
double power = plugin.getConfig().getDouble("double_jump.launch_power", 1.0);
|
||||
double powerY = plugin.getConfig().getDouble("double_jump.launch_power_y", 0.9);
|
||||
private void performDoubleJump(Player player) {
|
||||
double power = ConfigHelper.getPower(plugin.getConfig(), CONFIG_PATH, "launch_power", 1.0);
|
||||
double powerY = ConfigHelper.getPower(plugin.getConfig(), CONFIG_PATH, "launch_power_y", 0.9);
|
||||
|
||||
Vector velocity = player.getLocation().getDirection().multiply(power);
|
||||
velocity.setY(powerY);
|
||||
player.setVelocity(velocity);
|
||||
LaunchHelper.launch(player, power, powerY);
|
||||
|
||||
int cooldown = plugin.getConfig().getInt("double_jump.cooldown", 3);
|
||||
plugin.getCooldownManager().setCooldown("double_jump", player.getUniqueId(), cooldown);
|
||||
int cooldown = ConfigHelper.getCooldown(plugin.getConfig(), CONFIG_PATH, 3);
|
||||
plugin.getCooldownManager().setCooldown(COOLDOWN_KEY, player.getUniqueId(), cooldown);
|
||||
|
||||
List<String> actions = plugin.getConfig().getStringList("double_jump.actions");
|
||||
executeActions(player);
|
||||
}
|
||||
|
||||
private void executeActions(Player player) {
|
||||
List<String> actions = plugin.getConfig().getStringList(CONFIG_PATH + ".actions");
|
||||
if (!actions.isEmpty()) {
|
||||
plugin.getActionManager().executeActions(player, actions, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,11 @@ import org.bukkit.event.block.BlockBreakEvent;
|
|||
import org.bukkit.event.block.BlockPlaceEvent;
|
||||
import org.bukkit.event.entity.EntityDamageByEntityEvent;
|
||||
import org.bukkit.event.entity.FoodLevelChangeEvent;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerPickupItemEvent;
|
||||
import org.bukkit.event.player.PlayerSwapHandItemsEvent;
|
||||
|
||||
public class HubProtectionListener implements Listener {
|
||||
|
||||
|
|
@ -131,4 +133,38 @@ public class HubProtectionListener implements Listener {
|
|||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerSwapHandItems(PlayerSwapHandItemsEvent event) {
|
||||
if (!plugin.getConfig().getBoolean("world_settings.disable_off_hand_swap", true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
if (player.hasPermission("lohub.bypass.protection")) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
if (!plugin.getConfig().getBoolean("world_settings.disable_off_hand_swap", true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(event.getWhoClicked() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = (Player) event.getWhoClicked();
|
||||
if (player.hasPermission("lohub.bypass.protection")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getRawSlot() != event.getSlot() && event.getSlot() == 40) {
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,21 @@
|
|||
package com.loki.lohub.listeners;
|
||||
|
||||
import com.loki.lohub.LoHub;
|
||||
import com.loki.lohub.common.ConfigHelper;
|
||||
import com.loki.lohub.common.LaunchHelper;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class LaunchpadListener implements Listener {
|
||||
|
||||
private static final String CONFIG_PATH = "launchpad";
|
||||
|
||||
private final LoHub plugin;
|
||||
|
||||
public LaunchpadListener(LoHub plugin) {
|
||||
|
|
@ -21,46 +24,59 @@ public class LaunchpadListener implements Listener {
|
|||
|
||||
@EventHandler
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
if (!plugin.getConfig().getBoolean("launchpad.enabled", true)) {
|
||||
if (!ConfigHelper.isEnabled(plugin.getConfig(), CONFIG_PATH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.getFrom().getBlockX() == event.getTo().getBlockX()
|
||||
&& event.getFrom().getBlockY() == event.getTo().getBlockY()
|
||||
&& event.getFrom().getBlockZ() == event.getTo().getBlockZ()) {
|
||||
if (!hasMoved(event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = event.getPlayer();
|
||||
Block block = player.getLocation().getBlock();
|
||||
|
||||
String topBlockStr = plugin.getConfig().getString("launchpad.top_block", "STONE_PRESSURE_PLATE");
|
||||
String bottomBlockStr = plugin.getConfig().getString("launchpad.bottom_block", "REDSTONE_BLOCK");
|
||||
|
||||
Material topMaterial = Material.getMaterial(topBlockStr);
|
||||
Material bottomMaterial = Material.getMaterial(bottomBlockStr);
|
||||
|
||||
if (topMaterial == null || bottomMaterial == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (block.getType() == topMaterial) {
|
||||
Block below = block.getRelative(0, -1, 0);
|
||||
if (below.getType() == bottomMaterial) {
|
||||
if (isLaunchpad(block)) {
|
||||
launchPlayer(player);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasMoved(PlayerMoveEvent event) {
|
||||
return event.getFrom().getBlockX() != event.getTo().getBlockX()
|
||||
|| event.getFrom().getBlockY() != event.getTo().getBlockY()
|
||||
|| event.getFrom().getBlockZ() != event.getTo().getBlockZ();
|
||||
}
|
||||
|
||||
private boolean isLaunchpad(Block block) {
|
||||
Material topMaterial = getMaterial("top_block", "STONE_PRESSURE_PLATE");
|
||||
Material bottomMaterial = getMaterial("bottom_block", "REDSTONE_BLOCK");
|
||||
|
||||
if (topMaterial == null || bottomMaterial == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (block.getType() != topMaterial) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Block below = block.getRelative(0, -1, 0);
|
||||
return below.getType() == bottomMaterial;
|
||||
}
|
||||
|
||||
private Material getMaterial(String key, String defaultValue) {
|
||||
String materialName = plugin.getConfig().getString(CONFIG_PATH + "." + key, defaultValue);
|
||||
return Material.getMaterial(materialName);
|
||||
}
|
||||
|
||||
private void launchPlayer(Player player) {
|
||||
double power = plugin.getConfig().getDouble("launchpad.launch_power", 3.0);
|
||||
double powerY = plugin.getConfig().getDouble("launchpad.launch_power_y", 1.0);
|
||||
double power = ConfigHelper.getPower(plugin.getConfig(), CONFIG_PATH, "launch_power", 3.0);
|
||||
double powerY = ConfigHelper.getPower(plugin.getConfig(), CONFIG_PATH, "launch_power_y", 1.0);
|
||||
|
||||
Vector velocity = player.getLocation().getDirection().multiply(power);
|
||||
velocity.setY(powerY);
|
||||
player.setVelocity(velocity);
|
||||
LaunchHelper.launch(player, power, powerY);
|
||||
executeActions(player);
|
||||
}
|
||||
|
||||
List<String> actions = plugin.getConfig().getStringList("launchpad.actions");
|
||||
private void executeActions(Player player) {
|
||||
List<String> actions = plugin.getConfig().getStringList(CONFIG_PATH + ".actions");
|
||||
if (!actions.isEmpty()) {
|
||||
plugin.getActionManager().executeActions(player, actions, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
package com.loki.lohub.listeners;
|
||||
|
||||
import com.loki.lohub.LoHub;
|
||||
import com.loki.lohub.utils.TextUtil;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Color;
|
||||
import org.bukkit.FireworkEffect;
|
||||
import com.loki.lohub.features.FireworkHandler;
|
||||
import com.loki.lohub.features.JoinMessageHandler;
|
||||
import com.loki.lohub.features.JoinSettingsHandler;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Firework;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
|
|
@ -16,37 +13,11 @@ import org.bukkit.event.entity.PlayerDeathEvent;
|
|||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
import org.bukkit.event.player.PlayerRespawnEvent;
|
||||
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) {
|
||||
|
|
@ -61,10 +32,10 @@ public class PlayerJoinListener implements Listener {
|
|||
return;
|
||||
}
|
||||
|
||||
handleJoinMessage(event, player);
|
||||
handleJoinSettings(player);
|
||||
handleJoinEvents(player);
|
||||
handleFirework(player);
|
||||
JoinMessageHandler.handleJoin(event, player, plugin.getConfig());
|
||||
JoinSettingsHandler.apply(player, plugin);
|
||||
executeJoinActions(player);
|
||||
FireworkHandler.spawn(player, plugin.getConfig());
|
||||
|
||||
plugin.getScoreboardManager().setScoreboard(player, true);
|
||||
plugin.getTablistManager().setTablist(player);
|
||||
|
|
@ -81,14 +52,7 @@ public class PlayerJoinListener implements Listener {
|
|||
plugin.getPlayerHiderManager().removePlayer(player);
|
||||
plugin.getScoreboardManager().removePlayer(player);
|
||||
|
||||
if (plugin.getConfig().getBoolean("join_leave_messages.enabled", true)) {
|
||||
String quitMessage = plugin.getConfig().getString("join_leave_messages.quit_message", "");
|
||||
if (quitMessage.isEmpty()) {
|
||||
event.quitMessage(null);
|
||||
} else {
|
||||
event.quitMessage(Component.text(TextUtil.colorize(quitMessage.replace("%player%", player.getName()))));
|
||||
}
|
||||
}
|
||||
JoinMessageHandler.handleQuit(event, player, plugin.getConfig());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
|
|
@ -118,100 +82,13 @@ public class PlayerJoinListener implements Listener {
|
|||
}
|
||||
}
|
||||
|
||||
private void handleJoinMessage(PlayerJoinEvent event, Player player) {
|
||||
if (plugin.getConfig().getBoolean("join_leave_messages.enabled", true)) {
|
||||
String joinMessage = plugin.getConfig().getString("join_leave_messages.join_message", "");
|
||||
if (joinMessage.isEmpty()) {
|
||||
event.joinMessage(null);
|
||||
} else {
|
||||
event.joinMessage(Component.text(TextUtil.colorize(joinMessage.replace("%player%", player.getName()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleJoinSettings(Player player) {
|
||||
if (plugin.getConfig().getBoolean("join_settings.spawn_join", true)) {
|
||||
Location spawn = plugin.getSpawnManager().getSpawn();
|
||||
if (spawn != null) {
|
||||
player.teleport(spawn);
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.getConfig().getBoolean("join_settings.heal", true)) {
|
||||
player.setHealth(player.getMaxHealth());
|
||||
player.setFoodLevel(20);
|
||||
player.setSaturation(20);
|
||||
}
|
||||
|
||||
if (plugin.getConfig().getBoolean("join_settings.extinguish", true)) {
|
||||
player.setFireTicks(0);
|
||||
}
|
||||
|
||||
if (plugin.getConfig().getBoolean("join_settings.clear_inventory", false)) {
|
||||
player.getInventory().clear();
|
||||
}
|
||||
|
||||
plugin.getHotbarManager().giveItems(player);
|
||||
plugin.getPlayerHiderManager().giveItem(player);
|
||||
}
|
||||
|
||||
private void handleJoinEvents(Player player) {
|
||||
private void executeJoinActions(Player player) {
|
||||
List<String> actions = plugin.getConfig().getStringList("join_events");
|
||||
if (!actions.isEmpty()) {
|
||||
plugin.getActionManager().executeActions(player, actions, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleFirework(Player player) {
|
||||
if (!plugin.getConfig().getBoolean("join_settings.firework.enabled", false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean firstJoinOnly = plugin.getConfig().getBoolean("join_settings.firework.first_join_only", true);
|
||||
if (firstJoinOnly && player.hasPlayedBefore()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Location loc = player.getLocation();
|
||||
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");
|
||||
FireworkEffect.Type type;
|
||||
try {
|
||||
type = FireworkEffect.Type.valueOf(typeStr);
|
||||
} catch (IllegalArgumentException e) {
|
||||
type = FireworkEffect.Type.BALL_LARGE;
|
||||
}
|
||||
|
||||
List<Color> colors = new ArrayList<>();
|
||||
for (String colorStr : plugin.getConfig().getStringList("join_settings.firework.colors")) {
|
||||
Color color = parseColor(colorStr);
|
||||
if (color != null) {
|
||||
colors.add(color);
|
||||
}
|
||||
}
|
||||
|
||||
if (colors.isEmpty()) {
|
||||
colors.add(Color.AQUA);
|
||||
}
|
||||
|
||||
FireworkEffect effect = FireworkEffect.builder()
|
||||
.with(type)
|
||||
.withColor(colors)
|
||||
.flicker(plugin.getConfig().getBoolean("join_settings.firework.flicker", true))
|
||||
.trail(plugin.getConfig().getBoolean("join_settings.firework.trail", true))
|
||||
.build();
|
||||
|
||||
meta.addEffect(effect);
|
||||
meta.setPower(plugin.getConfig().getInt("join_settings.firework.power", 1));
|
||||
firework.setFireworkMeta(meta);
|
||||
}
|
||||
|
||||
private Color parseColor(String colorStr) {
|
||||
return COLOR_MAP.get(colorStr.toUpperCase());
|
||||
}
|
||||
|
||||
private boolean isWorldDisabled(String worldName) {
|
||||
List<String> disabledWorlds = plugin.getConfig().getStringList("disabled-worlds.worlds");
|
||||
boolean invert = plugin.getConfig().getBoolean("disabled-worlds.invert", false);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.loki.lohub.managers;
|
||||
|
||||
import com.loki.lohub.LoHub;
|
||||
import com.loki.lohub.utils.PlaceholderUtil;
|
||||
import com.loki.lohub.utils.TextUtil;
|
||||
import com.loki.lohub.common.ConfigHelper;
|
||||
import com.loki.lohub.common.TextFormatter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Sound;
|
||||
|
|
@ -14,6 +14,8 @@ import java.util.List;
|
|||
|
||||
public class AnnouncementManager {
|
||||
|
||||
private static final String CONFIG_PATH = "announcements";
|
||||
|
||||
private final LoHub plugin;
|
||||
private final List<Announcement> announcements = new ArrayList<>();
|
||||
private int currentIndex = 0;
|
||||
|
|
@ -26,21 +28,21 @@ public class AnnouncementManager {
|
|||
|
||||
private void loadAnnouncements() {
|
||||
announcements.clear();
|
||||
ConfigurationSection section = plugin.getConfig().getConfigurationSection("announcements.announcements");
|
||||
ConfigurationSection section = plugin.getConfig().getConfigurationSection(CONFIG_PATH + ".announcements");
|
||||
if (section == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String key : section.getKeys(false)) {
|
||||
section.getKeys(false).forEach(key -> {
|
||||
List<String> messages = section.getStringList(key);
|
||||
if (!messages.isEmpty()) {
|
||||
announcements.add(new Announcement(key, messages));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void start() {
|
||||
if (!plugin.getConfig().getBoolean("announcements.enabled", false)) {
|
||||
if (!ConfigHelper.isEnabled(plugin.getConfig(), CONFIG_PATH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -48,7 +50,7 @@ public class AnnouncementManager {
|
|||
return;
|
||||
}
|
||||
|
||||
int delay = plugin.getConfig().getInt("announcements.delay", 60) * 20;
|
||||
int delay = plugin.getConfig().getInt(CONFIG_PATH + ".delay", 60) * 20;
|
||||
taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, this::broadcast, delay, delay);
|
||||
}
|
||||
|
||||
|
|
@ -60,8 +62,7 @@ public class AnnouncementManager {
|
|||
}
|
||||
|
||||
private void broadcast() {
|
||||
int requiredPlayers = plugin.getConfig().getInt("announcements.required_players", 1);
|
||||
if (Bukkit.getOnlinePlayers().size() < requiredPlayers) {
|
||||
if (!hasEnoughPlayers()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -69,25 +70,40 @@ public class AnnouncementManager {
|
|||
return;
|
||||
}
|
||||
|
||||
Announcement announcement = announcements.get(currentIndex);
|
||||
currentIndex = (currentIndex + 1) % announcements.size();
|
||||
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
for (String message : announcement.messages()) {
|
||||
String formatted = PlaceholderUtil.parse(message, player);
|
||||
player.sendMessage(Component.text(TextUtil.colorize(formatted)));
|
||||
Announcement announcement = getNextAnnouncement();
|
||||
Bukkit.getOnlinePlayers().forEach(player -> sendAnnouncement(player, announcement));
|
||||
}
|
||||
|
||||
if (plugin.getConfig().getBoolean("announcements.sound.enabled", true)) {
|
||||
private boolean hasEnoughPlayers() {
|
||||
int required = plugin.getConfig().getInt(CONFIG_PATH + ".required_players", 1);
|
||||
return Bukkit.getOnlinePlayers().size() >= required;
|
||||
}
|
||||
|
||||
private Announcement getNextAnnouncement() {
|
||||
Announcement announcement = announcements.get(currentIndex);
|
||||
currentIndex = (currentIndex + 1) % announcements.size();
|
||||
return announcement;
|
||||
}
|
||||
|
||||
private void sendAnnouncement(Player player, Announcement announcement) {
|
||||
announcement.messages().forEach(message -> {
|
||||
String formatted = TextFormatter.format(message, player);
|
||||
player.sendMessage(Component.text(formatted));
|
||||
});
|
||||
|
||||
if (shouldPlaySound()) {
|
||||
playSound(player);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldPlaySound() {
|
||||
return plugin.getConfig().getBoolean(CONFIG_PATH + ".sound.enabled", true);
|
||||
}
|
||||
|
||||
private void playSound(Player player) {
|
||||
String soundStr = plugin.getConfig().getString("announcements.sound.value", "BLOCK_NOTE_BLOCK_PLING");
|
||||
float volume = (float) plugin.getConfig().getDouble("announcements.sound.volume", 1.0);
|
||||
float pitch = (float) plugin.getConfig().getDouble("announcements.sound.pitch", 1.0);
|
||||
String soundStr = plugin.getConfig().getString(CONFIG_PATH + ".sound.value", "BLOCK_NOTE_BLOCK_PLING");
|
||||
float volume = (float) plugin.getConfig().getDouble(CONFIG_PATH + ".sound.volume", 1.0);
|
||||
float pitch = (float) plugin.getConfig().getDouble(CONFIG_PATH + ".sound.pitch", 1.0);
|
||||
|
||||
try {
|
||||
Sound sound = Sound.valueOf(soundStr);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
package com.loki.lohub.managers;
|
||||
|
||||
import com.loki.lohub.LoHub;
|
||||
|
||||
public class ChatLockManager {
|
||||
|
||||
private final LoHub plugin;
|
||||
|
||||
public ChatLockManager(LoHub plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public boolean isChatLocked() {
|
||||
return plugin.getConfigManager().getData().getBoolean("chat_locked", false);
|
||||
}
|
||||
|
||||
public void setChatLocked(boolean locked) {
|
||||
plugin.getConfigManager().getData().set("chat_locked", locked);
|
||||
plugin.getConfigManager().saveData();
|
||||
}
|
||||
|
||||
public void toggle() {
|
||||
setChatLocked(!isChatLocked());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package com.loki.lohub.managers;
|
||||
|
||||
import com.loki.lohub.LoHub;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CustomCommandManager {
|
||||
|
||||
private final LoHub plugin;
|
||||
private final Map<String, CustomCommand> commands = new HashMap<>();
|
||||
|
||||
public CustomCommandManager(LoHub plugin) {
|
||||
this.plugin = plugin;
|
||||
loadCommands();
|
||||
}
|
||||
|
||||
private void loadCommands() {
|
||||
commands.clear();
|
||||
ConfigurationSection section = plugin.getConfigManager().getCommands().getConfigurationSection("custom_commands");
|
||||
if (section == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String key : section.getKeys(false)) {
|
||||
ConfigurationSection cmdSection = section.getConfigurationSection(key);
|
||||
if (cmdSection == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
List<String> aliases = cmdSection.getStringList("aliases");
|
||||
String permission = cmdSection.getString("permission");
|
||||
List<String> actions = cmdSection.getStringList("actions");
|
||||
|
||||
if (aliases.isEmpty() || actions.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CustomCommand cmd = new CustomCommand(key, aliases, permission, actions);
|
||||
for (String alias : aliases) {
|
||||
commands.put(alias.toLowerCase(), cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CustomCommand getCommand(String alias) {
|
||||
return commands.get(alias.toLowerCase());
|
||||
}
|
||||
|
||||
public boolean hasCommand(String alias) {
|
||||
return commands.containsKey(alias.toLowerCase());
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
loadCommands();
|
||||
}
|
||||
|
||||
public record CustomCommand(String name, List<String> aliases, String permission, List<String> actions) {
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,8 @@ import java.util.Map;
|
|||
|
||||
public class HotbarManager {
|
||||
|
||||
private static final String CONFIG_PATH = "custom_join_items";
|
||||
|
||||
private final LoHub plugin;
|
||||
private final Map<Integer, HotbarItem> items = new HashMap<>();
|
||||
|
||||
|
|
@ -23,46 +25,56 @@ public class HotbarManager {
|
|||
|
||||
private void loadItems() {
|
||||
items.clear();
|
||||
ConfigurationSection section = plugin.getConfig().getConfigurationSection("custom_join_items.items");
|
||||
ConfigurationSection section = plugin.getConfig().getConfigurationSection(CONFIG_PATH + ".items");
|
||||
if (section == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String key : section.getKeys(false)) {
|
||||
ConfigurationSection itemSection = section.getConfigurationSection(key);
|
||||
if (itemSection == null) {
|
||||
continue;
|
||||
loadItem(section.getConfigurationSection(key));
|
||||
}
|
||||
}
|
||||
|
||||
Material material = Material.getMaterial(itemSection.getString("material", "STONE"));
|
||||
private void loadItem(ConfigurationSection itemSection) {
|
||||
if (itemSection == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Material material = getMaterial(itemSection);
|
||||
if (material == null) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
int slot = itemSection.getInt("slot", 0);
|
||||
int amount = itemSection.getInt("amount", 1);
|
||||
String displayName = itemSection.getString("display_name", "");
|
||||
List<String> lore = itemSection.getStringList("lore");
|
||||
ItemStack item = buildItem(itemSection, material);
|
||||
List<String> actions = itemSection.getStringList("actions");
|
||||
|
||||
ItemStack item = new ItemBuilder(material)
|
||||
items.put(slot, new HotbarItem(item, actions));
|
||||
}
|
||||
|
||||
private Material getMaterial(ConfigurationSection section) {
|
||||
String materialName = section.getString("material", "STONE");
|
||||
return Material.getMaterial(materialName);
|
||||
}
|
||||
|
||||
private ItemStack buildItem(ConfigurationSection section, Material material) {
|
||||
int amount = section.getInt("amount", 1);
|
||||
String displayName = section.getString("display_name", "");
|
||||
List<String> lore = section.getStringList("lore");
|
||||
|
||||
return new ItemBuilder(material)
|
||||
.amount(amount)
|
||||
.name(displayName)
|
||||
.lore(lore)
|
||||
.build();
|
||||
|
||||
items.put(slot, new HotbarItem(item, actions));
|
||||
}
|
||||
}
|
||||
|
||||
public void giveItems(Player player) {
|
||||
if (!plugin.getConfig().getBoolean("custom_join_items.enabled", false)) {
|
||||
if (!isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Map.Entry<Integer, HotbarItem> entry : items.entrySet()) {
|
||||
player.getInventory().setItem(entry.getKey(), entry.getValue().item());
|
||||
}
|
||||
items.forEach((slot, item) -> player.getInventory().setItem(slot, item.item()));
|
||||
}
|
||||
|
||||
public void handleClick(Player player, int slot) {
|
||||
|
|
@ -82,6 +94,10 @@ public class HotbarManager {
|
|||
loadItems();
|
||||
}
|
||||
|
||||
private boolean isEnabled() {
|
||||
return plugin.getConfig().getBoolean(CONFIG_PATH + ".enabled", false);
|
||||
}
|
||||
|
||||
private record HotbarItem(ItemStack item, List<String> actions) {
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ import java.util.UUID;
|
|||
|
||||
public class PlayerHiderManager {
|
||||
|
||||
private static final String CONFIG_PATH = "player_hider";
|
||||
private static final String HIDDEN_PATH = CONFIG_PATH + ".hidden";
|
||||
private static final String NOT_HIDDEN_PATH = CONFIG_PATH + ".not_hidden";
|
||||
|
||||
private final LoHub plugin;
|
||||
private final Set<UUID> hiddenPlayers = new HashSet<>();
|
||||
|
||||
|
|
@ -22,23 +26,18 @@ public class PlayerHiderManager {
|
|||
}
|
||||
|
||||
public void giveItem(Player player) {
|
||||
if (!plugin.getConfig().getBoolean("player_hider.enabled", true)) {
|
||||
if (!isEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int slot = plugin.getConfig().getInt("player_hider.slot", 8);
|
||||
player.getInventory().setItem(slot, getItem(player));
|
||||
player.getInventory().setItem(getSlot(), getItem(player));
|
||||
}
|
||||
|
||||
public ItemStack getItem(Player player) {
|
||||
boolean hidden = hiddenPlayers.contains(player.getUniqueId());
|
||||
String path = hidden ? "player_hider.hidden" : "player_hider.not_hidden";
|
||||
|
||||
Material material = Material.getMaterial(plugin.getConfig().getString(path + ".material", "LIME_DYE"));
|
||||
if (material == null) {
|
||||
material = Material.LIME_DYE;
|
||||
}
|
||||
boolean hidden = isHidden(player);
|
||||
String path = hidden ? HIDDEN_PATH : NOT_HIDDEN_PATH;
|
||||
|
||||
Material material = getMaterial(path);
|
||||
int amount = plugin.getConfig().getInt(path + ".amount", 1);
|
||||
String displayName = plugin.getConfig().getString(path + ".display_name", "");
|
||||
List<String> lore = plugin.getConfig().getStringList(path + ".lore");
|
||||
|
|
@ -51,7 +50,7 @@ public class PlayerHiderManager {
|
|||
}
|
||||
|
||||
public void toggle(Player player) {
|
||||
if (hiddenPlayers.contains(player.getUniqueId())) {
|
||||
if (isHidden(player)) {
|
||||
showPlayers(player);
|
||||
} else {
|
||||
hidePlayers(player);
|
||||
|
|
@ -62,33 +61,53 @@ public class PlayerHiderManager {
|
|||
|
||||
private void hidePlayers(Player player) {
|
||||
hiddenPlayers.add(player.getUniqueId());
|
||||
for (Player online : Bukkit.getOnlinePlayers()) {
|
||||
if (!online.equals(player)) {
|
||||
player.hidePlayer(plugin, online);
|
||||
}
|
||||
}
|
||||
applyVisibility(player, false);
|
||||
}
|
||||
|
||||
private void showPlayers(Player player) {
|
||||
hiddenPlayers.remove(player.getUniqueId());
|
||||
applyVisibility(player, true);
|
||||
}
|
||||
|
||||
private void applyVisibility(Player player, boolean visible) {
|
||||
for (Player online : Bukkit.getOnlinePlayers()) {
|
||||
if (!online.equals(player)) {
|
||||
if (visible) {
|
||||
player.showPlayer(plugin, online);
|
||||
} else {
|
||||
player.hidePlayer(plugin, online);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateItem(Player player) {
|
||||
int slot = plugin.getConfig().getInt("player_hider.slot", 8);
|
||||
player.getInventory().setItem(slot, getItem(player));
|
||||
player.getInventory().setItem(getSlot(), getItem(player));
|
||||
}
|
||||
|
||||
public boolean isPlayerHiderSlot(int slot) {
|
||||
return plugin.getConfig().getBoolean("player_hider.enabled", true)
|
||||
&& slot == plugin.getConfig().getInt("player_hider.slot", 8);
|
||||
return isEnabled() && slot == getSlot();
|
||||
}
|
||||
|
||||
public void removePlayer(Player player) {
|
||||
hiddenPlayers.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
private boolean isEnabled() {
|
||||
return plugin.getConfig().getBoolean(CONFIG_PATH + ".enabled", true);
|
||||
}
|
||||
|
||||
private int getSlot() {
|
||||
return plugin.getConfig().getInt(CONFIG_PATH + ".slot", 8);
|
||||
}
|
||||
|
||||
private boolean isHidden(Player player) {
|
||||
return hiddenPlayers.contains(player.getUniqueId());
|
||||
}
|
||||
|
||||
private Material getMaterial(String path) {
|
||||
String materialName = plugin.getConfig().getString(path + ".material", "LIME_DYE");
|
||||
Material material = Material.getMaterial(materialName);
|
||||
return material != null ? material : Material.LIME_DYE;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.loki.lohub.managers;
|
||||
|
||||
import com.loki.lohub.LoHub;
|
||||
import com.loki.lohub.utils.PlaceholderUtil;
|
||||
import com.loki.lohub.utils.TextUtil;
|
||||
import com.loki.lohub.common.ConfigHelper;
|
||||
import com.loki.lohub.common.TextFormatter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
|
@ -18,6 +18,9 @@ import java.util.UUID;
|
|||
|
||||
public class ScoreboardManager {
|
||||
|
||||
private static final String CONFIG_PATH = "scoreboard";
|
||||
private static final String OBJECTIVE_NAME = "lohub";
|
||||
|
||||
private final LoHub plugin;
|
||||
private final Map<UUID, Scoreboard> scoreboards = new HashMap<>();
|
||||
private int taskId = -1;
|
||||
|
|
@ -27,12 +30,12 @@ public class ScoreboardManager {
|
|||
}
|
||||
|
||||
public void start() {
|
||||
if (!plugin.getConfig().getBoolean("scoreboard.enabled", false)) {
|
||||
if (!ConfigHelper.isEnabled(plugin.getConfig(), CONFIG_PATH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getConfig().getBoolean("scoreboard.refresh.enabled", true)) {
|
||||
int rate = plugin.getConfig().getInt("scoreboard.refresh.rate", 200);
|
||||
if (shouldRefresh()) {
|
||||
int rate = plugin.getConfig().getInt(CONFIG_PATH + ".refresh.rate", 200);
|
||||
taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, this::updateAll, 0L, rate);
|
||||
}
|
||||
}
|
||||
|
|
@ -46,12 +49,12 @@ public class ScoreboardManager {
|
|||
}
|
||||
|
||||
public void setScoreboard(Player player, boolean delayed) {
|
||||
if (!plugin.getConfig().getBoolean("scoreboard.enabled", false)) {
|
||||
if (!ConfigHelper.isEnabled(plugin.getConfig(), CONFIG_PATH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (delayed) {
|
||||
int delay = plugin.getConfig().getInt("scoreboard.display_delay.server_enter", 60);
|
||||
int delay = plugin.getConfig().getInt(CONFIG_PATH + ".display_delay.server_enter", 60);
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> createScoreboard(player), delay);
|
||||
} else {
|
||||
createScoreboard(player);
|
||||
|
|
@ -60,7 +63,7 @@ public class ScoreboardManager {
|
|||
|
||||
private void createScoreboard(Player player) {
|
||||
Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
|
||||
Objective objective = scoreboard.registerNewObjective("lohub", "dummy", Component.text(""));
|
||||
Objective objective = scoreboard.registerNewObjective(OBJECTIVE_NAME, "dummy", Component.text(""));
|
||||
|
||||
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
|
||||
updateScoreboard(player, scoreboard, objective);
|
||||
|
|
@ -70,43 +73,56 @@ public class ScoreboardManager {
|
|||
}
|
||||
|
||||
private void updateScoreboard(Player player, Scoreboard scoreboard, Objective objective) {
|
||||
String title = plugin.getConfig().getString("scoreboard.title", "");
|
||||
title = PlaceholderUtil.parse(title, player);
|
||||
objective.displayName(Component.text(TextUtil.colorize(title)));
|
||||
updateTitle(player, objective);
|
||||
updateLines(player, scoreboard, objective);
|
||||
}
|
||||
|
||||
List<String> lines = plugin.getConfig().getStringList("scoreboard.lines");
|
||||
private void updateTitle(Player player, Objective objective) {
|
||||
String title = plugin.getConfig().getString(CONFIG_PATH + ".title", "");
|
||||
objective.displayName(Component.text(TextFormatter.format(title, player)));
|
||||
}
|
||||
|
||||
private void updateLines(Player player, Scoreboard scoreboard, Objective objective) {
|
||||
List<String> lines = plugin.getConfig().getStringList(CONFIG_PATH + ".lines");
|
||||
int score = lines.size();
|
||||
|
||||
for (String line : lines) {
|
||||
line = PlaceholderUtil.parse(line, player);
|
||||
line = TextUtil.colorize(line);
|
||||
|
||||
String formatted = TextFormatter.format(line, player);
|
||||
String teamName = "line_" + score;
|
||||
Team team = scoreboard.getTeam(teamName);
|
||||
if (team == null) {
|
||||
team = scoreboard.registerNewTeam(teamName);
|
||||
team.addEntry(teamName);
|
||||
}
|
||||
|
||||
team.prefix(Component.text(line));
|
||||
Team team = getOrCreateTeam(scoreboard, teamName);
|
||||
team.prefix(Component.text(formatted));
|
||||
objective.getScore(teamName).setScore(score);
|
||||
score--;
|
||||
}
|
||||
}
|
||||
|
||||
private Team getOrCreateTeam(Scoreboard scoreboard, String teamName) {
|
||||
Team team = scoreboard.getTeam(teamName);
|
||||
if (team == null) {
|
||||
team = scoreboard.registerNewTeam(teamName);
|
||||
team.addEntry(teamName);
|
||||
}
|
||||
return team;
|
||||
}
|
||||
|
||||
private void updateAll() {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
Scoreboard scoreboard = scoreboards.get(player.getUniqueId());
|
||||
if (scoreboard != null) {
|
||||
Objective objective = scoreboard.getObjective("lohub");
|
||||
scoreboards.forEach((uuid, scoreboard) -> {
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
if (player != null) {
|
||||
Objective objective = scoreboard.getObjective(OBJECTIVE_NAME);
|
||||
if (objective != null) {
|
||||
updateScoreboard(player, scoreboard, objective);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void removePlayer(Player player) {
|
||||
scoreboards.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
private boolean shouldRefresh() {
|
||||
return plugin.getConfig().getBoolean(CONFIG_PATH + ".refresh.enabled", true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,83 +4,56 @@ import com.loki.lohub.LoHub;
|
|||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class SpawnManager {
|
||||
|
||||
private final LoHub plugin;
|
||||
private final File spawnFile;
|
||||
private FileConfiguration spawnConfig;
|
||||
private Location spawnLocation;
|
||||
|
||||
public SpawnManager(LoHub plugin) {
|
||||
this.plugin = plugin;
|
||||
this.spawnFile = new File(plugin.getDataFolder(), "spawn.yml");
|
||||
loadSpawn();
|
||||
}
|
||||
|
||||
private void loadSpawn() {
|
||||
if (!spawnFile.exists()) {
|
||||
try {
|
||||
spawnFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Failed to create spawn.yml: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
spawnConfig = YamlConfiguration.loadConfiguration(spawnFile);
|
||||
|
||||
if (spawnConfig.contains("spawn")) {
|
||||
String worldName = spawnConfig.getString("spawn.world");
|
||||
double x = spawnConfig.getDouble("spawn.x");
|
||||
double y = spawnConfig.getDouble("spawn.y");
|
||||
double z = spawnConfig.getDouble("spawn.z");
|
||||
float yaw = (float) spawnConfig.getDouble("spawn.yaw");
|
||||
float pitch = (float) spawnConfig.getDouble("spawn.pitch");
|
||||
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (world != null) {
|
||||
spawnLocation = new Location(world, x, y, z, yaw, pitch);
|
||||
plugin.getLogger().info("Spawn loaded: " + worldName + " (" + x + ", " + y + ", " + z + ")");
|
||||
} else {
|
||||
plugin.getLogger().warning("World '" + worldName + "' not found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Location getSpawn() {
|
||||
return spawnLocation;
|
||||
String worldName = plugin.getConfigManager().getData().getString("spawn.world");
|
||||
if (worldName == null || worldName.equals("null")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
World world = Bukkit.getWorld(worldName);
|
||||
if (world == null) {
|
||||
plugin.getLogger().warning("World '" + worldName + "' not found!");
|
||||
return null;
|
||||
}
|
||||
|
||||
double x = plugin.getConfigManager().getData().getDouble("spawn.x");
|
||||
double y = plugin.getConfigManager().getData().getDouble("spawn.y");
|
||||
double z = plugin.getConfigManager().getData().getDouble("spawn.z");
|
||||
float yaw = (float) plugin.getConfigManager().getData().getDouble("spawn.yaw");
|
||||
float pitch = (float) plugin.getConfigManager().getData().getDouble("spawn.pitch");
|
||||
|
||||
return new Location(world, x, y, z, yaw, pitch);
|
||||
}
|
||||
|
||||
public void setSpawn(Location location) {
|
||||
this.spawnLocation = location;
|
||||
plugin.getConfigManager().getData().set("spawn.world", location.getWorld().getName());
|
||||
plugin.getConfigManager().getData().set("spawn.x", location.getX());
|
||||
plugin.getConfigManager().getData().set("spawn.y", location.getY());
|
||||
plugin.getConfigManager().getData().set("spawn.z", location.getZ());
|
||||
plugin.getConfigManager().getData().set("spawn.yaw", location.getYaw());
|
||||
plugin.getConfigManager().getData().set("spawn.pitch", location.getPitch());
|
||||
plugin.getConfigManager().saveData();
|
||||
|
||||
spawnConfig.set("spawn.world", location.getWorld().getName());
|
||||
spawnConfig.set("spawn.x", location.getX());
|
||||
spawnConfig.set("spawn.y", location.getY());
|
||||
spawnConfig.set("spawn.z", location.getZ());
|
||||
spawnConfig.set("spawn.yaw", location.getYaw());
|
||||
spawnConfig.set("spawn.pitch", location.getPitch());
|
||||
|
||||
try {
|
||||
spawnConfig.save(spawnFile);
|
||||
plugin.getLogger().info("Spawn set: " + location.getWorld().getName() +
|
||||
" (" + location.getBlockX() + ", " + location.getBlockY() + ", " + location.getBlockZ() + ")");
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Failed to save spawn.yml: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void teleportToSpawn(Player player) {
|
||||
if (spawnLocation == null) {
|
||||
Location spawn = getSpawn();
|
||||
if (spawn == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
player.teleport(spawnLocation);
|
||||
player.teleport(spawn);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
package com.loki.lohub.managers;
|
||||
|
||||
import com.loki.lohub.LoHub;
|
||||
import com.loki.lohub.utils.PlaceholderUtil;
|
||||
import com.loki.lohub.utils.TextUtil;
|
||||
import com.loki.lohub.common.ConfigHelper;
|
||||
import com.loki.lohub.common.TextFormatter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
|
@ -11,6 +11,8 @@ import java.util.List;
|
|||
|
||||
public class TablistManager {
|
||||
|
||||
private static final String CONFIG_PATH = "tablist";
|
||||
|
||||
private final LoHub plugin;
|
||||
private int taskId = -1;
|
||||
|
||||
|
|
@ -19,12 +21,12 @@ public class TablistManager {
|
|||
}
|
||||
|
||||
public void start() {
|
||||
if (!plugin.getConfig().getBoolean("tablist.enabled", false)) {
|
||||
if (!ConfigHelper.isEnabled(plugin.getConfig(), CONFIG_PATH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.getConfig().getBoolean("tablist.refresh.enabled", true)) {
|
||||
int rate = plugin.getConfig().getInt("tablist.refresh.rate", 400);
|
||||
if (shouldRefresh()) {
|
||||
int rate = plugin.getConfig().getInt(CONFIG_PATH + ".refresh.rate", 400);
|
||||
taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, this::updateAll, 0L, rate);
|
||||
}
|
||||
}
|
||||
|
|
@ -37,7 +39,7 @@ public class TablistManager {
|
|||
}
|
||||
|
||||
public void setTablist(Player player) {
|
||||
if (!plugin.getConfig().getBoolean("tablist.enabled", false)) {
|
||||
if (!ConfigHelper.isEnabled(plugin.getConfig(), CONFIG_PATH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -45,36 +47,25 @@ public class TablistManager {
|
|||
}
|
||||
|
||||
private void updateTablist(Player player) {
|
||||
List<String> headerLines = plugin.getConfig().getStringList("tablist.header");
|
||||
List<String> footerLines = plugin.getConfig().getStringList("tablist.footer");
|
||||
|
||||
StringBuilder header = new StringBuilder();
|
||||
for (int i = 0; i < headerLines.size(); i++) {
|
||||
String line = PlaceholderUtil.parse(headerLines.get(i), player);
|
||||
header.append(TextUtil.colorize(line));
|
||||
if (i < headerLines.size() - 1) {
|
||||
header.append("\n");
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder footer = new StringBuilder();
|
||||
for (int i = 0; i < footerLines.size(); i++) {
|
||||
String line = PlaceholderUtil.parse(footerLines.get(i), player);
|
||||
footer.append(TextUtil.colorize(line));
|
||||
if (i < footerLines.size() - 1) {
|
||||
footer.append("\n");
|
||||
}
|
||||
}
|
||||
String header = formatLines(CONFIG_PATH + ".header", player);
|
||||
String footer = formatLines(CONFIG_PATH + ".footer", player);
|
||||
|
||||
player.sendPlayerListHeaderAndFooter(
|
||||
Component.text(header.toString()),
|
||||
Component.text(footer.toString())
|
||||
Component.text(header),
|
||||
Component.text(footer)
|
||||
);
|
||||
}
|
||||
|
||||
private void updateAll() {
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
updateTablist(player);
|
||||
private String formatLines(String path, Player player) {
|
||||
List<String> lines = plugin.getConfig().getStringList(path);
|
||||
return TextFormatter.joinLines(lines, player, "\n");
|
||||
}
|
||||
|
||||
private void updateAll() {
|
||||
Bukkit.getOnlinePlayers().forEach(this::updateTablist);
|
||||
}
|
||||
|
||||
private boolean shouldRefresh() {
|
||||
return plugin.getConfig().getBoolean(CONFIG_PATH + ".refresh.enabled", true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
105
lohub/src/main/resources/commands.yml
Normal file
105
lohub/src/main/resources/commands.yml
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
# ╔══════════════════════════════════════════════════════════════════════════════╗
|
||||
# ║ LoHub Custom Commands Configuration ║
|
||||
# ║ Create custom commands with actions ║
|
||||
# ╚══════════════════════════════════════════════════════════════════════════════╝
|
||||
#
|
||||
# ACTIONS:
|
||||
# [MESSAGE] text - Send message to player
|
||||
# [BROADCAST] text - Broadcast to all players
|
||||
# [TITLE] title;subtitle;fadeIn;stay;fadeOut - Send title
|
||||
# [ACTIONBAR] text - Send actionbar message
|
||||
# [SOUND] sound - Play sound
|
||||
# [COMMAND] command - Execute as player
|
||||
# [CONSOLE] command - Execute as console
|
||||
# [GAMEMODE] mode - Change gamemode
|
||||
# [EFFECT] effect;level - Give potion effect
|
||||
# [CLOSE] - Close inventory
|
||||
#
|
||||
# PLACEHOLDERS:
|
||||
# %player% - Player name
|
||||
# %player_displayname% - Player display name
|
||||
# %online% - Online players count
|
||||
# %online_max% - Max players
|
||||
#
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | CUSTOM COMMANDS |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
|
||||
custom_commands:
|
||||
# Discord command
|
||||
discord:
|
||||
aliases:
|
||||
- discord
|
||||
- дискорд
|
||||
- ds
|
||||
permission: null # null = no permission required
|
||||
actions:
|
||||
- "[MESSAGE] 	B59B6Discord: &#FFFFFFdiscord.example.net"
|
||||
- "[SOUND] BLOCK_NOTE_BLOCK_PLING"
|
||||
|
||||
# Website command
|
||||
website:
|
||||
aliases:
|
||||
- website
|
||||
- site
|
||||
- сайт
|
||||
- web
|
||||
permission: null
|
||||
actions:
|
||||
- "[MESSAGE] �D4FFWebsite: &#FFFFFFwww.example.net"
|
||||
- "[SOUND] BLOCK_NOTE_BLOCK_PLING"
|
||||
|
||||
# Store command
|
||||
store:
|
||||
aliases:
|
||||
- store
|
||||
- shop
|
||||
- магазин
|
||||
- донат
|
||||
permission: null
|
||||
actions:
|
||||
- "[MESSAGE] &#FF6B6BStore: &#FFFFFFstore.example.net"
|
||||
- "[SOUND] BLOCK_NOTE_BLOCK_PLING"
|
||||
|
||||
# Clear inventory command (admin only)
|
||||
clearinventory:
|
||||
aliases:
|
||||
- ci
|
||||
- clearinv
|
||||
- очиститьинв
|
||||
permission: lohub.admin
|
||||
actions:
|
||||
- "[CONSOLE] minecraft:clear %player%"
|
||||
- "[MESSAGE] {prefix}BCB77Your inventory has been cleared!"
|
||||
- "[SOUND] ENTITY_ITEM_PICKUP"
|
||||
|
||||
# Heal command (admin only)
|
||||
heal:
|
||||
aliases:
|
||||
- heal
|
||||
- хил
|
||||
permission: lohub.admin
|
||||
actions:
|
||||
- "[CONSOLE] minecraft:effect give %player% minecraft:instant_health 1 10 true"
|
||||
- "[CONSOLE] minecraft:effect give %player% minecraft:saturation 1 10 true"
|
||||
- "[MESSAGE] {prefix}BCB77You have been healed!"
|
||||
- "[SOUND] ENTITY_PLAYER_LEVELUP"
|
||||
|
||||
# Rules command
|
||||
rules:
|
||||
aliases:
|
||||
- rules
|
||||
- правила
|
||||
permission: null
|
||||
actions:
|
||||
- "[MESSAGE] &r"
|
||||
- "[MESSAGE] &#FFD700╔═══ Server Rules ═══╗"
|
||||
- "[MESSAGE] &r"
|
||||
- "[MESSAGE] BCB771. Be respectful to all players"
|
||||
- "[MESSAGE] BCB772. No cheating or hacking"
|
||||
- "[MESSAGE] BCB773. No spam in chat"
|
||||
- "[MESSAGE] BCB774. Follow staff instructions"
|
||||
- "[MESSAGE] BCB775. Have fun!"
|
||||
- "[MESSAGE] &r"
|
||||
- "[MESSAGE] &#FFD700╚═══════════════════════╝"
|
||||
- "[SOUND] BLOCK_NOTE_BLOCK_PLING"
|
||||
|
|
@ -328,16 +328,14 @@ announcements:
|
|||
- "&#FFD700╚═══════════════════════╝"
|
||||
- "&r"
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | CUSTOM COMMANDS |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# All custom commands are now in commands.yml
|
||||
# You can create custom commands with actions there
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | MESSAGES |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
|
||||
messages:
|
||||
prefix: "�D4FF[�D4FFL�CAF7o�C0EEH�B7E6u�ADDDbcCC]"
|
||||
spawn-set: "BCB77Spawn set successfully!"
|
||||
spawn-teleport: "BCB77Teleporting to spawn..."
|
||||
no-spawn: "&#FF6B6BSpawn not set! Use /sethub"
|
||||
no-permission: "&#FF6B6BYou don't have permission!"
|
||||
players-only: "&#FF6B6BThis command is only for players!"
|
||||
config-reloaded: "BCB77Configuration reloaded!"
|
||||
usage: "&#FFD700Usage: /lohub reload"
|
||||
# All messages are now in messages.yml
|
||||
# You can customize the plugin prefix and all messages there
|
||||
|
|
|
|||
17
lohub/src/main/resources/data.yml
Normal file
17
lohub/src/main/resources/data.yml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
# ╔══════════════════════════════════════════════════════════════════════════════╗
|
||||
# ║ LoHub Data Storage ║
|
||||
# ║ DO NOT EDIT THIS FILE MANUALLY! ║
|
||||
# ║ This file is automatically managed by the plugin ║
|
||||
# ╚══════════════════════════════════════════════════════════════════════════════╝
|
||||
|
||||
# Chat lock state
|
||||
chat_locked: false
|
||||
|
||||
# Spawn location (set via /sethub command)
|
||||
spawn:
|
||||
world: null
|
||||
x: 0.0
|
||||
y: 0.0
|
||||
z: 0.0
|
||||
yaw: 0.0
|
||||
pitch: 0.0
|
||||
84
lohub/src/main/resources/messages.yml
Normal file
84
lohub/src/main/resources/messages.yml
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
# ╔══════════════════════════════════════════════════════════════════════════════╗
|
||||
# ║ LoHub Messages Configuration ║
|
||||
# ║ All plugin messages in one place ║
|
||||
# ╚══════════════════════════════════════════════════════════════════════════════╝
|
||||
|
||||
# Plugin prefix (used in all messages with {prefix} placeholder)
|
||||
prefix: "�D4FF[�D4FFL�CAF7o�C0EEH�B7E6u�ADDDbcCC] "
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | GENERAL MESSAGES |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
|
||||
general:
|
||||
no-permission: "{prefix}&#FF6B6BYou don't have permission!"
|
||||
players-only: "{prefix}&#FF6B6BThis command is only for players!"
|
||||
config-reloaded: "{prefix}BCB77Configuration reloaded!"
|
||||
invalid-player: "{prefix}&#FF6B6BPlayer %player% not found!"
|
||||
cooldown-active: "{prefix}&#FF6B6BPlease wait %time%s before using this again!"
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | SPAWN MESSAGES |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
|
||||
spawn:
|
||||
set: "{prefix}BCB77Spawn set successfully!"
|
||||
teleport: "{prefix}BCB77Teleporting to spawn..."
|
||||
no-spawn: "{prefix}&#FF6B6BSpawn not set! Use /sethub"
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | CHAT LOCK MESSAGES |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
|
||||
chat:
|
||||
locked: "{prefix}&#FF6B6BChat is currently locked!"
|
||||
lock-enabled: "{prefix}BCB77Chat has been locked!"
|
||||
lock-disabled: "{prefix}&#FF6B6BChat has been unlocked!"
|
||||
lock-broadcast-enabled: "{prefix}&#FFD700%player% &#AAAAAAhas locked the chat!"
|
||||
lock-broadcast-disabled: "{prefix}&#FFD700%player% &#AAAAAAhas unlocked the chat!"
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | PLAYER HIDER MESSAGES |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
|
||||
player-hider:
|
||||
hidden: "{prefix}&#FF6B6BPlayers are now hidden!"
|
||||
shown: "{prefix}BCB77Players are now visible!"
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | WORLD PROTECTION MESSAGES |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
|
||||
protection:
|
||||
item-drop: "{prefix}&#FF6B6BYou cannot drop items here!"
|
||||
item-pickup: "{prefix}&#FF6B6BYou cannot pickup items here!"
|
||||
block-place: "{prefix}&#FF6B6BYou cannot place blocks here!"
|
||||
block-break: "{prefix}&#FF6B6BYou cannot break blocks here!"
|
||||
block-interact: "{prefix}&#FF6B6BYou cannot interact with this!"
|
||||
player-pvp: "{prefix}&#FF6B6BPVP is disabled here!"
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | DOUBLE JUMP MESSAGES |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
|
||||
double-jump:
|
||||
cooldown: "{prefix}&#FF6B6BWait %time%s before double jumping again!"
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | COMMAND MESSAGES |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
|
||||
commands:
|
||||
usage-lohub: "{prefix}&#FFD700Usage: /lohub reload"
|
||||
usage-hub: "{prefix}&#FFD700Usage: /hub"
|
||||
usage-sethub: "{prefix}&#FFD700Usage: /sethub"
|
||||
usage-chatlock: "{prefix}&#FFD700Usage: /chatlock"
|
||||
command-blocked: "{prefix}&#FF6B6BThis command is blocked!"
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | ANTI-SWEAR MESSAGES |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
|
||||
anti-swear:
|
||||
blocked: "{prefix}&#FF6B6BYour message contains inappropriate language!"
|
||||
admin-notify: "{prefix}&#FFD700%player% &#AAAAAAattempted to say: &#FF6B6B%word%"
|
||||
|
|
@ -28,6 +28,12 @@ commands:
|
|||
usage: /lohub [reload]
|
||||
permission: lohub.admin
|
||||
|
||||
chatlock:
|
||||
description: Lock/unlock chat
|
||||
usage: /chatlock
|
||||
permission: lohub.chatlock
|
||||
aliases: [ lockchat, чатлок ]
|
||||
|
||||
permissions:
|
||||
lohub.hub:
|
||||
description: Can use /hub command
|
||||
|
|
@ -38,3 +44,9 @@ permissions:
|
|||
lohub.bypass.protection:
|
||||
description: Bypass world protection
|
||||
default: op
|
||||
lohub.chatlock:
|
||||
description: Can lock/unlock chat
|
||||
default: op
|
||||
lohub.chatlock.bypass:
|
||||
description: Can bypass chat lock
|
||||
default: op
|
||||
|
|
|
|||
139
lohub/src/main/resources/serverselector.yml
Normal file
139
lohub/src/main/resources/serverselector.yml
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
# ╔══════════════════════════════════════════════════════════════════════════════╗
|
||||
# ║ LoHub Server Selector Configuration ║
|
||||
# ║ GUI menu for server selection ║
|
||||
# ╚══════════════════════════════════════════════════════════════════════════════╝
|
||||
#
|
||||
# This file defines the server selector GUI that players can open
|
||||
# You can customize the items, layout, and actions
|
||||
#
|
||||
# ITEM ACTIONS:
|
||||
# [MESSAGE] text - Send message to player
|
||||
# [BROADCAST] text - Broadcast to all players
|
||||
# [TITLE] title;subtitle;fadeIn;stay;fadeOut - Send title
|
||||
# [ACTIONBAR] text - Send actionbar message
|
||||
# [SOUND] sound - Play sound
|
||||
# [COMMAND] command - Execute as player
|
||||
# [CONSOLE] command - Execute as console
|
||||
# [PROXY] server - Send player to BungeeCord/Velocity server
|
||||
# [CLOSE] - Close inventory
|
||||
#
|
||||
# ITEM FLAGS:
|
||||
# - HIDE_ATTRIBUTES
|
||||
# - HIDE_DESTROYS
|
||||
# - HIDE_ENCHANTS
|
||||
# - HIDE_PLACED_ON
|
||||
# - HIDE_POTION_EFFECTS
|
||||
# - HIDE_UNBREAKABLE
|
||||
#
|
||||
# PLAYER HEADS:
|
||||
# material: PLAYER_HEAD
|
||||
# username: <player_name> # OR
|
||||
# base64: <base64_texture>
|
||||
#
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | SERVER SELECTOR GUI |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
|
||||
# GUI settings
|
||||
gui:
|
||||
# Title of the inventory
|
||||
title: "&#FFD700S&#FFC700e&#FFB700r&#FFA700v&#FF9700e&#FF8700r &#FF7700S&#FF6700e&#FF5700l&#FF4700e&#FF3700c&#FF2700t&#FF1700o&#FF0700r"
|
||||
|
||||
# Number of rows (1-6, each row = 9 slots)
|
||||
rows: 3
|
||||
|
||||
# Auto-update GUI (for placeholders)
|
||||
refresh:
|
||||
enabled: false
|
||||
rate: 40 # In ticks (20 ticks = 1 second)
|
||||
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
# | GUI ITEMS |
|
||||
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
|
||||
|
||||
items:
|
||||
# Filler item (decorative glass)
|
||||
filler:
|
||||
material: GRAY_STAINED_GLASS_PANE
|
||||
slot: -1 # -1 = fill all empty slots
|
||||
amount: 1
|
||||
display_name: " "
|
||||
item_flags:
|
||||
- HIDE_ATTRIBUTES
|
||||
|
||||
# Survival server
|
||||
survival:
|
||||
material: GRASS_BLOCK
|
||||
slot: 11
|
||||
amount: 1
|
||||
glow: true
|
||||
display_name: "BCB77S>C973uAC76Fr3C56Bv1C367i(C163v&BF5FaFBD5Bl"
|
||||
lore:
|
||||
- ""
|
||||
- "&#AAAAAAClassic survival experience"
|
||||
- "&#AAAAAABuild, mine, and survive!"
|
||||
- ""
|
||||
- "&#FFD700Click to join!"
|
||||
actions:
|
||||
- "[CLOSE]"
|
||||
- "[MESSAGE] {prefix}BCB77Connecting to Survival..."
|
||||
- "[SOUND] ENTITY_ENDERMAN_TELEPORT"
|
||||
# For BungeeCord/Velocity:
|
||||
# - "[PROXY] survival"
|
||||
# For Multiverse-Core (multi-world):
|
||||
# - "[CONSOLE] mvtp %player% survival_world"
|
||||
|
||||
# Creative server
|
||||
creative:
|
||||
material: COMMAND_BLOCK
|
||||
slot: 13
|
||||
amount: 1
|
||||
glow: true
|
||||
display_name: "&#FF6B6BC&#FF5757r&#FF4343e&#FF2F2Fa&#FF1B1Bt&#FF0707i&#F30000v&#DF0000e"
|
||||
lore:
|
||||
- ""
|
||||
- "&#AAAAAAUnlimited creativity!"
|
||||
- "&#AAAAAABuild anything you imagine"
|
||||
- ""
|
||||
- "&#FFD700Click to join!"
|
||||
actions:
|
||||
- "[CLOSE]"
|
||||
- "[MESSAGE] {prefix}&#FF6B6BConnecting to Creative..."
|
||||
- "[SOUND] ENTITY_ENDERMAN_TELEPORT"
|
||||
# For BungeeCord/Velocity:
|
||||
# - "[PROXY] creative"
|
||||
# For Multiverse-Core:
|
||||
# - "[CONSOLE] mvtp %player% creative_world"
|
||||
|
||||
# Minigames server
|
||||
minigames:
|
||||
material: DIAMOND_SWORD
|
||||
slot: 15
|
||||
amount: 1
|
||||
glow: true
|
||||
display_name: "	B59B6ME4FB0iῑAAnA3BA4iD319Eg򓚖aȔD92m񰸵e餝Fs"
|
||||
lore:
|
||||
- ""
|
||||
- "&#AAAAAAFun minigames and competitions"
|
||||
- "&#AAAAAAPlay with friends!"
|
||||
- ""
|
||||
- "&#FFD700Click to join!"
|
||||
actions:
|
||||
- "[CLOSE]"
|
||||
- "[MESSAGE] {prefix}	B59B6Connecting to Minigames..."
|
||||
- "[SOUND] ENTITY_ENDERMAN_TELEPORT"
|
||||
# For BungeeCord/Velocity:
|
||||
# - "[PROXY] minigames"
|
||||
|
||||
# Close button
|
||||
close:
|
||||
material: BARRIER
|
||||
slot: 22
|
||||
amount: 1
|
||||
display_name: "&#FF6B6BClose"
|
||||
lore:
|
||||
- ""
|
||||
- "&#AAAAAAClick to close this menu"
|
||||
actions:
|
||||
- "[CLOSE]"
|
||||
- "[SOUND] BLOCK_CHEST_CLOSE"
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
package com.loki.lochat.core.service;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.loki.lochat.data.model.MuteData;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class MuteHistoryManager {
|
||||
|
||||
private final Map<UUID, List<MuteData.MuteHistoryEntry>> history = new ConcurrentHashMap<>();
|
||||
private final File historyFile;
|
||||
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
public MuteHistoryManager(File historyFile) {
|
||||
this.historyFile = historyFile;
|
||||
load();
|
||||
}
|
||||
|
||||
public void addEntry(UUID uuid, String playerName, long duration, String reason, String mutedBy) {
|
||||
List<MuteData.MuteHistoryEntry> entries = history.computeIfAbsent(uuid, k -> new ArrayList<>());
|
||||
entries.add(new MuteData.MuteHistoryEntry(
|
||||
playerName,
|
||||
duration,
|
||||
reason,
|
||||
mutedBy,
|
||||
System.currentTimeMillis(),
|
||||
false,
|
||||
null,
|
||||
0
|
||||
));
|
||||
}
|
||||
|
||||
public void updateUnmute(UUID uuid, String unmutedBy) {
|
||||
List<MuteData.MuteHistoryEntry> entries = history.get(uuid);
|
||||
if (entries != null && !entries.isEmpty()) {
|
||||
MuteData.MuteHistoryEntry lastEntry = entries.get(entries.size() - 1);
|
||||
if (lastEntry.unmutedBy == null) {
|
||||
lastEntry.unmuted = true;
|
||||
lastEntry.unmutedBy = unmutedBy;
|
||||
lastEntry.unmutedAt = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<MuteData.MuteHistoryEntry> getHistory(UUID uuid) {
|
||||
return history.getOrDefault(uuid, Collections.emptyList());
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try (FileWriter writer = new FileWriter(historyFile)) {
|
||||
gson.toJson(history, writer);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void load() {
|
||||
if (!historyFile.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try (FileReader reader = new FileReader(historyFile)) {
|
||||
Type type = new TypeToken<Map<UUID, List<MuteData.MuteHistoryEntry>>>() {
|
||||
}.getType();
|
||||
Map<UUID, List<MuteData.MuteHistoryEntry>> loaded = gson.fromJson(reader, type);
|
||||
if (loaded != null) {
|
||||
history.putAll(loaded);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import com.google.gson.reflect.TypeToken;
|
|||
import com.loki.lochat.api.service.MuteService;
|
||||
import com.loki.lochat.data.model.MuteData;
|
||||
import com.loki.lochat.gradient.util.FoliaUtil;
|
||||
import com.loki.lochat.utils.TimeFormatter;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
|
|
@ -14,23 +15,19 @@ import java.lang.reflect.Type;
|
|||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* Реализация сервиса мутов
|
||||
*/
|
||||
public class MuteServiceImpl implements MuteService {
|
||||
|
||||
private final JavaPlugin plugin;
|
||||
private final Map<UUID, MuteData> mutes = new ConcurrentHashMap<>();
|
||||
private final Map<UUID, List<MuteData.MuteHistoryEntry>> history = new ConcurrentHashMap<>();
|
||||
private final MuteHistoryManager historyManager;
|
||||
private final File dataFile;
|
||||
private final File historyFile;
|
||||
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
public MuteServiceImpl(JavaPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.dataFile = new File(plugin.getDataFolder(), "mutes.json");
|
||||
this.historyFile = new File(plugin.getDataFolder(), "mute-history.json");
|
||||
this.historyManager = new MuteHistoryManager(new File(plugin.getDataFolder(), "mute-history.json"));
|
||||
load();
|
||||
loadHistory();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -39,9 +36,7 @@ public class MuteServiceImpl implements MuteService {
|
|||
MuteData data = new MuteData(uuid, playerName, endTime, reason, mutedBy);
|
||||
mutes.put(uuid, data);
|
||||
|
||||
// Добавляем в историю
|
||||
addToHistory(uuid, playerName, duration, reason, mutedBy);
|
||||
|
||||
historyManager.addEntry(uuid, playerName, duration, reason, mutedBy);
|
||||
saveAsync();
|
||||
}
|
||||
|
||||
|
|
@ -49,7 +44,7 @@ public class MuteServiceImpl implements MuteService {
|
|||
public boolean unmute(UUID uuid, String unmutedBy) {
|
||||
MuteData removed = mutes.remove(uuid);
|
||||
if (removed != null) {
|
||||
updateHistoryUnmute(uuid, unmutedBy);
|
||||
historyManager.updateUnmute(uuid, unmutedBy);
|
||||
saveAsync();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -59,9 +54,11 @@ public class MuteServiceImpl implements MuteService {
|
|||
@Override
|
||||
public boolean isMuted(UUID uuid) {
|
||||
MuteData data = mutes.get(uuid);
|
||||
if (data == null) return false;
|
||||
if (data == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data.getEndTime() > 0 && System.currentTimeMillis() > data.getEndTime()) {
|
||||
if (isExpired(data)) {
|
||||
mutes.remove(uuid);
|
||||
saveAsync();
|
||||
return false;
|
||||
|
|
@ -71,66 +68,35 @@ public class MuteServiceImpl implements MuteService {
|
|||
|
||||
@Override
|
||||
public MuteData getMuteData(UUID uuid) {
|
||||
if (!isMuted(uuid)) return null;
|
||||
return mutes.get(uuid);
|
||||
return isMuted(uuid) ? mutes.get(uuid) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getRemainingTime(UUID uuid) {
|
||||
MuteData data = mutes.get(uuid);
|
||||
if (data == null) return 0;
|
||||
if (data.getEndTime() == 0) return -1; // Перманентный
|
||||
if (data == null) {
|
||||
return 0;
|
||||
}
|
||||
if (data.getEndTime() == 0) {
|
||||
return -1;
|
||||
}
|
||||
return Math.max(0, data.getEndTime() - System.currentTimeMillis());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String formatTime(long millis) {
|
||||
if (millis <= 0) return "0с";
|
||||
|
||||
long seconds = millis / 1000;
|
||||
long minutes = seconds / 60;
|
||||
long hours = minutes / 60;
|
||||
long days = hours / 24;
|
||||
|
||||
if (days > 0) {
|
||||
return days + "д " + (hours % 24) + "ч";
|
||||
} else if (hours > 0) {
|
||||
return hours + "ч " + (minutes % 60) + "м";
|
||||
} else if (minutes > 0) {
|
||||
return minutes + "м " + (seconds % 60) + "с";
|
||||
} else {
|
||||
return seconds + "с";
|
||||
}
|
||||
return TimeFormatter.format(millis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long parseTime(String timeStr) {
|
||||
if (timeStr == null || timeStr.isEmpty()) return 0;
|
||||
|
||||
timeStr = timeStr.toLowerCase();
|
||||
long multiplier = 1000; // базово в миллисекундах
|
||||
|
||||
try {
|
||||
if (timeStr.endsWith("d")) {
|
||||
return Long.parseLong(timeStr.replace("d", "")) * 24 * 60 * 60 * multiplier;
|
||||
} else if (timeStr.endsWith("h")) {
|
||||
return Long.parseLong(timeStr.replace("h", "")) * 60 * 60 * multiplier;
|
||||
} else if (timeStr.endsWith("m")) {
|
||||
return Long.parseLong(timeStr.replace("m", "")) * 60 * multiplier;
|
||||
} else if (timeStr.endsWith("s")) {
|
||||
return Long.parseLong(timeStr.replace("s", "")) * multiplier;
|
||||
} else {
|
||||
return Long.parseLong(timeStr) * 60 * multiplier;
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
return -1;
|
||||
}
|
||||
return TimeFormatter.parse(timeStr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxDuration(Player player) {
|
||||
if (player.hasPermission("lochat.mute.dur.perm")) {
|
||||
return 0; // Перманентный
|
||||
return 0;
|
||||
}
|
||||
|
||||
String[] durations = {"30d", "14d", "7d", "3d", "1d", "12h", "6h", "1h", "30m", "10m"};
|
||||
|
|
@ -140,7 +106,7 @@ public class MuteServiceImpl implements MuteService {
|
|||
}
|
||||
}
|
||||
|
||||
return -1; // Нет прав
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -154,37 +120,39 @@ public class MuteServiceImpl implements MuteService {
|
|||
}
|
||||
|
||||
long maxDuration = getMaxDuration(player);
|
||||
if (maxDuration == -1) return false;
|
||||
if (maxDuration == 0) return true;
|
||||
if (maxDuration == -1) {
|
||||
return false;
|
||||
}
|
||||
if (maxDuration == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return duration <= maxDuration;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MuteData.MuteHistoryEntry> getPlayerHistory(UUID uuid) {
|
||||
return history.getOrDefault(uuid, new ArrayList<>());
|
||||
return historyManager.getHistory(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MuteData.MuteHistoryEntry> getMutesByOperator(String operatorName) {
|
||||
List<MuteData.MuteHistoryEntry> result = new ArrayList<>();
|
||||
for (List<MuteData.MuteHistoryEntry> playerHistory : history.values()) {
|
||||
for (MuteData.MuteHistoryEntry entry : playerHistory) {
|
||||
if (entry.mutedBy != null && entry.mutedBy.equalsIgnoreCase(operatorName)) {
|
||||
result.add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
mutes.keySet().forEach(uuid -> {
|
||||
historyManager.getHistory(uuid).stream()
|
||||
.filter(entry -> entry.mutedBy != null && entry.mutedBy.equalsIgnoreCase(operatorName))
|
||||
.forEach(result::add);
|
||||
});
|
||||
result.sort((a, b) -> Long.compare(b.mutedAt, a.mutedAt));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getUUIDByName(String name) {
|
||||
for (Map.Entry<UUID, List<MuteData.MuteHistoryEntry>> entry : history.entrySet()) {
|
||||
for (MuteData.MuteHistoryEntry historyEntry : entry.getValue()) {
|
||||
if (historyEntry.playerName != null && historyEntry.playerName.equalsIgnoreCase(name)) {
|
||||
return entry.getKey();
|
||||
for (UUID uuid : mutes.keySet()) {
|
||||
for (MuteData.MuteHistoryEntry entry : historyManager.getHistory(uuid)) {
|
||||
if (entry.playerName != null && entry.playerName.equalsIgnoreCase(name)) {
|
||||
return uuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -193,10 +161,7 @@ public class MuteServiceImpl implements MuteService {
|
|||
|
||||
@Override
|
||||
public Map<UUID, MuteData> getActiveMutes() {
|
||||
mutes.entrySet().removeIf(entry -> {
|
||||
MuteData data = entry.getValue();
|
||||
return data.getEndTime() > 0 && System.currentTimeMillis() > data.getEndTime();
|
||||
});
|
||||
mutes.entrySet().removeIf(entry -> isExpired(entry.getValue()));
|
||||
return new HashMap<>(mutes);
|
||||
}
|
||||
|
||||
|
|
@ -212,23 +177,37 @@ public class MuteServiceImpl implements MuteService {
|
|||
@Override
|
||||
public void save() {
|
||||
try {
|
||||
ensureDataFolderExists();
|
||||
saveMutes();
|
||||
historyManager.save();
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().warning("Error saving mutes: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isExpired(MuteData data) {
|
||||
return data.getEndTime() > 0 && System.currentTimeMillis() > data.getEndTime();
|
||||
}
|
||||
|
||||
private void ensureDataFolderExists() {
|
||||
if (!dataFile.getParentFile().exists()) {
|
||||
dataFile.getParentFile().mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveMutes() throws IOException {
|
||||
Map<String, MuteData> toSave = new ConcurrentHashMap<>();
|
||||
mutes.forEach((uuid, data) -> toSave.put(uuid.toString(), data));
|
||||
|
||||
try (Writer writer = new FileWriter(dataFile)) {
|
||||
gson.toJson(toSave, writer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().warning("Ошибка сохранения мутов: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void load() {
|
||||
if (!dataFile.exists()) return;
|
||||
if (!dataFile.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try (Reader reader = new FileReader(dataFile)) {
|
||||
Type type = new TypeToken<Map<String, MuteData>>() {
|
||||
|
|
@ -243,86 +222,11 @@ public class MuteServiceImpl implements MuteService {
|
|||
});
|
||||
}
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().warning("Ошибка загрузки мутов: " + e.getMessage());
|
||||
plugin.getLogger().warning("Error loading mutes: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void loadHistory() {
|
||||
if (!historyFile.exists()) return;
|
||||
|
||||
try (Reader reader = new FileReader(historyFile)) {
|
||||
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 (IOException e) {
|
||||
plugin.getLogger().warning("Ошибка загрузки истории мутов: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void saveHistory() {
|
||||
try {
|
||||
if (!historyFile.getParentFile().exists()) {
|
||||
historyFile.getParentFile().mkdirs();
|
||||
}
|
||||
|
||||
Map<String, List<MuteData.MuteHistoryEntry>> toSave = new ConcurrentHashMap<>();
|
||||
history.forEach((uuid, data) -> toSave.put(uuid.toString(), data));
|
||||
|
||||
try (Writer writer = new FileWriter(historyFile)) {
|
||||
gson.toJson(toSave, writer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().warning("Ошибка сохранения истории мутов: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void addToHistory(UUID uuid, String playerName, long duration, String reason, String mutedBy) {
|
||||
List<MuteData.MuteHistoryEntry> playerHistory = history.computeIfAbsent(uuid, k -> new ArrayList<>());
|
||||
playerHistory.add(new MuteData.MuteHistoryEntry(
|
||||
playerName,
|
||||
duration,
|
||||
reason,
|
||||
mutedBy,
|
||||
System.currentTimeMillis(),
|
||||
false,
|
||||
null,
|
||||
0
|
||||
));
|
||||
saveHistoryAsync();
|
||||
}
|
||||
|
||||
private void updateHistoryUnmute(UUID uuid, String unmutedBy) {
|
||||
List<MuteData.MuteHistoryEntry> playerHistory = history.get(uuid);
|
||||
if (playerHistory != null && !playerHistory.isEmpty()) {
|
||||
for (int i = playerHistory.size() - 1; i >= 0; i--) {
|
||||
MuteData.MuteHistoryEntry entry = playerHistory.get(i);
|
||||
if (!entry.unmuted) {
|
||||
entry.unmuted = true;
|
||||
entry.unmutedBy = unmutedBy;
|
||||
entry.unmutedAt = System.currentTimeMillis();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
saveHistoryAsync();
|
||||
}
|
||||
|
||||
private void saveHistoryAsync() {
|
||||
FoliaUtil.runAsync(plugin, this::saveHistory);
|
||||
}
|
||||
|
||||
private void saveAsync() {
|
||||
FoliaUtil.runAsync(plugin, () -> {
|
||||
save();
|
||||
saveHistory();
|
||||
});
|
||||
FoliaUtil.runAsync(plugin, this::save);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
59
src/main/java/com/loki/lochat/utils/TimeFormatter.java
Normal file
59
src/main/java/com/loki/lochat/utils/TimeFormatter.java
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
package com.loki.lochat.utils;
|
||||
|
||||
public final class TimeFormatter {
|
||||
|
||||
private TimeFormatter() {
|
||||
}
|
||||
|
||||
public static String format(long millis) {
|
||||
if (millis <= 0) {
|
||||
return "0с";
|
||||
}
|
||||
|
||||
long seconds = millis / 1000;
|
||||
long minutes = seconds / 60;
|
||||
long hours = minutes / 60;
|
||||
long days = hours / 24;
|
||||
|
||||
if (days > 0) {
|
||||
return days + "д " + (hours % 24) + "ч";
|
||||
} else if (hours > 0) {
|
||||
return hours + "ч " + (minutes % 60) + "м";
|
||||
} else if (minutes > 0) {
|
||||
return minutes + "м " + (seconds % 60) + "с";
|
||||
} else {
|
||||
return seconds + "с";
|
||||
}
|
||||
}
|
||||
|
||||
public static long parse(String timeStr) {
|
||||
if (timeStr == null || timeStr.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long totalMillis = 0;
|
||||
StringBuilder number = new StringBuilder();
|
||||
|
||||
for (char c : timeStr.toCharArray()) {
|
||||
if (Character.isDigit(c)) {
|
||||
number.append(c);
|
||||
} else if (number.length() > 0) {
|
||||
long value = Long.parseLong(number.toString());
|
||||
totalMillis += getMillisForUnit(c, value);
|
||||
number.setLength(0);
|
||||
}
|
||||
}
|
||||
|
||||
return totalMillis;
|
||||
}
|
||||
|
||||
private static long getMillisForUnit(char unit, long value) {
|
||||
return switch (Character.toLowerCase(unit)) {
|
||||
case 's', 'с' -> value * 1000;
|
||||
case 'm', 'м' -> value * 60 * 1000;
|
||||
case 'h', 'ч' -> value * 60 * 60 * 1000;
|
||||
case 'd', 'д' -> value * 24 * 60 * 60 * 1000;
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue