mirror of
https://github.com/Xiao-MoMi/Custom-Fishing.git
synced 2025-12-26 02:19:21 +00:00
gui framework
This commit is contained in:
@@ -21,7 +21,6 @@ import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import de.tr7zw.changeme.nbtapi.utils.MinecraftVersion;
|
||||
import de.tr7zw.changeme.nbtapi.utils.VersionChecker;
|
||||
import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver;
|
||||
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.util.LogUtils;
|
||||
@@ -211,8 +210,12 @@ public class CustomFishingPluginImpl extends CustomFishingPlugin {
|
||||
"org.xerial:sqlite-jdbc:3.43.0.0", mavenRepo,
|
||||
"dev.jorel:commandapi-bukkit-shade:9.2.0", mavenRepo,
|
||||
"xyz.xenondevs.invui:invui-core:1.19", "https://repo.xenondevs.xyz/releases/",
|
||||
"xyz.xenondevs.invui:inventory-access:1.19", "https://repo.xenondevs.xyz/releases/",
|
||||
"xyz.xenondevs.invui:inventory-access-r8:1.19", "https://repo.xenondevs.xyz/releases/",
|
||||
"xyz.xenondevs.invui:inventory-access-r9:1.19", "https://repo.xenondevs.xyz/releases/",
|
||||
"xyz.xenondevs.invui:inventory-access-r10:1.19", "https://repo.xenondevs.xyz/releases/",
|
||||
"xyz.xenondevs.invui:inventory-access-r11:1.19", "https://repo.xenondevs.xyz/releases/",
|
||||
"xyz.xenondevs.invui:inventory-access-r12:1.19", "https://repo.xenondevs.xyz/releases/",
|
||||
"xyz.xenondevs.invui:inventory-access-r13:1.19", "https://repo.xenondevs.xyz/releases/",
|
||||
"xyz.xenondevs.invui:inventory-access-r14:1.19", "https://repo.xenondevs.xyz/releases/",
|
||||
"xyz.xenondevs.invui:inventory-access-r15:1.19", "https://repo.xenondevs.xyz/releases/"
|
||||
|
||||
@@ -213,7 +213,7 @@ public class AdventureManagerImpl implements AdventureManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object shadedComponentToPaperComponent(Component component) {
|
||||
public Object shadedComponentToOriginalComponent(Component component) {
|
||||
Object cp;
|
||||
try {
|
||||
cp = ReflectionUtils.gsonDeserializeMethod.invoke(ReflectionUtils.gsonInstance, GsonComponentSerializer.gson().serialize(component));
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package net.momirealms.customfishing.adventure.component;
|
||||
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class Languages {
|
||||
|
||||
private static final Languages INSTANCE = new Languages();
|
||||
private final Map<String, Map<String, String>> translations = new HashMap<>();
|
||||
private Function<Player, Locale> languageProvider = Player::locale;
|
||||
private boolean serverSideTranslations = true;
|
||||
|
||||
private Languages() {
|
||||
}
|
||||
|
||||
public static Languages getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public void addLanguage(@NotNull String lang, @NotNull Map<String, String> translations) {
|
||||
this.translations.put(lang, translations);
|
||||
}
|
||||
|
||||
public void loadLanguage(@NotNull String lang, @NotNull Reader reader) throws IOException {
|
||||
var translations = new HashMap<String, String>();
|
||||
try (var jsonReader = new JsonReader(reader)) {
|
||||
jsonReader.beginObject();
|
||||
while (jsonReader.hasNext()) {
|
||||
var key = jsonReader.nextName();
|
||||
var value = jsonReader.nextString();
|
||||
translations.put(key, value);
|
||||
}
|
||||
|
||||
addLanguage(lang, translations);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadLanguage(@NotNull String lang, @NotNull File file, @NotNull Charset charset) throws IOException {
|
||||
try (var reader = new FileReader(file, charset)) {
|
||||
loadLanguage(lang, reader);
|
||||
}
|
||||
}
|
||||
|
||||
public @Nullable String getFormatString(@NotNull String lang, @NotNull String key) {
|
||||
var map = translations.get(lang);
|
||||
if (map == null)
|
||||
return null;
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
public void setLanguageProvider(@NotNull Function<Player, Locale> languageProvider) {
|
||||
this.languageProvider = languageProvider;
|
||||
}
|
||||
|
||||
public @NotNull Locale getLanguage(@NotNull Player player) {
|
||||
return languageProvider.apply(player);
|
||||
}
|
||||
|
||||
public void enableServerSideTranslations(boolean enable) {
|
||||
serverSideTranslations = enable;
|
||||
}
|
||||
|
||||
public boolean doesServerSideTranslations() {
|
||||
return serverSideTranslations;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package net.momirealms.customfishing.adventure.component;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
|
||||
public class ShadedAdventureComponentUtils {
|
||||
|
||||
private static final Style FORMATTING_TEMPLATE = Style.style()
|
||||
.color(NamedTextColor.WHITE)
|
||||
.decoration(TextDecoration.ITALIC, false)
|
||||
.decoration(TextDecoration.BOLD, false)
|
||||
.decoration(TextDecoration.STRIKETHROUGH, false)
|
||||
.decoration(TextDecoration.UNDERLINED, false)
|
||||
.decoration(TextDecoration.OBFUSCATED, false)
|
||||
.build();
|
||||
|
||||
public static Component withoutPreFormatting(Component component) {
|
||||
return component.style(component.style().merge(FORMATTING_TEMPLATE, Style.Merge.Strategy.IF_ABSENT_ON_TARGET));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package net.momirealms.customfishing.adventure.component;
|
||||
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.xenondevs.inventoryaccess.component.ComponentWrapper;
|
||||
|
||||
public class ShadedAdventureComponentWrapper implements ComponentWrapper {
|
||||
|
||||
public static final ShadedAdventureComponentWrapper EMPTY = new ShadedAdventureComponentWrapper(Component.empty());
|
||||
|
||||
private final Component component;
|
||||
|
||||
public ShadedAdventureComponentWrapper(Component component) {
|
||||
this.component = component;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String serializeToJson() {
|
||||
return GsonComponentSerializer.gson().serialize(component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ComponentWrapper localized(@NotNull String lang) {
|
||||
if (!Languages.getInstance().doesServerSideTranslations())
|
||||
return this;
|
||||
|
||||
return new ShadedAdventureComponentWrapper(ShadedAdventureShadedComponentLocalizer.getInstance().localize(lang, component));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ComponentWrapper withoutPreFormatting() {
|
||||
return new ShadedAdventureComponentWrapper(ShadedAdventureComponentUtils.withoutPreFormatting(component));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ShadedAdventureComponentWrapper clone() {
|
||||
try {
|
||||
return (ShadedAdventureComponentWrapper) super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package net.momirealms.customfishing.adventure.component;
|
||||
|
||||
import net.kyori.adventure.text.*;
|
||||
|
||||
public class ShadedAdventureShadedComponentLocalizer extends ShadedComponentLocalizer<Component> {
|
||||
|
||||
private static final ShadedAdventureShadedComponentLocalizer INSTANCE = new ShadedAdventureShadedComponentLocalizer();
|
||||
|
||||
private ShadedAdventureShadedComponentLocalizer() {
|
||||
super(Component::text);
|
||||
}
|
||||
|
||||
public static ShadedAdventureShadedComponentLocalizer getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
@Override
|
||||
public Component localize(String lang, Component component) {
|
||||
if (!(component instanceof BuildableComponent))
|
||||
throw new IllegalStateException("Component is not a BuildableComponent");
|
||||
|
||||
return localize(lang, (BuildableComponent) component);
|
||||
}
|
||||
|
||||
@SuppressWarnings("NonExtendableApiUsage")
|
||||
private <C extends BuildableComponent<C, B>, B extends ComponentBuilder<C, B>> BuildableComponent<?, ?> localize(String lang, BuildableComponent<C, B> component) {
|
||||
ComponentBuilder<?, ?> builder;
|
||||
if (component instanceof TranslatableComponent) {
|
||||
builder = localizeTranslatable(lang, (TranslatableComponent) component).toBuilder();
|
||||
} else {
|
||||
builder = component.toBuilder();
|
||||
}
|
||||
|
||||
builder.mapChildrenDeep(child -> {
|
||||
if (child instanceof TranslatableComponent)
|
||||
return localizeTranslatable(lang, (TranslatableComponent) child);
|
||||
return child;
|
||||
});
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private BuildableComponent<?, ?> localizeTranslatable(String lang, TranslatableComponent component) {
|
||||
var formatString = Languages.getInstance().getFormatString(lang, component.key());
|
||||
if (formatString == null)
|
||||
return component;
|
||||
|
||||
var children = decomposeFormatString(lang, formatString, component, component.args());
|
||||
return Component.textOfChildren(children.toArray(ComponentLike[]::new)).style(component.style());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package net.momirealms.customfishing.adventure.component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
abstract class ShadedComponentLocalizer<T> {
|
||||
|
||||
private static final Pattern FORMAT_PATTERN = Pattern.compile("%(?:(\\d+)\\$)?([A-Za-z%]|$)");
|
||||
|
||||
private Function<String, T> componentCreator;
|
||||
|
||||
public ShadedComponentLocalizer(Function<String, T> componentCreator) {
|
||||
this.componentCreator = componentCreator;
|
||||
}
|
||||
|
||||
public void setComponentCreator(Function<String, T> componentCreator) {
|
||||
this.componentCreator = componentCreator;
|
||||
}
|
||||
|
||||
public abstract T localize(String lang, T component);
|
||||
|
||||
protected List<T> decomposeFormatString(String lang, String formatString, T component, List<T> args) {
|
||||
var matcher = FORMAT_PATTERN.matcher(formatString);
|
||||
|
||||
var components = new ArrayList<T>();
|
||||
var sb = new StringBuilder();
|
||||
var nextArgIdx = 0;
|
||||
|
||||
var i = 0;
|
||||
while (matcher.find(i)) {
|
||||
var start = matcher.start();
|
||||
var end = matcher.end();
|
||||
|
||||
// check for escaped %
|
||||
var matchedStr = formatString.substring(i, start);
|
||||
if ("%%".equals(matchedStr)) {
|
||||
sb.append('%');
|
||||
} else {
|
||||
// check for invalid format, only %s is supported
|
||||
var argType = matcher.group(2);
|
||||
if (!"s".equals(argType)) {
|
||||
throw new IllegalStateException("Unsupported format: '" + matchedStr + "'");
|
||||
}
|
||||
|
||||
// retrieve argument index
|
||||
var argIdxStr = matcher.group(1);
|
||||
var argIdx = argIdxStr == null ? nextArgIdx++ : Integer.parseInt(argIdxStr) - 1;
|
||||
|
||||
// validate argument index
|
||||
if (argIdx < 0)
|
||||
throw new IllegalStateException("Invalid argument index: " + argIdx);
|
||||
|
||||
// append the text before the argument
|
||||
sb.append(formatString, i, start);
|
||||
// add text component
|
||||
components.add(componentCreator.apply(sb.toString()));
|
||||
// add argument component
|
||||
components.add(args.size() <= argIdx ? componentCreator.apply("") : localize(lang, args.get(argIdx)));
|
||||
// clear string builder
|
||||
sb.setLength(0);
|
||||
}
|
||||
|
||||
// start next search after matcher end index
|
||||
i = end;
|
||||
}
|
||||
|
||||
// append the text after the last argument
|
||||
if (i < formatString.length()) {
|
||||
sb.append(formatString, i, formatString.length());
|
||||
components.add(componentCreator.apply(sb.toString()));
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,10 @@
|
||||
package net.momirealms.customfishing.command.sub;
|
||||
|
||||
import dev.jorel.commandapi.CommandAPICommand;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.gui.SelectFileGUI;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class GUIEditorCommand {
|
||||
|
||||
@@ -8,15 +12,8 @@ public class GUIEditorCommand {
|
||||
|
||||
public CommandAPICommand getEditorCommand() {
|
||||
return new CommandAPICommand("edit")
|
||||
.withSubcommands(
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
private CommandAPICommand getLootCommand() {
|
||||
return new CommandAPICommand("loot")
|
||||
.withSubcommands(
|
||||
|
||||
);
|
||||
.executesPlayer((player, arg) -> {
|
||||
new SelectFileGUI(player, new File(CustomFishingPlugin.get().getDataFolder(), "contents"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
package net.momirealms.customfishing.gui;
|
||||
|
||||
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.adventure.component.ShadedAdventureComponentWrapper;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.util.LogUtils;
|
||||
import net.momirealms.customfishing.gui.icon.BackGroundItem;
|
||||
import net.momirealms.customfishing.gui.icon.BackToFolderItem;
|
||||
import net.momirealms.customfishing.gui.icon.NextPageItem;
|
||||
import net.momirealms.customfishing.gui.icon.PreviousPageItem;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.xenondevs.invui.gui.Gui;
|
||||
import xyz.xenondevs.invui.gui.PagedGui;
|
||||
import xyz.xenondevs.invui.gui.structure.Markers;
|
||||
import xyz.xenondevs.invui.item.Item;
|
||||
import xyz.xenondevs.invui.item.ItemProvider;
|
||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||
import xyz.xenondevs.invui.item.impl.AbstractItem;
|
||||
import xyz.xenondevs.invui.item.impl.SimpleItem;
|
||||
import xyz.xenondevs.invui.window.AnvilWindow;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class ItemEditor {
|
||||
|
||||
private static final String SEARCH = "Search";
|
||||
private final Player player;
|
||||
private final YamlConfiguration yaml;
|
||||
private String prefix;
|
||||
private final File file;
|
||||
|
||||
public ItemEditor(Player player, File file) {
|
||||
this.yaml = YamlConfiguration.loadConfiguration(file);
|
||||
this.player = player;
|
||||
this.file = file;
|
||||
this.prefix = SEARCH;
|
||||
this.reOpenWithFilter();
|
||||
}
|
||||
|
||||
public void reOpenWithFilter() {
|
||||
Item border = new SimpleItem(new ItemBuilder(Material.AIR));
|
||||
Gui upperGui = Gui.normal()
|
||||
.setStructure(
|
||||
"a # #"
|
||||
)
|
||||
.addIngredient('a', new SimpleItem(new ItemBuilder(Material.NAME_TAG).setDisplayName(prefix)))
|
||||
.addIngredient('#', border)
|
||||
.build();
|
||||
|
||||
var gui = PagedGui.items()
|
||||
.setStructure(
|
||||
"x x x x x x x x x",
|
||||
"x x x x x x x x x",
|
||||
"x x x x x x x x x",
|
||||
"# # a # c # b # #"
|
||||
)
|
||||
.addIngredient('x', Markers.CONTENT_LIST_SLOT_HORIZONTAL)
|
||||
.addIngredient('#', new BackGroundItem())
|
||||
.addIngredient('a', new PreviousPageItem())
|
||||
.addIngredient('b', new NextPageItem())
|
||||
.addIngredient('c', new BackToFolderItem(file.getParentFile()))
|
||||
.setContent(getItemList())
|
||||
.build();
|
||||
|
||||
var temp = prefix;
|
||||
var window = AnvilWindow.split()
|
||||
.setViewer(player)
|
||||
.setTitle(new ShadedAdventureComponentWrapper(
|
||||
AdventureManagerImpl.getInstance().getComponentFromMiniMessage("Select item to edit")
|
||||
))
|
||||
.addRenameHandler(s -> {
|
||||
if (s.equals(temp)) return;
|
||||
prefix = s;
|
||||
reOpenWithFilter();
|
||||
})
|
||||
.setUpperGui(upperGui)
|
||||
.setLowerGui(gui)
|
||||
.build();
|
||||
|
||||
window.open();
|
||||
}
|
||||
|
||||
public List<Item> getItemList() {
|
||||
List<Item> itemList = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : this.yaml.getValues(false).entrySet()) {
|
||||
String key = entry.getKey();
|
||||
if (entry.getValue() instanceof ConfigurationSection section) {
|
||||
if (!prefix.equals(SEARCH) && !entry.getKey().startsWith(prefix)) continue;
|
||||
String material = section.getString("material");
|
||||
if (material != null) {
|
||||
if (material.contains(":")) {
|
||||
ItemStack itemStack = CustomFishingPlugin.get().getItemManager().buildAnyPluginItemByID(player, material);
|
||||
if (itemStack != null) {
|
||||
ItemBuilder itemBuilder = new ItemBuilder(itemStack.getType());
|
||||
itemBuilder.setCustomModelData(itemStack.getItemMeta().getCustomModelData());
|
||||
itemBuilder.setCustomModelData(section.getInt("custom-model-data"));
|
||||
itemList.add(new ItemInList(key, itemBuilder, this));
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
ItemBuilder itemBuilder = new ItemBuilder(Material.valueOf(material.toUpperCase(Locale.ENGLISH)));
|
||||
itemBuilder.setCustomModelData(section.getInt("custom-model-data"));
|
||||
itemList.add(new ItemInList(key, itemBuilder, this));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
itemList.add(new ItemInList(key, new ItemBuilder(Material.STRUCTURE_VOID), this));
|
||||
}
|
||||
return itemList;
|
||||
}
|
||||
|
||||
public void removeKey(String key) {
|
||||
yaml.set(key, null);
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
yaml.save(file);
|
||||
} catch (IOException e) {
|
||||
LogUtils.warn("Failed to save file", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ItemInList extends AbstractItem {
|
||||
|
||||
private final String key;
|
||||
private final ItemBuilder itemBuilder;
|
||||
private final ItemEditor itemEditor;
|
||||
|
||||
public ItemInList(String key, ItemBuilder itemBuilder, ItemEditor itemEditor) {
|
||||
this.key = key;
|
||||
this.itemBuilder = itemBuilder;
|
||||
this.itemEditor = itemEditor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
return itemBuilder.setDisplayName(new ShadedAdventureComponentWrapper(AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
|
||||
key
|
||||
))).addLoreLines(new ShadedAdventureComponentWrapper(AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
|
||||
"<green>Left click to edit"
|
||||
))).addLoreLines(new ShadedAdventureComponentWrapper(AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
|
||||
"<red>Right click to delete"
|
||||
)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (clickType.isLeftClick()) {
|
||||
|
||||
} else if (clickType.isRightClick()) {
|
||||
this.itemEditor.removeKey(key);
|
||||
this.itemEditor.save();
|
||||
this.itemEditor.reOpenWithFilter();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package net.momirealms.customfishing.gui;
|
||||
|
||||
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.adventure.component.ShadedAdventureComponentWrapper;
|
||||
import net.momirealms.customfishing.gui.icon.*;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.xenondevs.invui.animation.impl.SequentialAnimation;
|
||||
import xyz.xenondevs.invui.gui.Gui;
|
||||
import xyz.xenondevs.invui.gui.ScrollGui;
|
||||
import xyz.xenondevs.invui.gui.SlotElement;
|
||||
import xyz.xenondevs.invui.gui.structure.Markers;
|
||||
import xyz.xenondevs.invui.item.Item;
|
||||
import xyz.xenondevs.invui.item.ItemProvider;
|
||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||
import xyz.xenondevs.invui.item.impl.AbstractItem;
|
||||
import xyz.xenondevs.invui.window.Window;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Deque;
|
||||
|
||||
public class SelectFileGUI {
|
||||
|
||||
public SelectFileGUI(Player player, File folder) {
|
||||
File[] files = folder.listFiles();
|
||||
Deque<Item> items = new ArrayDeque<>();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (file.isFile() && file.getName().endsWith(".yml")) {
|
||||
items.addLast(new FileItem(file));
|
||||
} else if (file.isDirectory()) {
|
||||
items.addFirst(new FolderItem(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Gui gui = ScrollGui.items()
|
||||
.setStructure(
|
||||
"x x x x x x x x u",
|
||||
"x x x x x x x x #",
|
||||
"x x x x x x x x b",
|
||||
"x x x x x x x x #",
|
||||
"x x x x x x x x d"
|
||||
)
|
||||
.addIngredient('x', Markers.CONTENT_LIST_SLOT_HORIZONTAL)
|
||||
.addIngredient('#', new BackGroundItem())
|
||||
.addIngredient('u', new ScrollUpItem())
|
||||
.addIngredient('d', new ScrollDownItem())
|
||||
.addIngredient('b', new BackToFolderItem(folder.getParentFile()))
|
||||
.setContent(items.stream().toList())
|
||||
.build();
|
||||
|
||||
Window window = Window.single()
|
||||
.setViewer(player)
|
||||
.setTitle(new ShadedAdventureComponentWrapper(
|
||||
AdventureManagerImpl.getInstance().getComponentFromMiniMessage("Select file")
|
||||
))
|
||||
.setGui(gui)
|
||||
.build();
|
||||
|
||||
gui.playAnimation(new SequentialAnimation(1, true), slotElement -> {
|
||||
if (slotElement instanceof SlotElement.ItemSlotElement itemSlotElement) {
|
||||
return !(itemSlotElement.getItem() instanceof Icon);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
window.open();
|
||||
}
|
||||
|
||||
public static class FileItem extends AbstractItem {
|
||||
|
||||
private final File file;
|
||||
|
||||
public FileItem(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
return new ItemBuilder(Material.PAPER).setDisplayName(new ShadedAdventureComponentWrapper(AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
|
||||
"<#FDF5E6>" + file.getName()
|
||||
)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
String path = file.getPath();
|
||||
String[] split = path.split("\\\\");
|
||||
String type = split[3];
|
||||
switch (type) {
|
||||
case "item" -> {
|
||||
new ItemEditor(player, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class FolderItem extends AbstractItem {
|
||||
|
||||
private final File file;
|
||||
|
||||
public FolderItem(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
return new ItemBuilder(Material.BOOK).setDisplayName(new ShadedAdventureComponentWrapper(AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
|
||||
"<#D2B48C><b>" + file.getName()
|
||||
)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
new SelectFileGUI(player, file);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.momirealms.customfishing.gui.icon;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.xenondevs.invui.item.ItemProvider;
|
||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||
import xyz.xenondevs.invui.item.impl.AbstractItem;
|
||||
|
||||
public class BackGroundItem extends AbstractItem implements Icon {
|
||||
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
return new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package net.momirealms.customfishing.gui.icon;
|
||||
|
||||
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.adventure.component.ShadedAdventureComponentWrapper;
|
||||
import net.momirealms.customfishing.gui.SelectFileGUI;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.xenondevs.invui.item.ItemProvider;
|
||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||
import xyz.xenondevs.invui.item.impl.AbstractItem;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class BackToFolderItem extends AbstractItem implements Icon {
|
||||
|
||||
private final File file;
|
||||
|
||||
public BackToFolderItem(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemProvider getItemProvider() {
|
||||
if (file != null && file.getPath().startsWith("plugins\\CustomFishing\\contents")) {
|
||||
return new ItemBuilder(Material.ORANGE_STAINED_GLASS_PANE)
|
||||
.setDisplayName(new ShadedAdventureComponentWrapper(AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
|
||||
"<#FF8C00>Back to parent folder"
|
||||
)))
|
||||
.setLore(List.of(new ShadedAdventureComponentWrapper(AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
|
||||
"<#FFA500>-> " + file.getName()
|
||||
))));
|
||||
} else {
|
||||
return new ItemBuilder(Material.BLACK_STAINED_GLASS_PANE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
|
||||
if (file != null && file.getPath().startsWith("plugins\\CustomFishing\\contents"))
|
||||
new SelectFileGUI(player, file);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
package net.momirealms.customfishing.gui.icon;
|
||||
|
||||
public interface Icon {
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package net.momirealms.customfishing.gui.icon;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import xyz.xenondevs.invui.gui.PagedGui;
|
||||
import xyz.xenondevs.invui.item.ItemProvider;
|
||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||
import xyz.xenondevs.invui.item.impl.controlitem.PageItem;
|
||||
|
||||
public class NextPageItem extends PageItem implements Icon {
|
||||
|
||||
public NextPageItem() {
|
||||
super(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemProvider getItemProvider(PagedGui<?> gui) {
|
||||
ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE);
|
||||
builder.setDisplayName("§7Next page")
|
||||
.addLoreLines(gui.hasNextPage()
|
||||
? "§7Go to page §e" + (gui.getCurrentPage() + 2) + "§7/§e" + gui.getPageAmount()
|
||||
: "§cThere are no more pages");
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package net.momirealms.customfishing.gui.icon;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import xyz.xenondevs.invui.gui.PagedGui;
|
||||
import xyz.xenondevs.invui.item.ItemProvider;
|
||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||
import xyz.xenondevs.invui.item.impl.controlitem.PageItem;
|
||||
|
||||
public class PreviousPageItem extends PageItem implements Icon {
|
||||
|
||||
public PreviousPageItem() {
|
||||
super(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemProvider getItemProvider(PagedGui<?> gui) {
|
||||
ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE);
|
||||
builder.setDisplayName("§7Previous page")
|
||||
.addLoreLines(gui.hasPreviousPage()
|
||||
? "§7Go to page §e" + gui.getCurrentPage() + "§7/§e" + gui.getPageAmount()
|
||||
: "§cYou can't go further back");
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package net.momirealms.customfishing.gui.icon;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import xyz.xenondevs.invui.gui.ScrollGui;
|
||||
import xyz.xenondevs.invui.item.ItemProvider;
|
||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||
import xyz.xenondevs.invui.item.impl.controlitem.ScrollItem;
|
||||
|
||||
public class ScrollDownItem extends ScrollItem implements Icon {
|
||||
|
||||
public ScrollDownItem() {
|
||||
super(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemProvider getItemProvider(ScrollGui<?> gui) {
|
||||
ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE);
|
||||
builder.setDisplayName("§7Scroll down");
|
||||
if (!gui.canScroll(1))
|
||||
builder.addLoreLines("§cYou can't scroll further down");
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package net.momirealms.customfishing.gui.icon;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import xyz.xenondevs.invui.gui.ScrollGui;
|
||||
import xyz.xenondevs.invui.item.ItemProvider;
|
||||
import xyz.xenondevs.invui.item.builder.ItemBuilder;
|
||||
import xyz.xenondevs.invui.item.impl.controlitem.ScrollItem;
|
||||
|
||||
public class ScrollUpItem extends ScrollItem implements Icon {
|
||||
|
||||
public ScrollUpItem() {
|
||||
super(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemProvider getItemProvider(ScrollGui<?> gui) {
|
||||
ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE);
|
||||
builder.setDisplayName("§7Scroll up");
|
||||
if (!gui.canScroll(-1))
|
||||
builder.addLoreLines("§cYou've reached the top");
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ package net.momirealms.customfishing.mechanic.competition.ranking;
|
||||
import net.momirealms.customfishing.api.common.Pair;
|
||||
import net.momirealms.customfishing.api.mechanic.competition.CompetitionPlayer;
|
||||
import net.momirealms.customfishing.api.mechanic.competition.Ranking;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ import net.momirealms.customfishing.api.common.Pair;
|
||||
import net.momirealms.customfishing.api.mechanic.competition.CompetitionPlayer;
|
||||
import net.momirealms.customfishing.api.mechanic.competition.Ranking;
|
||||
import net.momirealms.customfishing.storage.method.database.nosql.RedisManager;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import redis.clients.jedis.Jedis;
|
||||
import redis.clients.jedis.resps.Tuple;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user