Complete LoHub implementation: ETAP 4-10 (Custom Items, Launchpad, Double Jump, Player Hider, Scoreboard, Tablist, Announcements)

This commit is contained in:
loki5512344 2026-02-24 00:19:05 +01:00
parent e78d8a2de4
commit 102341bb2c
12 changed files with 803 additions and 43 deletions

99
TODO.md
View file

@ -20,7 +20,7 @@
--- ---
### 2. LoHub - Hub плагин (Paper/Folia) ### 2. LoHub - Hub плагин (Paper/Folia)
**Статус:** 🔄 В разработке (21% готово) **Статус:** ✅ Готов к использованию (100% готово)
#### ✅ Готово #### ✅ Готово
- ✅ Spawn система с телепортом - ✅ Spawn система с телепортом
@ -28,49 +28,62 @@
- ✅ Защита мира (блоки, PvP, мобы) - ✅ Защита мира (блоки, PvP, мобы)
- ✅ Команды /hub, /sethub, /lohub - ✅ Команды /hub, /sethub, /lohub
- ✅ Базовые утилиты (ItemBuilder, TextUtil, PlaceholderUtil) - ✅ Базовые утилиты (ItemBuilder, TextUtil, PlaceholderUtil)
- ✅ **ЭТАП 2: Action система**
- ✅ Action интерфейс и ActionType enum
- ✅ MessageAction, BroadcastAction, TitleAction, ActionbarAction
- ✅ SoundAction, CommandAction, ConsoleAction
- ✅ GamemodeAction, EffectAction, CloseAction
- ✅ ActionManager с regex парсингом
- ✅ **ЭТАП 3: Join система**
- ✅ PlayerJoinListener (join/quit/respawn/death)
- ✅ Телепорт на спавн при входе
- ✅ Хил и очистка эффектов
- ✅ Кастомные сообщения входа/выхода
- ✅ Фейерверки при первом входе
- ✅ Интеграция с Action системой
- ✅ **ЭТАП 4: Custom Join Items**
- ✅ HotbarManager - управление предметами
- ✅ Выдача предметов при входе
- ✅ HotbarListener - обработка кликов
- ✅ Защита от выбрасывания предметов
- ✅ Интеграция с Action системой
- ✅ **ЭТАП 5: Launchpad**
- ✅ LaunchpadListener - прыжковые площадки
- ✅ Проверка блоков (плита + редстоун)
- ✅ Настраиваемая сила прыжка
- ✅ Интеграция с Action системой
- ✅ **ЭТАП 6: Double Jump**
- ✅ DoubleJumpListener - двойной прыжок
- ✅ Интеграция с CooldownManager
- ✅ Настраиваемая сила и кулдаун
- ✅ Интеграция с Action системой
- ✅ **ЭТАП 7: Player Hider**
- ✅ PlayerHiderManager - управление видимостью
- ✅ Скрытие/показ игроков
- ✅ Предмет для переключения
- ✅ Кулдаун на использование
- ✅ **ЭТАП 8: Scoreboard**
- ✅ ScoreboardManager - управление скорбордом
- ✅ Настраиваемый заголовок и строки
- ✅ Автообновление с настраиваемым интервалом
- ✅ PlaceholderAPI интеграция
- ✅ **ЭТАП 9: Tablist**
- ✅ TablistManager - управление табом
- ✅ Настраиваемый header и footer
- ✅ Автообновление с настраиваемым интервалом
- ✅ PlaceholderAPI интеграция
- ✅ **ЭТАП 10: Announcements**
- ✅ AnnouncementManager - система объявлений
- ✅ Множественные объявления с ротацией
- ✅ Настраиваемый интервал и звук
- ✅ Минимальное количество игроков
- ✅ PlaceholderAPI интеграция
#### 🔄 В работе - ЭТАП 2: Action система #### 📋 Дополнительно
- [ ] Action интерфейс и ActionType enum - Все основные функции реализованы
- [ ] MessageAction - отправка сообщений - Конфигурация полностью настраиваема через config.yml
- [ ] SoundAction - звуки - Поддержка PlaceholderAPI для всех текстовых элементов
- [ ] TitleAction - title/subtitle - Команда /lohub reload для перезагрузки конфигурации
- [ ] CommandAction - команды от игрока
- [ ] ConsoleAction - команды от консоли
- [ ] GamemodeAction - смена режима
- [ ] EffectAction - эффекты
- [ ] ActionManager - парсинг и выполнение
#### 📋 Запланировано
**ЭТАП 3: Join система**
- [ ] PlayerJoinListener
- [ ] Телепорт на спавн при входе
- [ ] Хил и очистка эффектов
- [ ] Кастомные сообщения входа/выхода
- [ ] Интеграция с Action системой
**ЭТАП 4: Custom Join Items**
- [ ] HotbarManager
- [ ] Выдача предметов при входе
- [ ] Обработка кликов (actions)
- [ ] Защита от выбрасывания
**ЭТАП 5: Launchpad**
- [ ] LaunchpadListener
- [ ] Прыжковые площадки (плита + редстоун)
**ЭТАП 6: Double Jump**
- [ ] DoubleJumpListener
- [ ] CooldownManager
- [ ] Двойной прыжок в воздухе
**ЭТАП 7: Player Hider**
- [ ] PlayerHiderManager
- [ ] Скрытие/показ игроков
- [ ] Предмет для переключения
**ЭТАП 8-10: Опционально**
- [ ] Scoreboard модуль
- [ ] Tablist модуль
- [ ] Announcements модуль - [ ] Announcements модуль
--- ---

View file

@ -4,9 +4,14 @@ import com.loki.lohub.config.ConfigManager;
import com.loki.lohub.listeners.HubProtectionListener; import com.loki.lohub.listeners.HubProtectionListener;
import com.loki.lohub.listeners.PlayerJoinListener; import com.loki.lohub.listeners.PlayerJoinListener;
import com.loki.lohub.managers.ActionManager; import com.loki.lohub.managers.ActionManager;
import com.loki.lohub.managers.AnnouncementManager;
import com.loki.lohub.managers.CooldownManager; import com.loki.lohub.managers.CooldownManager;
import com.loki.lohub.managers.HotbarManager;
import com.loki.lohub.managers.PlayerHiderManager;
import com.loki.lohub.managers.RegionManager; import com.loki.lohub.managers.RegionManager;
import com.loki.lohub.managers.ScoreboardManager;
import com.loki.lohub.managers.SpawnManager; import com.loki.lohub.managers.SpawnManager;
import com.loki.lohub.managers.TablistManager;
import com.loki.lohub.utils.PlaceholderUtil; import com.loki.lohub.utils.PlaceholderUtil;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@ -17,6 +22,11 @@ public class LoHub extends JavaPlugin {
private RegionManager regionManager; private RegionManager regionManager;
private ActionManager actionManager; private ActionManager actionManager;
private CooldownManager cooldownManager; private CooldownManager cooldownManager;
private HotbarManager hotbarManager;
private PlayerHiderManager playerHiderManager;
private ScoreboardManager scoreboardManager;
private TablistManager tablistManager;
private AnnouncementManager announcementManager;
@Override @Override
public void onEnable() { public void onEnable() {
@ -31,23 +41,38 @@ public class LoHub extends JavaPlugin {
this.regionManager = new RegionManager(this); this.regionManager = new RegionManager(this);
this.actionManager = new ActionManager(this); this.actionManager = new ActionManager(this);
this.cooldownManager = new CooldownManager(); this.cooldownManager = new CooldownManager();
this.hotbarManager = new HotbarManager(this);
this.playerHiderManager = new PlayerHiderManager(this);
this.scoreboardManager = new ScoreboardManager(this);
this.tablistManager = new TablistManager(this);
this.announcementManager = new AnnouncementManager(this);
registerListeners(); registerListeners();
registerCommands(); registerCommands();
regionManager.createHubRegion(); regionManager.createHubRegion();
scoreboardManager.start();
tablistManager.start();
announcementManager.start();
getLogger().info("LoHub successfully loaded!"); getLogger().info("LoHub successfully loaded!");
} }
@Override @Override
public void onDisable() { public void onDisable() {
scoreboardManager.stop();
tablistManager.stop();
announcementManager.stop();
getLogger().info("LoHub disabled!"); getLogger().info("LoHub disabled!");
} }
private void registerListeners() { private void registerListeners() {
getServer().getPluginManager().registerEvents(new HubProtectionListener(this), this); getServer().getPluginManager().registerEvents(new HubProtectionListener(this), this);
getServer().getPluginManager().registerEvents(new PlayerJoinListener(this), this); getServer().getPluginManager().registerEvents(new PlayerJoinListener(this), this);
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);
} }
private void registerCommands() { private void registerCommands() {
@ -75,4 +100,24 @@ public class LoHub extends JavaPlugin {
public CooldownManager getCooldownManager() { public CooldownManager getCooldownManager() {
return cooldownManager; return cooldownManager;
} }
public HotbarManager getHotbarManager() {
return hotbarManager;
}
public PlayerHiderManager getPlayerHiderManager() {
return playerHiderManager;
}
public ScoreboardManager getScoreboardManager() {
return scoreboardManager;
}
public TablistManager getTablistManager() {
return tablistManager;
}
public AnnouncementManager getAnnouncementManager() {
return announcementManager;
}
} }

View file

@ -29,6 +29,12 @@ public class LoHubCommand implements CommandExecutor {
if (args[0].equalsIgnoreCase("reload")) { if (args[0].equalsIgnoreCase("reload")) {
plugin.getConfigManager().reload(); plugin.getConfigManager().reload();
plugin.getHotbarManager().reload();
plugin.getAnnouncementManager().reload();
plugin.getScoreboardManager().stop();
plugin.getTablistManager().stop();
plugin.getScoreboardManager().start();
plugin.getTablistManager().start();
sender.sendMessage(TextUtil.colorize("&aConfiguration reloaded!")); sender.sendMessage(TextUtil.colorize("&aConfiguration reloaded!"));
return true; return true;
} }

View file

@ -0,0 +1,80 @@
package com.loki.lohub.listeners;
import com.loki.lohub.LoHub;
import org.bukkit.GameMode;
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 final LoHub plugin;
public DoubleJumpListener(LoHub plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
if (!plugin.getConfig().getBoolean("double_jump.enabled", true)) {
return;
}
Player player = event.getPlayer();
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
return;
}
if (!player.isOnGround() && !player.getAllowFlight()) {
player.setAllowFlight(true);
} else if (player.isOnGround() && player.getAllowFlight()) {
player.setAllowFlight(false);
player.setFlying(false);
}
}
@EventHandler
public void onPlayerToggleFlight(PlayerToggleFlightEvent event) {
if (!plugin.getConfig().getBoolean("double_jump.enabled", true)) {
return;
}
Player player = event.getPlayer();
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
return;
}
if (plugin.getCooldownManager().hasCooldown("double_jump", player.getUniqueId())) {
event.setCancelled(true);
player.setAllowFlight(false);
player.setFlying(false);
return;
}
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);
Vector velocity = player.getLocation().getDirection().multiply(power);
velocity.setY(powerY);
player.setVelocity(velocity);
int cooldown = plugin.getConfig().getInt("double_jump.cooldown", 3);
plugin.getCooldownManager().setCooldown("double_jump", player.getUniqueId(), cooldown);
List<String> actions = plugin.getConfig().getStringList("double_jump.actions");
if (!actions.isEmpty()) {
plugin.getActionManager().executeActions(player, actions, false);
}
}
}

View file

@ -0,0 +1,58 @@
package com.loki.lohub.listeners;
import com.loki.lohub.LoHub;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
public class HotbarListener implements Listener {
private final LoHub plugin;
public HotbarListener(LoHub plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPlayerInteract(PlayerInteractEvent event) {
if (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
}
Player player = event.getPlayer();
int slot = player.getInventory().getHeldItemSlot();
if (plugin.getPlayerHiderManager().isPlayerHiderSlot(slot)) {
event.setCancelled(true);
if (plugin.getCooldownManager().hasCooldown("player_hider", player.getUniqueId())) {
return;
}
int cooldown = plugin.getConfig().getInt("player_hider.cooldown", 3);
plugin.getCooldownManager().setCooldown("player_hider", player.getUniqueId(), cooldown);
plugin.getPlayerHiderManager().toggle(player);
} else if (plugin.getHotbarManager().isHotbarItem(slot)) {
event.setCancelled(true);
plugin.getHotbarManager().handleClick(player, slot);
}
}
@EventHandler
public void onPlayerDropItem(PlayerDropItemEvent event) {
if (!plugin.getConfig().getBoolean("custom_join_items.disable_inventory_movement", true)) {
return;
}
Player player = event.getPlayer();
int slot = player.getInventory().getHeldItemSlot();
if (plugin.getHotbarManager().isHotbarItem(slot) || plugin.getPlayerHiderManager().isPlayerHiderSlot(slot)) {
event.setCancelled(true);
}
}
}

View file

@ -0,0 +1,68 @@
package com.loki.lohub.listeners;
import com.loki.lohub.LoHub;
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 final LoHub plugin;
public LaunchpadListener(LoHub plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPlayerMove(PlayerMoveEvent event) {
if (!plugin.getConfig().getBoolean("launchpad.enabled", true)) {
return;
}
if (event.getFrom().getBlockX() == event.getTo().getBlockX()
&& event.getFrom().getBlockY() == event.getTo().getBlockY()
&& event.getFrom().getBlockZ() == event.getTo().getBlockZ()) {
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) {
launchPlayer(player);
}
}
}
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);
Vector velocity = player.getLocation().getDirection().multiply(power);
velocity.setY(powerY);
player.setVelocity(velocity);
List<String> actions = plugin.getConfig().getStringList("launchpad.actions");
if (!actions.isEmpty()) {
plugin.getActionManager().executeActions(player, actions, false);
}
}
}

View file

@ -65,6 +65,9 @@ public class PlayerJoinListener implements Listener {
handleJoinSettings(player); handleJoinSettings(player);
handleJoinEvents(player); handleJoinEvents(player);
handleFirework(player); handleFirework(player);
plugin.getScoreboardManager().setScoreboard(player, true);
plugin.getTablistManager().setTablist(player);
} }
@EventHandler(priority = EventPriority.HIGHEST) @EventHandler(priority = EventPriority.HIGHEST)
@ -75,6 +78,9 @@ public class PlayerJoinListener implements Listener {
return; return;
} }
plugin.getPlayerHiderManager().removePlayer(player);
plugin.getScoreboardManager().removePlayer(player);
if (plugin.getConfig().getBoolean("join_leave_messages.enabled", true)) { if (plugin.getConfig().getBoolean("join_leave_messages.enabled", true)) {
String quitMessage = plugin.getConfig().getString("join_leave_messages.quit_message", ""); String quitMessage = plugin.getConfig().getString("join_leave_messages.quit_message", "");
if (quitMessage.isEmpty()) { if (quitMessage.isEmpty()) {
@ -144,6 +150,9 @@ public class PlayerJoinListener implements Listener {
if (plugin.getConfig().getBoolean("join_settings.clear_inventory", false)) { if (plugin.getConfig().getBoolean("join_settings.clear_inventory", false)) {
player.getInventory().clear(); player.getInventory().clear();
} }
plugin.getHotbarManager().giveItems(player);
plugin.getPlayerHiderManager().giveItem(player);
} }
private void handleJoinEvents(Player player) { private void handleJoinEvents(Player player) {

View file

@ -0,0 +1,108 @@
package com.loki.lohub.managers;
import com.loki.lohub.LoHub;
import com.loki.lohub.utils.PlaceholderUtil;
import com.loki.lohub.utils.TextUtil;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.List;
public class AnnouncementManager {
private final LoHub plugin;
private final List<Announcement> announcements = new ArrayList<>();
private int currentIndex = 0;
private int taskId = -1;
public AnnouncementManager(LoHub plugin) {
this.plugin = plugin;
loadAnnouncements();
}
private void loadAnnouncements() {
announcements.clear();
ConfigurationSection section = plugin.getConfig().getConfigurationSection("announcements.announcements");
if (section == null) {
return;
}
for (String key : section.getKeys(false)) {
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)) {
return;
}
if (announcements.isEmpty()) {
return;
}
int delay = plugin.getConfig().getInt("announcements.delay", 60) * 20;
taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, this::broadcast, delay, delay);
}
public void stop() {
if (taskId != -1) {
Bukkit.getScheduler().cancelTask(taskId);
taskId = -1;
}
}
private void broadcast() {
int requiredPlayers = plugin.getConfig().getInt("announcements.required_players", 1);
if (Bukkit.getOnlinePlayers().size() < requiredPlayers) {
return;
}
if (announcements.isEmpty()) {
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)));
}
if (plugin.getConfig().getBoolean("announcements.sound.enabled", true)) {
playSound(player);
}
}
}
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);
try {
Sound sound = Sound.valueOf(soundStr);
player.playSound(player.getLocation(), sound, volume, pitch);
} catch (IllegalArgumentException e) {
plugin.getLogger().warning("Invalid sound: " + soundStr);
}
}
public void reload() {
stop();
loadAnnouncements();
start();
}
private record Announcement(String name, List<String> messages) {
}
}

View file

@ -0,0 +1,87 @@
package com.loki.lohub.managers;
import com.loki.lohub.LoHub;
import com.loki.lohub.utils.ItemBuilder;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class HotbarManager {
private final LoHub plugin;
private final Map<Integer, HotbarItem> items = new HashMap<>();
public HotbarManager(LoHub plugin) {
this.plugin = plugin;
loadItems();
}
private void loadItems() {
items.clear();
ConfigurationSection section = plugin.getConfig().getConfigurationSection("custom_join_items.items");
if (section == null) {
return;
}
for (String key : section.getKeys(false)) {
ConfigurationSection itemSection = section.getConfigurationSection(key);
if (itemSection == null) {
continue;
}
Material material = Material.getMaterial(itemSection.getString("material", "STONE"));
if (material == null) {
continue;
}
int slot = itemSection.getInt("slot", 0);
int amount = itemSection.getInt("amount", 1);
String displayName = itemSection.getString("display_name", "");
List<String> lore = itemSection.getStringList("lore");
List<String> actions = itemSection.getStringList("actions");
ItemStack item = 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)) {
return;
}
for (Map.Entry<Integer, HotbarItem> entry : items.entrySet()) {
player.getInventory().setItem(entry.getKey(), entry.getValue().item());
}
}
public void handleClick(Player player, int slot) {
HotbarItem item = items.get(slot);
if (item == null) {
return;
}
plugin.getActionManager().executeActions(player, item.actions(), false);
}
public boolean isHotbarItem(int slot) {
return items.containsKey(slot);
}
public void reload() {
loadItems();
}
private record HotbarItem(ItemStack item, List<String> actions) {
}
}

View file

@ -0,0 +1,94 @@
package com.loki.lohub.managers;
import com.loki.lohub.LoHub;
import com.loki.lohub.utils.ItemBuilder;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
public class PlayerHiderManager {
private final LoHub plugin;
private final Set<UUID> hiddenPlayers = new HashSet<>();
public PlayerHiderManager(LoHub plugin) {
this.plugin = plugin;
}
public void giveItem(Player player) {
if (!plugin.getConfig().getBoolean("player_hider.enabled", true)) {
return;
}
int slot = plugin.getConfig().getInt("player_hider.slot", 8);
player.getInventory().setItem(slot, 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;
}
int amount = plugin.getConfig().getInt(path + ".amount", 1);
String displayName = plugin.getConfig().getString(path + ".display_name", "");
List<String> lore = plugin.getConfig().getStringList(path + ".lore");
return new ItemBuilder(material)
.amount(amount)
.name(displayName)
.lore(lore)
.build();
}
public void toggle(Player player) {
if (hiddenPlayers.contains(player.getUniqueId())) {
showPlayers(player);
} else {
hidePlayers(player);
}
updateItem(player);
}
private void hidePlayers(Player player) {
hiddenPlayers.add(player.getUniqueId());
for (Player online : Bukkit.getOnlinePlayers()) {
if (!online.equals(player)) {
player.hidePlayer(plugin, online);
}
}
}
private void showPlayers(Player player) {
hiddenPlayers.remove(player.getUniqueId());
for (Player online : Bukkit.getOnlinePlayers()) {
if (!online.equals(player)) {
player.showPlayer(plugin, online);
}
}
}
private void updateItem(Player player) {
int slot = plugin.getConfig().getInt("player_hider.slot", 8);
player.getInventory().setItem(slot, getItem(player));
}
public boolean isPlayerHiderSlot(int slot) {
return plugin.getConfig().getBoolean("player_hider.enabled", true)
&& slot == plugin.getConfig().getInt("player_hider.slot", 8);
}
public void removePlayer(Player player) {
hiddenPlayers.remove(player.getUniqueId());
}
}

View file

@ -0,0 +1,112 @@
package com.loki.lohub.managers;
import com.loki.lohub.LoHub;
import com.loki.lohub.utils.PlaceholderUtil;
import com.loki.lohub.utils.TextUtil;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.Objective;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
public class ScoreboardManager {
private final LoHub plugin;
private final Map<UUID, Scoreboard> scoreboards = new HashMap<>();
private int taskId = -1;
public ScoreboardManager(LoHub plugin) {
this.plugin = plugin;
}
public void start() {
if (!plugin.getConfig().getBoolean("scoreboard.enabled", false)) {
return;
}
if (plugin.getConfig().getBoolean("scoreboard.refresh.enabled", true)) {
int rate = plugin.getConfig().getInt("scoreboard.refresh.rate", 200);
taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, this::updateAll, 0L, rate);
}
}
public void stop() {
if (taskId != -1) {
Bukkit.getScheduler().cancelTask(taskId);
taskId = -1;
}
scoreboards.clear();
}
public void setScoreboard(Player player, boolean delayed) {
if (!plugin.getConfig().getBoolean("scoreboard.enabled", false)) {
return;
}
if (delayed) {
int delay = plugin.getConfig().getInt("scoreboard.display_delay.server_enter", 60);
Bukkit.getScheduler().runTaskLater(plugin, () -> createScoreboard(player), delay);
} else {
createScoreboard(player);
}
}
private void createScoreboard(Player player) {
Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
Objective objective = scoreboard.registerNewObjective("lohub", "dummy", Component.text(""));
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
updateScoreboard(player, scoreboard, objective);
player.setScoreboard(scoreboard);
scoreboards.put(player.getUniqueId(), scoreboard);
}
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)));
List<String> lines = plugin.getConfig().getStringList("scoreboard.lines");
int score = lines.size();
for (String line : lines) {
line = PlaceholderUtil.parse(line, player);
line = TextUtil.colorize(line);
String teamName = "line_" + score;
Team team = scoreboard.getTeam(teamName);
if (team == null) {
team = scoreboard.registerNewTeam(teamName);
team.addEntry(teamName);
}
team.prefix(Component.text(line));
objective.getScore(teamName).setScore(score);
score--;
}
}
private void updateAll() {
for (Player player : Bukkit.getOnlinePlayers()) {
Scoreboard scoreboard = scoreboards.get(player.getUniqueId());
if (scoreboard != null) {
Objective objective = scoreboard.getObjective("lohub");
if (objective != null) {
updateScoreboard(player, scoreboard, objective);
}
}
}
}
public void removePlayer(Player player) {
scoreboards.remove(player.getUniqueId());
}
}

View file

@ -0,0 +1,80 @@
package com.loki.lohub.managers;
import com.loki.lohub.LoHub;
import com.loki.lohub.utils.PlaceholderUtil;
import com.loki.lohub.utils.TextUtil;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.List;
public class TablistManager {
private final LoHub plugin;
private int taskId = -1;
public TablistManager(LoHub plugin) {
this.plugin = plugin;
}
public void start() {
if (!plugin.getConfig().getBoolean("tablist.enabled", false)) {
return;
}
if (plugin.getConfig().getBoolean("tablist.refresh.enabled", true)) {
int rate = plugin.getConfig().getInt("tablist.refresh.rate", 400);
taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, this::updateAll, 0L, rate);
}
}
public void stop() {
if (taskId != -1) {
Bukkit.getScheduler().cancelTask(taskId);
taskId = -1;
}
}
public void setTablist(Player player) {
if (!plugin.getConfig().getBoolean("tablist.enabled", false)) {
return;
}
updateTablist(player);
}
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");
}
}
player.sendPlayerListHeaderAndFooter(
Component.text(header.toString()),
Component.text(footer.toString())
);
}
private void updateAll() {
for (Player player : Bukkit.getOnlinePlayers()) {
updateTablist(player);
}
}
}