Compare commits
3 Commits
bd7a46c283
...
ff9133ecfa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff9133ecfa | ||
|
|
57b5b8fe84 | ||
|
|
e03c51198c |
|
|
@ -42,6 +42,8 @@ public final class PlayerUtils extends JavaPlugin {
|
||||||
pluginManager.registerEvents(new LimitArmorStands(this), this);
|
pluginManager.registerEvents(new LimitArmorStands(this), this);
|
||||||
pluginManager.registerEvents(new BlockBlockUseEvent(), this);
|
pluginManager.registerEvents(new BlockBlockUseEvent(), this);
|
||||||
pluginManager.registerEvents(new PlayerJoin(this), this);
|
pluginManager.registerEvents(new PlayerJoin(this), this);
|
||||||
|
pluginManager.registerEvents(new BookWriteEvent(), this);
|
||||||
|
pluginManager.registerEvents(new BookByteLimitListener(), this);
|
||||||
|
|
||||||
RotateBlockEvent rotateBlockEvent = new RotateBlockEvent();
|
RotateBlockEvent rotateBlockEvent = new RotateBlockEvent();
|
||||||
pluginManager.registerEvents(rotateBlockEvent, this);
|
pluginManager.registerEvents(rotateBlockEvent, this);
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ import java.util.stream.Collectors;
|
||||||
.forEach(team -> team.removePlayer(player));
|
.forEach(team -> team.removePlayer(player));
|
||||||
|
|
||||||
if (args[1].equalsIgnoreCase("off")) {
|
if (args[1].equalsIgnoreCase("off")) {
|
||||||
turnOffGlow(commandSender, player, otherPlayer);
|
turnOffGlow(commandSender, player, otherPlayer, board);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,10 +88,15 @@ import java.util.stream.Collectors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void turnOffGlow(CommandSender commandSender, Player player, boolean otherPlayer) {
|
private void turnOffGlow(CommandSender commandSender, Player player, boolean otherPlayer, Scoreboard board) {
|
||||||
player.sendRichMessage(Messages.GLOW.GLOW_OFF);
|
player.sendRichMessage(Messages.GLOW.GLOW_OFF);
|
||||||
player.setGlowing(false);
|
player.setGlowing(false);
|
||||||
|
|
||||||
|
board.getTeams().stream()
|
||||||
|
.filter(team -> team.getName().startsWith("Glow-"))
|
||||||
|
.filter(team -> team.hasPlayer(player))
|
||||||
|
.forEach(team -> team.removePlayer(player));
|
||||||
|
|
||||||
if (otherPlayer) {
|
if (otherPlayer) {
|
||||||
commandSender.sendRichMessage(Messages.GLOW.GLOW_OFF_FOR_PLAYER, Placeholder.component("player", player.name()));
|
commandSender.sendRichMessage(Messages.GLOW.GLOW_OFF_FOR_PLAYER, Placeholder.component("player", player.name()));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
package com.alttd.playerutils.event_listeners;
|
||||||
|
|
||||||
|
import com.alttd.playerutils.util.BookByteUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.HumanEntity;
|
||||||
|
import org.bukkit.entity.Item;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.ItemSpawnEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryAction;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||||
|
import org.bukkit.event.inventory.InventoryMoveItemEvent;
|
||||||
|
import org.bukkit.event.player.PlayerDropItemEvent;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class BookByteLimitListener implements Listener {
|
||||||
|
|
||||||
|
private boolean isOversizedBook(ItemStack stack) {
|
||||||
|
boolean isOversizedBook = BookByteUtils.shouldCountForBookByteLimit(stack)
|
||||||
|
&& BookByteUtils.computeBytes(stack) > BookByteUtils.MAX_BOOK_BYTES;
|
||||||
|
if (isOversizedBook) {
|
||||||
|
log.warn("Player tried to drop an oversized book");
|
||||||
|
Component message = MiniMessage.miniMessage().deserialize(
|
||||||
|
"<red>Player tried to drop an oversized book</red>");
|
||||||
|
Bukkit.broadcast(message, "staffutils.patrol");
|
||||||
|
}
|
||||||
|
return isOversizedBook;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isOversizedBook(ItemStack stack, HumanEntity humanEntity) {
|
||||||
|
boolean isOversizedBook = BookByteUtils.shouldCountForBookByteLimit(stack)
|
||||||
|
&& BookByteUtils.computeBytes(stack) > BookByteUtils.MAX_BOOK_BYTES;
|
||||||
|
if (isOversizedBook) {
|
||||||
|
log.warn("{} [{}] tried to drop an oversized book", humanEntity.getName(), humanEntity.getUniqueId());
|
||||||
|
Component message = MiniMessage.miniMessage().deserialize(
|
||||||
|
"<red>Player <player> tried to drop an oversized book</red>",
|
||||||
|
Placeholder.unparsed("player", humanEntity.getName()));
|
||||||
|
Bukkit.broadcast(message, "staffutils.patrol");
|
||||||
|
}
|
||||||
|
return isOversizedBook;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onItemSpawn(ItemSpawnEvent event) {
|
||||||
|
Item item = event.getEntity();
|
||||||
|
if (isOversizedBook(item.getItemStack())) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerDrop(PlayerDropItemEvent event) {
|
||||||
|
if (isOversizedBook(event.getItemDrop().getItemStack(), event.getPlayer())) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInventoryClick(InventoryClickEvent event) {
|
||||||
|
InventoryAction action = event.getAction();
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case PLACE_ALL, PLACE_ONE, PLACE_SOME, SWAP_WITH_CURSOR -> {
|
||||||
|
if (isOversizedBook(event.getCursor(), event.getWhoClicked())) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case MOVE_TO_OTHER_INVENTORY -> {
|
||||||
|
if (isOversizedBook(event.getCurrentItem(), event.getWhoClicked())) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case HOTBAR_SWAP -> {
|
||||||
|
ItemStack hotbarItem = event.getWhoClicked().getInventory().getItem(event.getHotbarButton());
|
||||||
|
if (isOversizedBook(hotbarItem, event.getWhoClicked())) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default -> {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInventoryDrag(InventoryDragEvent event) {
|
||||||
|
if (isOversizedBook(event.getOldCursor(), event.getWhoClicked())) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInventoryMoveItem(InventoryMoveItemEvent event) {
|
||||||
|
if (isOversizedBook(event.getItem())) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package com.alttd.playerutils.event_listeners;
|
||||||
|
|
||||||
|
import com.alttd.playerutils.util.BookByteUtils;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerEditBookEvent;
|
||||||
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class BookWriteEvent implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerEditBook(PlayerEditBookEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
|
||||||
|
BookMeta meta = event.getNewBookMeta();
|
||||||
|
|
||||||
|
int totalBytes = BookByteUtils.computeBytes(meta);
|
||||||
|
|
||||||
|
if (totalBytes > BookByteUtils.MAX_BOOK_BYTES) {
|
||||||
|
log.warn("Player {} [{}] tried to write a book with {} bytes",
|
||||||
|
player.getName(), player.getUniqueId(), totalBytes);
|
||||||
|
event.setCancelled(true);
|
||||||
|
Component message = MiniMessage.miniMessage().deserialize(
|
||||||
|
"<red>Player <player> tried to write a book with <bytes> bytes</red>",
|
||||||
|
Placeholder.unparsed("player", player.getName()), Placeholder.parsed("bytes", String.valueOf(totalBytes)));
|
||||||
|
Bukkit.broadcast(message, "staffutils.patrol");
|
||||||
|
} else if (totalBytes > BookByteUtils.BIG_BOOK_BYTES) {
|
||||||
|
log.warn("Player {} [{}] wrote a large book with {} bytes",
|
||||||
|
player.getName(), player.getUniqueId(), totalBytes);
|
||||||
|
Component message = MiniMessage.miniMessage().deserialize(
|
||||||
|
"<red>Player <player> wrote a book with <bytes> bytes</red>",
|
||||||
|
Placeholder.unparsed("player", player.getName()), Placeholder.parsed("bytes", String.valueOf(totalBytes)));
|
||||||
|
Bukkit.broadcast(message, "staffutils.patrol");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package com.alttd.playerutils.event_listeners;
|
package com.alttd.playerutils.event_listeners;
|
||||||
|
|
||||||
import com.alttd.playerutils.data_objects.GHAST_SPEED;
|
import com.alttd.playerutils.data_objects.GHAST_SPEED;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.bukkit.attribute.Attribute;
|
import org.bukkit.attribute.Attribute;
|
||||||
import org.bukkit.attribute.AttributeInstance;
|
import org.bukkit.attribute.AttributeInstance;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
|
@ -10,15 +11,13 @@ import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.entity.EntityDismountEvent;
|
import org.bukkit.event.entity.EntityDismountEvent;
|
||||||
import org.bukkit.event.entity.EntityMountEvent;
|
import org.bukkit.event.entity.EntityMountEvent;
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
public class GhastSpeedEvent implements Listener {
|
public class GhastSpeedEvent implements Listener {
|
||||||
|
|
||||||
private static final org.slf4j.Logger log = LoggerFactory.getLogger(GhastSpeedEvent.class);
|
|
||||||
|
|
||||||
private final HashMap<UUID, GHAST_SPEED> lastSetSpeed = new HashMap<>();
|
private final HashMap<UUID, GHAST_SPEED> lastSetSpeed = new HashMap<>();
|
||||||
|
|
||||||
public GhastSpeedEvent() {
|
public GhastSpeedEvent() {
|
||||||
|
|
|
||||||
106
src/main/java/com/alttd/playerutils/util/BookByteUtils.java
Normal file
106
src/main/java/com/alttd/playerutils/util/BookByteUtils.java
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
package com.alttd.playerutils.util;
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.block.ShulkerBox;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
import org.bukkit.inventory.meta.BlockStateMeta;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility to compute the UTF-8 byte size of a written book's contents.
|
||||||
|
*/
|
||||||
|
public final class BookByteUtils {
|
||||||
|
|
||||||
|
private BookByteUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// 65,000 bytes per book (below CoreProtect hard limit ~65,535)
|
||||||
|
public static final int MAX_BOOK_BYTES = 30_000;
|
||||||
|
public static final int BIG_BOOK_BYTES = 10_000;
|
||||||
|
|
||||||
|
public static boolean shouldCountForBookByteLimit(ItemStack stack) {
|
||||||
|
if (stack == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Material type = stack.getType();
|
||||||
|
if (type == Material.WRITTEN_BOOK || type == Material.WRITABLE_BOOK) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (stack.getItemMeta() instanceof BookMeta) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(stack.getItemMeta() instanceof BlockStateMeta bsm) || !(bsm.getBlockState() instanceof ShulkerBox shulker)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (ItemStack content : shulker.getInventory().getContents()) {
|
||||||
|
if (content == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Material contentType = content.getType();
|
||||||
|
if (contentType == Material.WRITTEN_BOOK || contentType == Material.WRITABLE_BOOK) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (content.getItemMeta() instanceof BookMeta) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes used by the provided BookMeta.
|
||||||
|
*/
|
||||||
|
public static int computeBytes(BookMeta meta) {
|
||||||
|
if (meta == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int totalBytes = 0;
|
||||||
|
String title = meta.getTitle();
|
||||||
|
if (title != null) {
|
||||||
|
totalBytes += title.getBytes(StandardCharsets.UTF_8).length;
|
||||||
|
}
|
||||||
|
for (Component page : meta.pages()) {
|
||||||
|
if (page == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String pageString = MiniMessage.miniMessage().serialize(page);
|
||||||
|
if (pageString.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
totalBytes += pageString.getBytes(StandardCharsets.UTF_8).length;
|
||||||
|
}
|
||||||
|
return totalBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the number of bytes used by a book item stack. If the item is not a written book, returns 0.
|
||||||
|
*/
|
||||||
|
public static int computeBytes(ItemStack stack) {
|
||||||
|
if (stack == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// Direct written book
|
||||||
|
if (stack.getItemMeta() instanceof BookMeta meta) {
|
||||||
|
int perBook = computeBytes(meta);
|
||||||
|
return perBook * Math.max(1, stack.getAmount());
|
||||||
|
}
|
||||||
|
// Shulker box: sum bytes of contained written books
|
||||||
|
if (stack.getItemMeta() instanceof BlockStateMeta bsm && bsm.getBlockState() instanceof ShulkerBox shulker) {
|
||||||
|
int total = 0;
|
||||||
|
for (ItemStack content : shulker.getInventory().getContents()) {
|
||||||
|
if (content == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (content.getItemMeta() instanceof BookMeta bookMeta) {
|
||||||
|
total += computeBytes(bookMeta) * Math.max(1, content.getAmount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user