Skip to content
2 changes: 2 additions & 0 deletions API/src/main/java/fr/maxlego08/menu/api/PacketManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public interface PacketManager {

void onEnable();

void onPostEnable();

void onDisable();

void editInventoryTitleName(@NotNull Player player, @NotNull Component title);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.jetbrains.annotations.NotNull;

import java.util.List;
import java.util.Set;
import java.util.UUID;

public interface StorageManager extends Listener {
Expand Down Expand Up @@ -35,4 +36,9 @@ public interface StorageManager extends Listener {
void storeInventory(@NotNull UUID uuid,@NotNull InventoryPlayer inventoryPlayer);

void removeInventory(@NotNull UUID uuid);

@NotNull
Set<String> getVisitedWorlds(@NotNull UUID playerId);

void markWorldVisited(@NotNull UUID playerId, @NotNull String worldName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ public interface Tables {
@NotNull String PLAYER_OPEN_INVENTORIES = "%prefix%player_open_inventories";
@NotNull String PLAYER_DATAS = "%prefix%player_datas";
@NotNull String PLAYER_INVENTORIES = "%prefix%player_inventories";
@NotNull String FIRST_WORLD_JOIN = "%prefix%first_world_join";

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package fr.maxlego08.menu.api.storage.dto;

import java.util.UUID;

public record FirstWorldJoinDTO(UUID playerId, String worldName) {
}
12 changes: 6 additions & 6 deletions API/src/main/java/fr/maxlego08/menu/api/utils/ColorUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ private ColorUtils() {
public static Color parse(@NotNull Object obj) {
switch (obj) {
case Float[] floatsArray when (floatsArray.length == 3 || floatsArray.length == 4) -> {
return getColor(floatsArray[0] * 255, floatsArray[1] * 255, floatsArray[2] * 255, floatsArray.length == 3, floatsArray[3] * 255);
return getColor(floatsArray[0] * 255, floatsArray[1] * 255, floatsArray[2] * 255, floatsArray.length == 3, floatsArray.length == 4 ? floatsArray[3] * 255 : 0);
}
case Double[] doublesArray when (doublesArray.length == 3 || doublesArray.length == 4) -> {
return getColor(doublesArray[0] * 255, doublesArray[1] * 255, doublesArray[2] * 255, doublesArray.length == 3, doublesArray[3] * 255);
return getColor(doublesArray[0] * 255, doublesArray[1] * 255, doublesArray[2] * 255, doublesArray.length == 3, doublesArray.length == 4 ? doublesArray[3] * 255 : 0);
}
case List<?> list when (list.size() == 3 || list.size() == 4) -> {
try {
Expand Down Expand Up @@ -114,14 +114,14 @@ private static int clamp(int value) {

@NotNull
private static Color getColor(double v, double v2, double v3, boolean b2, double v4) {
int r = (int) (v);
int g = (int) (v2);
int b = (int) (v3);
int r = clamp((int) (v));
int g = clamp((int) (v2));
int b = clamp((int) (v3));

if (b2) { // RGB
return Color.fromRGB(r, g, b);
} else { // RGBA
int a = (int) (v4);
int a = clamp((int) (v4));
return Color.fromARGB(a, r, g, b);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,11 +279,13 @@ private List<ItemStack> collectSessionItems(Player player, InventoryEngine inven

List<ItemStack> sessionItems = new ArrayList<>();
var playerInventory = player.getInventory();
for (int slot = 0; slot < playerInventory.getSize(); slot++) {
int storageSize = Math.min(playerInventory.getSize(), 36);
for (int slot = 0; slot < storageSize; slot++) {
if (buttonSlots.contains(slot)) continue;
ItemStack item = playerInventory.getItem(slot);
if (item != null && !item.getType().isAir()) {
sessionItems.add(item.clone());
playerInventory.setItem(slot, null);
}
}
return sessionItems;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ public CraftEngineLoader() {
public ItemStack load(@NonNull Player player, @NonNull YamlConfiguration configuration, @NonNull String path, @NonNull String materialString) {
BukkitItemDefinition custom = CraftEngineItems.byId(materialString);
if (custom == null) return null;
return custom.buildBukkitItem();
return custom.buildBukkitItem(player);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class PacketUtils implements InventoryListener, PacketManager {

private PacketAnimationListener packetAnimationListener;
private PacketTitleListener packetTitleListener;
private PacketEventClickLimiterListener packetEventClickLimiterListener;

public static final Map<UUID, FakeInventory> fakeContents = new HashMap<>();
private final MenuPlugin plugin;
Expand All @@ -57,7 +58,15 @@ public void onEnable() {
eventManager.registerListener(this.packetAnimationListener = new PacketAnimationListener(this.plugin), PacketListenerPriority.LOW);
eventManager.registerListener(this.packetTitleListener = new PacketTitleListener(), PacketListenerPriority.LOW);
if (Configuration.enablePacketEventClickLimiter){
eventManager.registerListener(new PacketEventClickLimiterListener(), PacketListenerPriority.HIGH);
this.packetEventClickLimiterListener = new PacketEventClickLimiterListener();
eventManager.registerListener(this.packetEventClickLimiterListener, PacketListenerPriority.HIGH);
}
}

@Override
public void onPostEnable() {
if (this.packetEventClickLimiterListener != null) {
this.plugin.getInventoryManager().registerInventoryListener(this.packetEventClickLimiterListener);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,18 @@
import fr.maxlego08.menu.api.utils.CompatibilityUtil;
import fr.maxlego08.menu.hooks.packetevents.animation.PacketPlayerTitleAnimation;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

public class PacketAnimationListener implements PacketListener {
private final Map<UUID, PlayerAnimationData> playerAnimationData = new HashMap<>();
private final Map<UUID, PlayerAnimationData> playerAnimationData = new ConcurrentHashMap<>();
private final MenuPlugin plugin;

public PacketAnimationListener(MenuPlugin plugin) {
Expand Down Expand Up @@ -57,7 +56,7 @@ public void setWindowId(int windowId) {
}
}

private void runInventoryTask(@NotNull Player player,@NotNull Inventory inventory,@NotNull Runnable task) {
private void runInventoryTask(@NotNull Player player, @NotNull Runnable task) {
if (Bukkit.isPrimaryThread()) {
task.run();
return;
Expand All @@ -67,24 +66,7 @@ private void runInventoryTask(@NotNull Player player,@NotNull Inventory inventor
return;
}

Location location = this.resolveSafeLocation(inventory);

if (location != null) {
this.plugin.getScheduler().runAtLocation(location, w -> task.run());
} else {
this.plugin.getScheduler().runAtEntity(player, w -> task.run());
}
}

private Location resolveSafeLocation(@NotNull Inventory inventory) {
try {
Location location = inventory.getLocation();
if (location != null && location.getWorld() != null) {
return location;
}
} catch (Exception ignored) {
}
return null;
this.plugin.getScheduler().runAtEntity(player, w -> task.run());
}

@Override
Expand All @@ -102,12 +84,10 @@ public void onPacketSend(PacketSendEvent event) {
if (data != null && data.getContainerId() == containerId) {
return;
}
Inventory topInventory = CompatibilityUtil.getTopInventory(player);
if (topInventory == null) {
return;
}

Runnable task = () -> {
Inventory topInventory = CompatibilityUtil.getTopInventory(player);
if (topInventory == null) return;
InventoryHolder holder = topInventory.getHolder();
if (holder instanceof BaseInventory baseInventory) {
TitleAnimation titleAnimation = baseInventory.getTitleAnimation();
Expand All @@ -124,25 +104,23 @@ public void onPacketSend(PacketSendEvent event) {
}
};

this.runInventoryTask(player, topInventory, task);
this.runInventoryTask(player, task);
}
case PacketType.Play.Server.CLOSE_WINDOW -> {
Player player = event.getPlayer();
if (player == null) return;
Inventory topInventory = CompatibilityUtil.getTopInventory(player);
if (topInventory == null) {
return;
}

Runnable task = () -> {
Inventory topInventory = CompatibilityUtil.getTopInventory(player);
if (topInventory == null) return;
InventoryHolder holder = topInventory.getHolder();
if (holder instanceof BaseInventory) {
UUID playerUniqueId = player.getUniqueId();
this.playerAnimationData.remove(playerUniqueId);
}
};

this.runInventoryTask(player, topInventory, task);
this.runInventoryTask(player, task);
}
case PacketType.Play.Server.WINDOW_ITEMS -> {
WrapperPlayServerWindowItems wrapper = new WrapperPlayServerWindowItems(event);
Expand All @@ -152,23 +130,15 @@ public void onPacketSend(PacketSendEvent event) {

int windowId = wrapper.getWindowId();

PlayerAnimationData data = this.playerAnimationData.get(playerUniqueId);
if (data != null && data.getWindowId() == windowId) {
PlayerAnimationData data = this.playerAnimationData.computeIfAbsent(playerUniqueId, k -> new PlayerAnimationData(0));
if (data.getWindowId() == windowId) {
return;
}

if (data == null) {
data = new PlayerAnimationData(0);
this.playerAnimationData.put(playerUniqueId, data);
}
data.setWindowId(windowId);

Inventory topInventory = CompatibilityUtil.getTopInventory(player);
if (topInventory == null) {
return;
}

Runnable task = () -> {
Inventory topInventory = CompatibilityUtil.getTopInventory(player);
if (topInventory == null) return;
InventoryHolder holder = topInventory.getHolder();
if (holder instanceof BaseInventory baseInventory && baseInventory.getPlayerTitleAnimation() instanceof PacketPlayerTitleAnimation playerTitleAnimation) {
playerTitleAnimation.setWrapperPlayServerWindowItems(wrapper);
Expand All @@ -178,7 +148,7 @@ public void onPacketSend(PacketSendEvent event) {
}
};

this.runInventoryTask(player, topInventory, task);
this.runInventoryTask(player, task);
}
default -> {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.protocol.packettype.PacketTypeCommon;
import fr.maxlego08.menu.api.InventoryListener;
import fr.maxlego08.menu.api.configuration.Configuration;
import fr.maxlego08.menu.api.engine.BaseInventory;
import fr.maxlego08.menu.api.utils.CompatibilityUtil;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

public class PacketEventClickLimiterListener implements PacketListener {
private final Map<UUID, Long> lastClickTimes = new HashMap<>();
public class PacketEventClickLimiterListener implements PacketListener, InventoryListener {
private final Map<UUID, Long> lastClickTimes = new ConcurrentHashMap<>();
private final Set<UUID> clickLimitedPlayers = ConcurrentHashMap.newKeySet();

public PacketEventClickLimiterListener() {
}

@Override
public void onPacketReceive(PacketReceiveEvent event) {
Expand All @@ -24,20 +28,16 @@ public void onPacketReceive(PacketReceiveEvent event) {
if (packetType == PacketType.Play.Client.CLICK_WINDOW) {
Player player = event.getPlayer();
if (player == null) return;
Inventory topInventory = CompatibilityUtil.getTopInventory(player);
try {
if (topInventory != null && topInventory.getHolder() instanceof BaseInventory baseInventory && baseInventory.isClickLimiterEnabled()) {
UUID playerUniqueId = player.getUniqueId();

long currentTime = System.currentTimeMillis();
Long lastClickTime = this.lastClickTimes.get(playerUniqueId);
if (lastClickTime != null && (currentTime - lastClickTime) < Configuration.packetEventClickLimiterMilliseconds) {
event.setCancelled(true);
return;
}
this.lastClickTimes.put(playerUniqueId, currentTime);
UUID playerUniqueId = player.getUniqueId();

if (this.clickLimitedPlayers.contains(playerUniqueId)) {
long currentTime = System.currentTimeMillis();
Long lastClickTime = this.lastClickTimes.get(playerUniqueId);
if (lastClickTime != null && (currentTime - lastClickTime) < Configuration.packetEventClickLimiterMilliseconds) {
event.setCancelled(true);
return;
}
} catch (Exception ignored) {
this.lastClickTimes.put(playerUniqueId, currentTime);
}

} else if (packetType == PacketType.Play.Client.CLOSE_WINDOW) {
Expand All @@ -46,4 +46,16 @@ public void onPacketReceive(PacketReceiveEvent event) {
this.lastClickTimes.remove(playerUniqueId);
}
}

@Override
public void onInventoryPostOpen(Player player, BaseInventory inventory) {
if (inventory.isClickLimiterEnabled()) {
this.clickLimitedPlayers.add(player.getUniqueId());
}
}

@Override
public void onInventoryClose(Player player, BaseInventory inventory) {
this.clickLimitedPlayers.remove(player.getUniqueId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,17 @@
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerWindowItems;
import org.bukkit.entity.Player;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

public class PacketTitleListener implements PacketListener {
private final Map<UUID, PlayerPacketInformation> playerPacketInformation = new HashMap<>();
private final Map<UUID, PlayerPacketInformation> playerPacketInformation = new ConcurrentHashMap<>();

public static class PlayerPacketInformation {
private WrapperPlayServerWindowItems wrapperPlayServerWindowItems;
private WrapperPlayServerOpenWindow wrapperPlayServerOpenWindow;
private volatile WrapperPlayServerWindowItems wrapperPlayServerWindowItems;
private volatile WrapperPlayServerOpenWindow wrapperPlayServerOpenWindow;

public WrapperPlayServerWindowItems getWrapperPlayServerWindowItems() {
return this.wrapperPlayServerWindowItems;
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/fr/maxlego08/menu/ZMenuPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,10 @@ public void onEnable() {
// this.inventoryManager.registerInventoryListener(this.packetUtils);
if (this.isActive(Plugins.PACKETEVENTS)) this.inventoryManager.registerInventoryListener(new PacketEventPlayerInventoryManager(this));

if (this.packetManager != null) {
this.packetManager.onPostEnable();
}

this.postEnable();
}

Expand Down
Loading
Loading