Skip to content
This repository has been archived by the owner on Aug 3, 2024. It is now read-only.

Commit

Permalink
More improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
nulli0n committed Feb 17, 2023
1 parent 517ca82 commit a912521
Show file tree
Hide file tree
Showing 11 changed files with 343 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public interface ColumnFormer {

ColumnFormer STRING = (storageType, length) -> {
if (length < 1 || storageType == StorageType.SQLITE) {
return "TEXT NOT NULL";
return storageType == StorageType.SQLITE ? "TEXT NOT NULL" : "MEDIUMTEXT NOT NULL";
}
return "varchar(" + length + ") CHARACTER SET utf8 NOT NULL";
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package su.nexmedia.engine.api.manager;

import org.jetbrains.annotations.NotNull;
import su.nexmedia.engine.utils.Pair;
import su.nexmedia.engine.utils.StringUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.function.UnaryOperator;

public class PlaceholderMap {

private final List<Pair<String, String>> keys;

public PlaceholderMap() {
this.keys = new ArrayList<>();
}

@NotNull
public PlaceholderMap add(@NotNull String key, @NotNull String replacer) {
this.keys.add(Pair.of(key, replacer));
return this;
}

@NotNull
public UnaryOperator<String> replacer() {
String[] placeholders = new String[this.keys.size()];
String[] replaces = new String[this.keys.size()];

for (int index = 0; index < this.keys.size(); index++) {
Pair<String, String> pair = this.keys.get(index);
placeholders[index] = pair.getFirst();
replaces[index] = pair.getSecond();
}

return str -> StringUtil.replaceEach(str, placeholders, replaces);
}
}
102 changes: 56 additions & 46 deletions NexEngine/src/main/java/su/nexmedia/engine/api/menu/AbstractMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import me.clip.placeholderapi.PlaceholderAPI;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.apache.commons.lang.ArrayUtils;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
Expand All @@ -19,21 +20,20 @@
import su.nexmedia.engine.api.manager.ICleanable;
import su.nexmedia.engine.api.type.ClickType;
import su.nexmedia.engine.hooks.Hooks;
import su.nexmedia.engine.utils.Colorizer;
import su.nexmedia.engine.utils.ItemUtil;
import su.nexmedia.engine.utils.Pair;
import su.nexmedia.engine.utils.PlayerUtil;
import su.nexmedia.engine.utils.StringUtil;

import java.util.*;

public abstract class AbstractMenu<P extends NexPlugin<P>> extends AbstractListener<P> implements ICleanable {

private static final Map<Player, AbstractMenu<?>> PLAYER_MENUS = new WeakHashMap<>();

protected final UUID id;
protected final Set<Player> viewers;
protected final Map<String, MenuItem> items;
protected final Map<Player, List<MenuItem>> userItems;
protected final Map<Player, int[]> userPage;
protected final UUID id;
protected final Map<String, MenuItem> items;
protected final Map<Player, Pair<Integer, Integer>> viewersMap;

protected String title;
protected int size;
Expand Down Expand Up @@ -62,9 +62,7 @@ public AbstractMenu(@NotNull P plugin, @NotNull String title, int size) {
this.setInventoryType(InventoryType.CHEST);

this.items = new LinkedHashMap<>();
this.userItems = new WeakHashMap<>();
this.userPage = new WeakHashMap<>();
this.viewers = new HashSet<>();
this.viewersMap = new WeakHashMap<>();

this.listener = new MenuListener<>(this);
this.listener.registerListeners();
Expand All @@ -73,11 +71,9 @@ public AbstractMenu(@NotNull P plugin, @NotNull String title, int size) {

@Override
public void clear() {
this.viewers.forEach(Player::closeInventory);
this.viewers.clear();
this.viewersMap.keySet().forEach(HumanEntity::closeInventory);
this.viewersMap.clear();
this.items.clear();
this.userItems.clear();
this.userPage.clear();
this.unregisterListeners();
this.listener.unregisterListeners();
this.listener = null;
Expand Down Expand Up @@ -121,20 +117,28 @@ public boolean open(@NotNull Player player, int page) {
if (player.isSleeping()) return false;

Inventory inventory;
boolean freshOpen = false;
if (this.isViewer(player)) {
this.getUserItemsMap().remove(player);
this.resetItemsVisibility(player);
inventory = player.getOpenInventory().getTopInventory();
inventory.clear();
}
else {
inventory = this.createInventory(player);
freshOpen = true;
}

this.setPage(player, page, page);
if (!this.onPrepare(player, inventory)) return false;
if (!this.onPrepare(player, inventory)) {
this.getViewersMap().remove(player);
return false;
}
this.setItems(player, inventory);
if (!this.onReady(player, inventory)) return false;
if (this.getViewers().add(player)) {
if (!this.onReady(player, inventory)) {
this.getViewersMap().remove(player);
return false;
}
if (freshOpen) {
player.openInventory(inventory);
}
PLAYER_MENUS.put(player, this);
Expand All @@ -150,9 +154,9 @@ public void setItems(@NotNull Player player, @NotNull Inventory inventory) {
int page = this.getPage(player);
int pages = this.getPageMax(player);

List<MenuItem> items = new ArrayList<>(this.getItemsMap().values());
items.sort(Comparator.comparingInt(MenuItem::getPriority));
items.addAll(this.getUserItems(player));
List<MenuItem> items = this.getItemsMap().values().stream()
.filter(menuItem -> menuItem.isVisible(player))
.sorted(Comparator.comparingInt(MenuItem::getPriority)).toList();

for (MenuItem menuItem : items) {
if (menuItem.getType() == MenuItemType.PAGE_NEXT) {
Expand Down Expand Up @@ -195,9 +199,8 @@ public void onClick(@NotNull Player player, @Nullable ItemStack item, int slot,
}

public void onClose(@NotNull Player player, @NotNull InventoryCloseEvent e) {
this.getUserPageMap().remove(player);
this.getUserItemsMap().remove(player);
this.getViewers().remove(player);
this.getViewersMap().remove(player);
this.resetItemsVisibility(player);

PLAYER_MENUS.remove(player);

Expand All @@ -206,8 +209,15 @@ public void onClose(@NotNull Player player, @NotNull InventoryCloseEvent e) {
}
}

protected void resetItemsVisibility(@NotNull Player player) {
this.getItemsMap().values().removeIf(menuItem -> {
return menuItem instanceof WeakMenuItem weakMenuItem && weakMenuItem.getWeakPolicy().test(player);
});
this.getItemsMap().values().forEach(menuItem -> menuItem.resetVisibility(player));
}

public boolean isViewer(@NotNull Player player) {
return this.getViewers().contains(player);
return this.getViewersMap().containsKey(player);
}

@NotNull
Expand All @@ -231,11 +241,6 @@ public Inventory createInventory(@NotNull Player player) {
}
}

@NotNull
public List<MenuItem> getUserItems(@NotNull Player player) {
return this.getUserItemsMap().computeIfAbsent(player, p -> new ArrayList<>());
}

@Nullable
public MenuItem getItem(@NotNull String id) {
return this.getItemsMap().get(id.toLowerCase());
Expand All @@ -250,39 +255,49 @@ public MenuItem getItem(int slot) {

@Nullable
public MenuItem getItem(@NotNull Player player, int slot) {
return this.getUserItems(player).stream()
.filter(item -> ArrayUtils.contains(item.getSlots(), slot))
return this.getItemsMap().values().stream()
.filter(menuItem -> ArrayUtils.contains(menuItem.getSlots(), slot) && menuItem.isVisible(player))
.max(Comparator.comparingInt(MenuItem::getPriority)).orElse(this.getItem(slot));
}

public void addItem(@NotNull ItemStack item, int... slots) {
this.addItem(new MenuItem(item, slots));
}

@Deprecated
public void addItem(@NotNull Player player, @NotNull ItemStack item, int... slots) {
this.addItem(player, new MenuItem(item, slots));
//this.addItem(player, new MenuItem(item, slots));
this.addWeakItem(player, item, slots);
}

public void addItem(@NotNull MenuItem menuItem) {
this.getItemsMap().put(menuItem.getId(), menuItem);
}

@Deprecated
public void addItem(@NotNull Player player, @NotNull MenuItem menuItem) {
this.getUserItems(player).add(menuItem);
WeakMenuItem weakMenuItem = new WeakMenuItem(player, menuItem.getItem(), menuItem.getSlots());
weakMenuItem.setClickHandler(menuItem.getClickHandler());
weakMenuItem.clickCommands = menuItem.clickCommands;
this.addItem(weakMenuItem);
}

public void addWeakItem(@NotNull Player player, @NotNull ItemStack item, int... slots) {
this.addItem(new WeakMenuItem(player, item, slots));
}

public int getPage(@NotNull Player player) {
return this.getUserPageMap().getOrDefault(player, new int[]{-1, -1})[0];
return this.getViewersMap().getOrDefault(player, Pair.of(-1,-1)).getFirst();
}

public int getPageMax(@NotNull Player player) {
return this.getUserPageMap().getOrDefault(player, new int[]{-1, -1})[1];
return this.getViewersMap().getOrDefault(player, Pair.of(-1,-1)).getSecond();
}

public void setPage(@NotNull Player player, int pageCurrent, int pageMax) {
pageCurrent = Math.max(1, pageCurrent);
pageMax = Math.max(1, pageMax);
this.getUserPageMap().put(player, new int[]{Math.min(pageCurrent, pageMax), pageMax});
this.getViewersMap().put(player, Pair.of(Math.min(pageCurrent, pageMax), pageMax));
}

@NotNull
Expand All @@ -305,7 +320,7 @@ public String getTitle(@NotNull Player player) {
}

public void setTitle(@NotNull String title) {
this.title = StringUtil.color(title);
this.title = Colorizer.apply(title);
}

public int getSize() {
Expand All @@ -331,18 +346,13 @@ public Map<String, MenuItem> getItemsMap() {
}

@NotNull
public Map<Player, List<MenuItem>> getUserItemsMap() {
return userItems;
}

@NotNull
public Map<Player, int[]> getUserPageMap() {
return userPage;
public Set<Player> getViewers() {
return this.getViewersMap().keySet();
}

@NotNull
public Set<Player> getViewers() {
return viewers;
public Map<Player, Pair<Integer, Integer>> getViewersMap() {
return viewersMap;
}

public boolean destroyWhenNoViewers() {
Expand Down
71 changes: 69 additions & 2 deletions NexEngine/src/main/java/su/nexmedia/engine/api/menu/MenuItem.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
package su.nexmedia.engine.api.menu;

import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import su.nexmedia.engine.api.type.ClickType;

import java.util.*;
import java.util.function.Predicate;

public class MenuItem {

protected final String id;
protected final Enum<?> type;

protected int priority;
protected int priority;
protected ItemStack item;
protected int[] slots;
protected int[] slots;
protected MenuItemVisibility visibility;
protected Map<UUID, MenuItemVisibility> personalVisibility;
protected Predicate<Player> visibilityPolicy;

protected MenuClick clickHandler;
protected Map<ClickType, List<String>> clickCommands;

Expand Down Expand Up @@ -51,6 +57,9 @@ public MenuItem(
this.setPriority(priority);
this.setSlots(slots);
this.setItem(item);
this.personalVisibility = new HashMap<>();
this.setVisibility(MenuItemVisibility.VISIBLE);
this.setVisibilityPolicy(null);
this.clickCommands = clickCommands;
}

Expand Down Expand Up @@ -89,6 +98,64 @@ public void setItem(@NotNull ItemStack item) {
this.item = new ItemStack(item);
}

@NotNull
public MenuItemVisibility getVisibility() {
return visibility;
}

public void setVisibility(@NotNull MenuItemVisibility visibility) {
this.visibility = visibility;
}

@NotNull
public Map<UUID, MenuItemVisibility> getPersonalVisibility() {
return personalVisibility;
}

@Nullable
public Predicate<Player> getVisibilityPolicy() {
return visibilityPolicy;
}

public void setVisibilityPolicy(@Nullable Predicate<Player> visibilityPolicy) {
this.visibilityPolicy = visibilityPolicy;
}

@NotNull
public MenuItemVisibility getPersonalVisibility(@NotNull Player player) {
return this.getPersonalVisibility().getOrDefault(player.getUniqueId(), this.getVisibility());
}

public void setPersonalVisibility(@NotNull Player player, @NotNull MenuItemVisibility visibility) {
this.getPersonalVisibility().put(player.getUniqueId(), visibility);
}

public void hideFrom(@NotNull Player player) {
this.setPersonalVisibility(player, MenuItemVisibility.HIDDEN);
}

public void showFor(@NotNull Player player) {
this.setPersonalVisibility(player, MenuItemVisibility.VISIBLE);
}

public void resetVisibility(@NotNull Player player) {
this.getPersonalVisibility().remove(player.getUniqueId());
}

public boolean isVisible(@NotNull Player player) {
MenuItemVisibility personal = this.getPersonalVisibility(player);
MenuItemVisibility global = this.getVisibility();
if (global == MenuItemVisibility.HIDDEN && personal == MenuItemVisibility.VISIBLE) {
return true;
}
else if (global == MenuItemVisibility.VISIBLE && personal == MenuItemVisibility.HIDDEN) {
return false;
}

Predicate<Player> policy = this.getVisibilityPolicy();
return policy == null || policy.test(player);
}

@Nullable
public MenuClick getClickHandler() {
return clickHandler;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package su.nexmedia.engine.api.menu;

public enum MenuItemVisibility {
VISIBLE, HIDDEN
}
Loading

0 comments on commit a912521

Please sign in to comment.