12
0

Add SchematicSelector
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Signed-off-by: Chaoscaot <chaoscaot444@gmail.com>
Dieser Commit ist enthalten in:
Chaoscaot 2021-11-21 10:55:08 +01:00
Ursprung bd6e9a0246
Commit 22df0035c4
4 geänderte Dateien mit 577 neuen und 0 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,438 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.util;
import com.google.common.collect.Lists;
import de.steamwar.inventory.*;
import de.steamwar.sql.SchematicNode;
import de.steamwar.sql.SchematicType;
import de.steamwar.sql.SteamwarUser;
import lombok.*;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
public class SchematicSelector {
@Getter
private final Player player;
@Getter
private final SteamwarUser user;
@Getter
private final Consumer<SchematicNode> callback;
@Getter
private final SelectorTarget target;
@Getter
private final SelectorFilter filter = new SelectorFilter();
private SchematicSelectorInjectable injectable;
private boolean useHooks;
@Setter
@Getter
private PublicMode publicMode = PublicMode.ALL;
@Setter
@Getter
private String title = "{0} auswahl: {1}";
@Setter
@Getter
private boolean singleDirOpen;
public SchematicSelector(Player player, SelectorTarget target, Consumer<SchematicNode> callback) {
this.player = player;
this.user = SteamwarUser.get(player.getUniqueId());
this.target = target;
this.callback = callback;
this.singleDirOpen = !target.target.isDirs();
}
public SchematicSelector(Player player, SelectorTarget target, SchematicSelectorInjectable injectable, Consumer<SchematicNode> callback) {
this(player, target, callback);
this.useHooks = true;
this.injectable = injectable;
}
public void open() {
if(useHooks) {
injectable.onSelectorCreate(this);
}
openList(null, publicMode == PublicMode.PUBLIC_ONLY);
}
private void openList(SchematicNode parent, boolean publics) {
List<SchematicNode> nodes = new ArrayList<>();
if(filter.isFilter()) {
nodes.addAll(SchematicNode.getAllSchematicsAccessibleByUser(publics?0:user.getId()));
nodes.removeIf(node -> {
if(useHooks) {
injectable.onNodeFilter(this, node);
}
return !filter.matches(node);
});
if(target.target == SelectorTarget.Target.DIRECTORY) {
nodes.removeIf(node -> !node.isDir());
}
if(target.target == SelectorTarget.Target.SCHEMATIC_TYPE) {
nodes.removeIf(node -> node.isDir() || !node.getType().equals(target.type.toDB()));
}
} else {
switch (target.target) {
case DIRECTORY:
if(parent == null) {
nodes.addAll(SchematicNode.getSchematicsAccessibleByUser(publics?0:user.getId(), null));
nodes.removeIf(node -> !node.isDir());
} else {
nodes.addAll(SchematicNode.getSchematicDirectoryInNode(parent.getId()));
}
break;
case SCHEMATIC_TYPE:
nodes.addAll(SchematicNode.getAccessibleSchematicsOfTypeInParent(publics?0:user.getId(), target.type.toDB(), parent==null?0:parent.getId()));
if(target.rank >= 0) {
nodes.removeIf(node -> node.getRank() > target.rank);
}
break;
default:
nodes.addAll(SchematicNode.getSchematicsAccessibleByUser(publics?0:user.getId(), parent == null?0:parent.getId()));
}
if(singleDirOpen && nodes.size() == 1 && nodes.get(0).isDir()) {
openList(nodes.get(0), publics);
return;
}
}
List<SWListInv.SWListEntry<SchematicNode>> list = new ArrayList<>();
if(parent != null) {
list.add(new SWListInv.SWListEntry<>(new SWItem(Material.ARROW, "§eZurück", clickType -> {}), null));
}
for (SchematicNode node : nodes) {
if(node.getName().equals("//copy")) continue;
Material m;
if (node.getItem().isEmpty())
m = node.isDir()?SWItem.getMaterial("CHEST"):SWItem.getMaterial("CAULDRON_ITEM");
else
m = SWItem.getMaterial(node.getItem());
String name = "§" + (filter.getName().isEmpty()?"e":"7") + node.getName();
if(!filter.getName().isEmpty()) {
name = name.replace(filter.getName(), "§e" + filter.getName() + "§7");
}
SWItem item = new SWItem(m, name, Collections.singletonList(node.isDir() ? "§9Ordner" : "§7" + node.getSchemtype().name()), !node.isDir() && !node.getSchemtype().writeable(), click -> {
});
if(!node.isDir()) {
if(node.getRank() > 0)
item.setLore(Lists.newArrayList("§7" + node.getSchemtype().name(), "§8Rang " + node.getRank()));
}
list.add(new SWListInv.SWListEntry<>(item, node));
}
SWListInv<SchematicNode> inv = new SWListInv<>(player, MessageFormat.format(title, target.target.getName(), filter.getName().isEmpty()?(parent == null?"/":parent.generateBreadcrumbs(user)):filter.getName()), false, list, (clickType, node) -> {
if(node == null) {
openList(getParent(parent), publics);
return;
}
if(node.isDir()) {
if(filter.isFilter() && target.target.isDirs()) {
player.closeInventory();
callback.accept(node);
return;
}
filter.reset();
openList(node, publics);
return;
}
player.closeInventory();
callback.accept(node);
});
if(publicMode == PublicMode.ALL) {
if(publics) {
inv.setItem(48, Material.BUCKET, "§7Eigene Schematics", clickType -> openList(null, false));
} else {
inv.setItem(48, Material.GLASS, "§7Public Schematics", clickType -> openList(null, true));
}
}
if(target.target.isDirs()) {
inv.setItem(49, SWItem.getDye(10), "§7Ordner auswählen", clickType -> {
player.closeInventory();
callback.accept(parent);
});
}
if(!publics) {
inv.setItem(50, Material.CHEST, "§7Neuer Ordner", clickType -> createFolderIn(parent));
}
inv.setItem(51, Material.NAME_TAG, "§7Filter", clickType -> openFilter(publics));
if(useHooks) {
injectable.onListRender(this, inv, parent);
}
inv.open();
}
private void createFolderIn(SchematicNode parent) {
SWAnvilInv inv = new SWAnvilInv(player, "Ordner Erstellen");
inv.setItem(Material.CHEST);
inv.setCallback(s -> {
if(useHooks) {
if(injectable.onFolderCreate(this, s)) {
SchematicNode.createSchematicDirectory(user.getId(), s, parent==null?0:parent.getId());
openList(parent, false);
}
} else {
SchematicNode.createSchematicDirectory(user.getId(), s, parent==null?0:parent.getId());
openList(parent, false);
}
});
inv.open();
}
private void openFilter(boolean publics) {
SWInventory inv = new SWInventory(player, 9, "Filter");
InvCallback nameCallback = clickType -> {
if(clickType.isRightClick()) {
filter.setName("");
openFilter(publics);
} else {
SWAnvilInv swAnvilInv = new SWAnvilInv(player, "Name eingeben");
swAnvilInv.setItem(Material.NAME_TAG);
swAnvilInv.setCallback(s -> {
filter.setName(s);
openFilter(publics);
});
swAnvilInv.open();
}
};
if(filter.getName().isEmpty()) {
inv.setItem(0, Material.NAME_TAG, "§7Nach namen suchen...", nameCallback);
} else {
inv.setItem(0, Material.NAME_TAG, "§7Nach namen suchen...", Collections.singletonList("§7Suchwort: §e" + filter.getName()), true, nameCallback);
}
InvCallback ownerCallback = clickType -> {
if(clickType.isRightClick()) {
filter.setOwner(null);
openFilter(publics);
} else {
SWAnvilInv swAnvilInv = new SWAnvilInv(player, "Besitzer eingeben");
swAnvilInv.setItem(Material.PLAYER_HEAD);
swAnvilInv.setCallback(s -> {
filter.setOwner(SteamwarUser.get(s).getId());
openFilter(publics);
});
swAnvilInv.open();
}
};
if(filter.getOwner() == null) {
inv.setItem(1, Material.PLAYER_HEAD, "§7Nach Besitzer suchen...", ownerCallback);
} else {
SteamwarUser user = SteamwarUser.get(filter.getOwner());
SWItem item = SWItem.getPlayerSkull(user.getUserName());
item.setName("§7Nach Besitzer suchen...");
item.setEnchanted(true);
item.setLore(Collections.singletonList("§7Besitzer: §e" + user.getUserName()));
item.setCallback(ownerCallback);
inv.setItem(1, item);
}
if(target.target != SelectorTarget.Target.SCHEMATIC_TYPE) {
InvCallback schemTypeCallback = clickType -> {
if(clickType.isRightClick()) {
filter.setType(null);
openFilter(publics);
} else {
List<SWListInv.SWListEntry<SchematicType>> types = new ArrayList<>();
SchematicType.values().forEach(schematicType -> {
types.add(new SWListInv.SWListEntry<>(new SWItem(SWItem.getMaterial("STONE_BUTTON"), "§e" + schematicType.name(), Collections.emptyList(), schematicType.fightType(), n -> {}), schematicType));
});
SWListInv<SchematicType> listInv = new SWListInv<>(player, "Typ wählen...", types, (clickType1, schematicType) -> {
filter.setType(schematicType);
openFilter(publics);
});
listInv.open();
}
};
if(filter.getType() == null) {
inv.setItem(2, SWItem.getMaterial("STONE_BUTTON"), "§7Nach Typ Filtern...", schemTypeCallback);
} else {
inv.setItem(2, SWItem.getMaterial("STONE_BUTTON"), "§7Nach Typ Filtern...", Collections.singletonList("§7Typ: §e" + filter.getType().name()), true, schemTypeCallback);
}
}
InvCallback materialCallback = clickType -> {
if(clickType.isRightClick()) {
filter.setItem(null);
openFilter(publics);
} else {
UtilGui.openMaterialSelector(player, material -> {
filter.setItem(material);
openFilter(publics);
});
}
};
final int iSlot = target.target== SelectorTarget.Target.SCHEMATIC_TYPE?2:3;
if(filter.getItem() == null) {
inv.setItem(iSlot, Material.STONE, "§7Nach Item Filtern...", materialCallback);
} else {
inv.setItem(iSlot, filter.getItem(), "§7Nach Item Filtern...", Collections.singletonList("§7Item: §e" + filter.getItem().name()), true, materialCallback);
}
inv.setItem(7, SWItem.getDye(1), "§eAbbrechen", clickType -> {
filter.reset();
openList(null, publics);
});
inv.setItem(8, SWItem.getDye(10), "§eSuchen...", clickType -> {
filter.setFilter(true);
if(useHooks) {
injectable.onFilterApply(this);
}
openList(null, publics);
});
if(useHooks) {
injectable.onFilterRender(this, inv);
}
inv.open();
}
private static SchematicNode getParent(SchematicNode node) {
if(node.getParent() == null) {
return null;
}
return node.getParentNode();
}
public static SelectorTarget selectSchematic() {
return new SelectorTarget(SelectorTarget.Target.SCHEMATIC, null, -1);
}
public static SelectorTarget selectDirectory() {
return new SelectorTarget(SelectorTarget.Target.DIRECTORY, null, -1);
}
public static SelectorTarget selectSchematicNode() {
return new SelectorTarget(SelectorTarget.Target.SCHEMATIC_NODE, null, -1);
}
public static SelectorTarget selectSchematicType(SchematicType type) {
return new SelectorTarget(SelectorTarget.Target.SCHEMATIC_TYPE, type, -1);
}
public static SelectorTarget selectSchematicTypeWithRank(SchematicType type, int rank) {
return new SelectorTarget(SelectorTarget.Target.SCHEMATIC_TYPE, type, rank);
}
private static class SelectorTarget {
private final Target target;
private final SchematicType type;
private final int rank;
private SelectorTarget(Target target, SchematicType type, int rank) {
this.target = target;
this.type = type;
this.rank = rank;
}
@AllArgsConstructor
private enum Target {
SCHEMATIC("Schematic", false),
DIRECTORY("Ordner", true),
SCHEMATIC_NODE("Schematic/Ordner", true),
SCHEMATIC_TYPE("Schematic", false);
@Getter
private String name;
@Getter
private boolean dirs;
}
}
@NoArgsConstructor
@Getter
@Setter
public static class SelectorFilter {
private boolean filter;
private String name = "";
private Integer owner = null;
private SchematicType type = null;
private Material item = null;
public void reset() {
name = "";
owner = null;
type = null;
item = null;
filter = false;
}
public boolean matches(SchematicNode node) {
boolean matches = true;
if(!name.isEmpty()) {
if(!node.getName().contains(name)) {
matches = false;
}
}
if(owner != null) {
if(node.getOwner() != owner) {
matches = false;
}
}
if(type != null) {
if(node.isDir() || !node.getType().equals(type.toDB())) {
matches = false;
}
}
if(item != null) {
String i;
if(node.getItem().isEmpty()) {
i = node.isDir()?"CHEST":"CAULDRON";
} else {
i = node.getItem();
}
if(!item.name().equals(i)) {
matches = false;
}
}
return matches;
}
}
public enum PublicMode {
ALL,
PRIVATE_ONLY,
PUBLIC_ONLY
}
}

Datei anzeigen

@ -0,0 +1,39 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.util;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWListInv;
import de.steamwar.sql.SchematicNode;
public interface SchematicSelectorInjectable {
void onSelectorCreate(SchematicSelector selector);
void onListRender(SchematicSelector selector, SWListInv<SchematicNode> inv, SchematicNode parent);
void onFilterRender(SchematicSelector selector, SWInventory inventory);
void onFilterApply(SchematicSelector selector);
boolean onFolderCreate(SchematicSelector selector, String name);
void onNodeFilter(SchematicSelector selector, SchematicNode node);
}

Datei anzeigen

@ -0,0 +1,47 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.util;
import de.steamwar.inventory.SWInventory;
import de.steamwar.inventory.SWListInv;
import de.steamwar.sql.SchematicNode;
import org.bukkit.entity.Player;
public abstract class SchematicSelectorInjectableAdapter implements SchematicSelectorInjectable {
@Override
public void onSelectorCreate(SchematicSelector selector) {}
@Override
public void onListRender(SchematicSelector selector, SWListInv<SchematicNode> inv, SchematicNode parent) {}
@Override
public void onFilterRender(SchematicSelector selector, SWInventory inventory) {}
@Override
public void onFilterApply(SchematicSelector selector) {}
@Override
public boolean onFolderCreate(SchematicSelector selector, String name) {
return true;
}
@Override
public void onNodeFilter(SchematicSelector selector, SchematicNode node) {}
}

Datei anzeigen

@ -0,0 +1,53 @@
/*
* This file is a part of the SteamWar software.
*
* Copyright (C) 2021 SteamWar.de-Serverteam
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package de.steamwar.util;
import de.steamwar.inventory.SWItem;
import de.steamwar.inventory.SWListInv;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Consumer;
@UtilityClass
public class UtilGui {
public static void openMaterialSelector(Player player, Consumer<Material> callback) {
openMaterialSelector(player, "Material auswählen", callback);
}
public static void openMaterialSelector(Player player, String title, Consumer<Material> callback) {
List<SWListInv.SWListEntry<Material>> materials = new LinkedList<>();
for(Material material : Material.values()){
if(material.name().startsWith(Material.LEGACY_PREFIX))
continue;
SWItem item = new SWItem(material, "§7" + material.name());
if(item.getItemMeta() != null && material.isItem()) {
materials.add(new SWListInv.SWListEntry<>(item, material));
}
}
SWListInv<Material> swListInv = new SWListInv<>(player, title, materials, (clickType3, material) -> callback.accept(material));
swListInv.open();
}
}