Added Blueprint Bundle renaming

This commit is contained in:
tastybento 2019-05-26 19:40:13 -07:00
parent f5338bfaac
commit 2a1ce5eafa
5 changed files with 64 additions and 50 deletions

View File

@ -8,13 +8,16 @@ import org.bukkit.entity.Player;
import net.md_5.bungee.api.ChatColor; import net.md_5.bungee.api.ChatColor;
import world.bentobox.bentobox.api.addons.GameModeAddon; import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.user.User; import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.blueprints.dataobjects.BlueprintBundle;
public class NamePrompt extends StringPrompt { public class NamePrompt extends StringPrompt {
private GameModeAddon addon; private GameModeAddon addon;
private BlueprintBundle bb;
public NamePrompt(GameModeAddon addon) { public NamePrompt(GameModeAddon addon, BlueprintBundle bb) {
this.addon = addon; this.addon = addon;
this.bb = bb;
} }
@Override @Override
@ -45,7 +48,7 @@ public class NamePrompt extends StringPrompt {
} }
context.setSessionData("uniqueId", uniqueId.toString()); context.setSessionData("uniqueId", uniqueId.toString());
context.setSessionData("name", input); context.setSessionData("name", input);
return new NameSuccessPrompt(addon); return new NameSuccessPrompt(addon, bb);
} }
} }

View File

@ -15,19 +15,27 @@ import world.bentobox.bentobox.panels.BlueprintManagementPanel;
public class NameSuccessPrompt extends MessagePrompt { public class NameSuccessPrompt extends MessagePrompt {
private GameModeAddon addon; private GameModeAddon addon;
private BlueprintBundle bb;
public NameSuccessPrompt(GameModeAddon addon) { public NameSuccessPrompt(GameModeAddon addon, BlueprintBundle bb) {
this.addon = addon; this.addon = addon;
this.bb = bb;
} }
@Override @Override
public String getPromptText(ConversationContext context) { public String getPromptText(ConversationContext context) {
String name = (String) context.getSessionData("name"); String name = (String) context.getSessionData("name");
String uniqueId = (String) context.getSessionData("uniqueId"); String uniqueId = (String) context.getSessionData("uniqueId");
BlueprintBundle bb = new BlueprintBundle(); if (bb == null) {
bb.setIcon(Material.RED_WOOL); // New Blueprint bundle
bb.setUniqueId(uniqueId); bb = new BlueprintBundle();
bb.setIcon(Material.RED_WOOL);
} else {
// Rename - remove old named file
BentoBox.getInstance().getBlueprintsManager().deleteBlueprintBundle(addon, bb);
}
bb.setDisplayName(name); bb.setDisplayName(name);
bb.setUniqueId(uniqueId);
BentoBox.getInstance().getBlueprintsManager().addBlueprintBundle(addon, bb); BentoBox.getInstance().getBlueprintsManager().addBlueprintBundle(addon, bb);
BentoBox.getInstance().getBlueprintsManager().saveBlueprintBundle(addon, bb); BentoBox.getInstance().getBlueprintsManager().saveBlueprintBundle(addon, bb);
User user = User.getInstance((Player)context.getForWhom()); User user = User.getInstance((Player)context.getForWhom());

View File

@ -7,14 +7,16 @@ import java.io.IOException;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.TreeMap;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.stream.Collectors;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
@ -59,13 +61,13 @@ public class BlueprintsManager {
* Inner map's key is the uniqueId of the blueprint bundle so it's * Inner map's key is the uniqueId of the blueprint bundle so it's
* easy to get from a UI * easy to get from a UI
*/ */
private @NonNull Map<GameModeAddon, Map<String, BlueprintBundle>> blueprintBundles; private @NonNull Map<GameModeAddon, List<BlueprintBundle>> blueprintBundles;
/** /**
* Map of blueprints. There can be many blueprints per game mode addon * Map of blueprints. There can be many blueprints per game mode addon
* Inner map's key is the blueprint's name so it's easy to get from a UI * Inner map's key is the blueprint's name so it's easy to get from a UI
*/ */
private @NonNull Map<GameModeAddon, Map<String, Blueprint>> blueprints; private @NonNull Map<GameModeAddon, List<Blueprint>> blueprints;
/** /**
* Gson used for serializing/deserializing the bundle class * Gson used for serializing/deserializing the bundle class
@ -128,7 +130,10 @@ public class BlueprintsManager {
* @param addon the {@link GameModeAddon} to get the blueprint bundles. * @param addon the {@link GameModeAddon} to get the blueprint bundles.
*/ */
public Map<String, BlueprintBundle> getBlueprintBundles(@NonNull GameModeAddon addon) { public Map<String, BlueprintBundle> getBlueprintBundles(@NonNull GameModeAddon addon) {
return blueprintBundles.getOrDefault(addon, new TreeMap<>(String.CASE_INSENSITIVE_ORDER)); if (!blueprintBundles.containsKey(addon)) {
return new HashMap<>();
}
return blueprintBundles.get(addon).stream().collect(Collectors.toMap(BlueprintBundle::getUniqueId, b -> b));
} }
/** /**
@ -146,7 +151,7 @@ public class BlueprintsManager {
* @param addon the {@link GameModeAddon} to load the blueprints of. * @param addon the {@link GameModeAddon} to load the blueprints of.
*/ */
public void loadBlueprintBundles(@NonNull GameModeAddon addon) { public void loadBlueprintBundles(@NonNull GameModeAddon addon) {
blueprintBundles.put(addon, new TreeMap<>(String.CASE_INSENSITIVE_ORDER)); blueprintBundles.put(addon, new ArrayList<>());
// See if there are any schems that need converting // See if there are any schems that need converting
new SchemToBlueprint(plugin).convertSchems(addon); new SchemToBlueprint(plugin).convertSchems(addon);
@ -165,7 +170,7 @@ public class BlueprintsManager {
for (File file: Objects.requireNonNull(bpf.listFiles((dir, name) -> name.toLowerCase(Locale.ENGLISH).endsWith(BLUEPRINT_BUNDLE_SUFFIX)))) { for (File file: Objects.requireNonNull(bpf.listFiles((dir, name) -> name.toLowerCase(Locale.ENGLISH).endsWith(BLUEPRINT_BUNDLE_SUFFIX)))) {
try { try {
BlueprintBundle bb = gson.fromJson(new FileReader(file), BlueprintBundle.class); BlueprintBundle bb = gson.fromJson(new FileReader(file), BlueprintBundle.class);
blueprintBundles.get(addon).put(bb.getUniqueId(), bb); blueprintBundles.get(addon).add(bb);
plugin.log("Loaded Blueprint Bundle '" + bb.getUniqueId() + "' for " + addon.getDescription().getName()); plugin.log("Loaded Blueprint Bundle '" + bb.getUniqueId() + "' for " + addon.getDescription().getName());
loaded = true; loaded = true;
} catch (Exception e) { } catch (Exception e) {
@ -201,7 +206,8 @@ public class BlueprintsManager {
bb.setBlueprint(World.Environment.NORMAL, defaultBp); bb.setBlueprint(World.Environment.NORMAL, defaultBp);
bb.setBlueprint(World.Environment.NETHER, defaultBp); bb.setBlueprint(World.Environment.NETHER, defaultBp);
bb.setBlueprint(World.Environment.THE_END, defaultBp); bb.setBlueprint(World.Environment.THE_END, defaultBp);
blueprintBundles.get(addon).put(DEFAULT_BUNDLE_NAME, bb); bb.setUniqueId(DEFAULT_BUNDLE_NAME);
blueprintBundles.get(addon).add(bb);
this.saveBlueprintBundles(); this.saveBlueprintBundles();
} }
@ -210,7 +216,7 @@ public class BlueprintsManager {
* @param addon the {@link GameModeAddon} to load the blueprints of. * @param addon the {@link GameModeAddon} to load the blueprints of.
*/ */
public void loadBlueprints(@NonNull GameModeAddon addon) { public void loadBlueprints(@NonNull GameModeAddon addon) {
blueprints.put(addon, new HashMap<>()); blueprints.put(addon, new ArrayList<>());
File bpf = getBlueprintsFolder(addon); File bpf = getBlueprintsFolder(addon);
for (File file: Objects.requireNonNull(bpf.listFiles((dir, name) -> name.toLowerCase(Locale.ENGLISH).endsWith(BLUEPRINT_SUFFIX)))) { for (File file: Objects.requireNonNull(bpf.listFiles((dir, name) -> name.toLowerCase(Locale.ENGLISH).endsWith(BLUEPRINT_SUFFIX)))) {
String fileName = file.getName().substring(0, file.getName().length() - BLUEPRINT_SUFFIX.length()); String fileName = file.getName().substring(0, file.getName().length() - BLUEPRINT_SUFFIX.length());
@ -219,7 +225,7 @@ public class BlueprintsManager {
if (bp.getName() == null) { if (bp.getName() == null) {
bp.setName(fileName); bp.setName(fileName);
} }
blueprints.get(addon).put(bp.getName(), bp); blueprints.get(addon).add(bp);
plugin.log("Loaded blueprint '" + bp.getName() + "' for " + addon.getDescription().getName()); plugin.log("Loaded blueprint '" + bp.getName() + "' for " + addon.getDescription().getName());
} catch (Exception e) { } catch (Exception e) {
plugin.logError("Could not load blueprint " + fileName + " " + e.getMessage()); plugin.logError("Could not load blueprint " + fileName + " " + e.getMessage());
@ -234,8 +240,8 @@ public class BlueprintsManager {
* @param bp - blueprint * @param bp - blueprint
*/ */
public void addBlueprint(@NonNull GameModeAddon addon, @NonNull Blueprint bp) { public void addBlueprint(@NonNull GameModeAddon addon, @NonNull Blueprint bp) {
blueprints.putIfAbsent(addon, new HashMap<>()); blueprints.putIfAbsent(addon, new ArrayList<>());
blueprints.get(addon).put(bp.getName(), bp); blueprints.get(addon).add(bp);
plugin.log("Added blueprint '" + bp.getName() + "' for " + addon.getDescription().getName()); plugin.log("Added blueprint '" + bp.getName() + "' for " + addon.getDescription().getName());
} }
@ -268,23 +274,7 @@ public class BlueprintsManager {
* Saves all the blueprint bundles * Saves all the blueprint bundles
*/ */
public void saveBlueprintBundles() { public void saveBlueprintBundles() {
blueprintBundles.forEach((k,v) -> v.values().forEach(m -> saveBlueprintBundle(k, m))); blueprintBundles.forEach((k,v) -> v.forEach(m -> saveBlueprintBundle(k, m)));
}
/**
* Set the bundles for this addon
* @param addon - {@link GameModeAddon}
* @param map - map of bundles, key is the bundle unique id, value is the bundle
*/
public void setBlueprintBundles(@NonNull GameModeAddon addon, Map<String, BlueprintBundle> map) {
blueprintBundles.put(addon, map);
}
/**
* @return the blueprints
*/
public Map<GameModeAddon, Map<String, Blueprint>> getBlueprints() {
return blueprints;
} }
/** /**
@ -293,7 +283,10 @@ public class BlueprintsManager {
* @return Map of name and blueprint or empty map * @return Map of name and blueprint or empty map
*/ */
public Map<String, Blueprint> getBlueprints(GameModeAddon addon) { public Map<String, Blueprint> getBlueprints(GameModeAddon addon) {
return blueprints.getOrDefault(addon, new HashMap<>()); if (!blueprints.containsKey(addon)) {
return new HashMap<>();
}
return blueprints.get(addon).stream().collect(Collectors.toMap(Blueprint::getName, b -> b));
} }
/** /**
@ -319,15 +312,15 @@ public class BlueprintsManager {
plugin.logError("Tried to paste '" + name + "' but the bundle is not loaded!"); plugin.logError("Tried to paste '" + name + "' but the bundle is not loaded!");
return false; return false;
} }
BlueprintBundle bb = blueprintBundles.get(addon).get(name.toLowerCase(Locale.ENGLISH)); BlueprintBundle bb = getBlueprintBundles(addon).get(name.toLowerCase(Locale.ENGLISH));
if (!blueprints.containsKey(addon) || blueprints.get(addon).isEmpty()) { if (!blueprints.containsKey(addon) || blueprints.get(addon).isEmpty()) {
plugin.logError("No blueprints loaded for bundle '" + name + "'!"); plugin.logError("No blueprints loaded for bundle '" + name + "'!");
return false; return false;
} }
Blueprint bp = blueprints.get(addon).get(bb.getBlueprint(World.Environment.NORMAL)); Blueprint bp = getBlueprints(addon).get(bb.getBlueprint(World.Environment.NORMAL));
if (bp == null) { if (bp == null) {
// Oops, no overworld // Oops, no overworld
bp = blueprints.get(addon).get("island"); bp = getBlueprints(addon).get("island");
plugin.logError("Blueprint bundle has no normal world blueprint, using default"); plugin.logError("Blueprint bundle has no normal world blueprint, using default");
if (bp == null) { if (bp == null) {
plugin.logError("NO DEFAULT BLUEPRINT FOUND! Make sure 'island.blu' exists!"); plugin.logError("NO DEFAULT BLUEPRINT FOUND! Make sure 'island.blu' exists!");
@ -342,7 +335,7 @@ public class BlueprintsManager {
&& addon.getWorldSettings().isNetherGenerate() && addon.getWorldSettings().isNetherGenerate()
&& addon.getWorldSettings().isNetherIslands() && addon.getWorldSettings().isNetherIslands()
&& addon.getNetherWorld() != null) { && addon.getNetherWorld() != null) {
bp = blueprints.get(addon).get(bb.getBlueprint(World.Environment.NETHER)); bp = getBlueprints(addon).get(bb.getBlueprint(World.Environment.NETHER));
new BlueprintPaster(plugin, bp, addon.getNetherWorld(), island, null); new BlueprintPaster(plugin, bp, addon.getNetherWorld(), island, null);
} }
// Make end island // Make end island
@ -350,7 +343,7 @@ public class BlueprintsManager {
&& addon.getWorldSettings().isEndGenerate() && addon.getWorldSettings().isEndGenerate()
&& addon.getWorldSettings().isEndIslands() && addon.getWorldSettings().isEndIslands()
&& addon.getEndWorld() != null) { && addon.getEndWorld() != null) {
bp = blueprints.get(addon).get(bb.getBlueprint(World.Environment.THE_END)); bp = getBlueprints(addon).get(bb.getBlueprint(World.Environment.THE_END));
new BlueprintPaster(plugin, bp, addon.getEndWorld(), island, null); new BlueprintPaster(plugin, bp, addon.getEndWorld(), island, null);
} }
return true; return true;
@ -367,20 +360,23 @@ public class BlueprintsManager {
if (name == null) { if (name == null) {
return null; return null;
} }
if (blueprintBundles.containsKey(addon) && blueprintBundles.get(addon).containsKey(name.toLowerCase(Locale.ENGLISH))) { if (blueprintBundles.containsKey(addon) && getBlueprintBundles(addon).containsKey(name.toLowerCase(Locale.ENGLISH))) {
return name; return name;
} }
return null; return null;
} }
/** /**
* Adds a blueprint bundle * Adds a blueprint bundle. If a bundle with the same uniqueId exists, it will be replaced
* @param addon - the game mode addon * @param addon - the game mode addon
* @param bb - the blueprint bundle * @param bb - the blueprint bundle
*/ */
public void addBlueprintBundle(GameModeAddon addon, BlueprintBundle bb) { public void addBlueprintBundle(GameModeAddon addon, BlueprintBundle bb) {
blueprintBundles.computeIfAbsent(addon, k -> new HashMap<>()).put(bb.getUniqueId(), bb); if (blueprintBundles.containsKey(addon)) {
// Remove any bundles with the same name
blueprintBundles.get(addon).removeIf(b -> b.getUniqueId().equals(bb.getUniqueId()));
}
blueprintBundles.computeIfAbsent(addon, k -> new ArrayList<>()).add(bb);
} }
/** /**
@ -409,7 +405,7 @@ public class BlueprintsManager {
*/ */
public void deleteBlueprintBundle(@NonNull GameModeAddon addon, BlueprintBundle bb) { public void deleteBlueprintBundle(@NonNull GameModeAddon addon, BlueprintBundle bb) {
if (blueprintBundles.containsKey(addon)) { if (blueprintBundles.containsKey(addon)) {
blueprintBundles.get(addon).keySet().removeIf(k -> k.equals(bb.getUniqueId())); blueprintBundles.get(addon).removeIf(k -> k.getUniqueId().equals(bb.getUniqueId()));
} }
File bpf = getBlueprintsFolder(addon); File bpf = getBlueprintsFolder(addon);
File fileName = new File(bpf, bb.getUniqueId() + BLUEPRINT_BUNDLE_SUFFIX); File fileName = new File(bpf, bb.getUniqueId() + BLUEPRINT_BUNDLE_SUFFIX);

View File

@ -82,11 +82,17 @@ public class BlueprintManagementPanel {
plugin.getBlueprintsManager().getBlueprintBundles(addon).values().stream().limit(36) plugin.getBlueprintsManager().getBlueprintBundles(addon).values().stream().limit(36)
.forEach(bb -> pb.item(new PanelItemBuilder() .forEach(bb -> pb.item(new PanelItemBuilder()
.name(bb.getDisplayName()) .name(bb.getDisplayName())
.description(t("edit")) .description(t("edit"),
!bb.getUniqueId().equals(BlueprintsManager.DEFAULT_BUNDLE_NAME) ? t("rename") : "")
.icon(bb.getIcon()) .icon(bb.getIcon())
.clickHandler((panel, u, clickType, slot) -> { .clickHandler((panel, u, clickType, slot) -> {
u.closeInventory(); u.closeInventory();
openBB(bb); if (clickType.equals(ClickType.RIGHT) && !bb.getUniqueId().equals(BlueprintsManager.DEFAULT_BUNDLE_NAME)) {
// Rename
askForName(u.getPlayer(), addon, bb);
} else {
openBB(bb);
}
return true; return true;
}) })
.build())); .build()));
@ -256,19 +262,19 @@ public class BlueprintManagementPanel {
.icon(Material.GREEN_BANNER) .icon(Material.GREEN_BANNER)
.clickHandler((panel, u, clickType, slot) -> { .clickHandler((panel, u, clickType, slot) -> {
u.closeInventory(); u.closeInventory();
askForName(u.getPlayer(), addon); askForName(u.getPlayer(), addon, null);
return true; return true;
}) })
.build(); .build();
} }
public void askForName(Conversable whom, GameModeAddon addon) { public void askForName(Conversable whom, GameModeAddon addon, BlueprintBundle bb) {
new ConversationFactory(BentoBox.getInstance()) new ConversationFactory(BentoBox.getInstance())
.withModality(true) .withModality(true)
.withLocalEcho(false) .withLocalEcho(false)
.withPrefix(new NameConversationPrefix()) .withPrefix(new NameConversationPrefix())
.withTimeout(90) .withTimeout(90)
.withFirstPrompt(new NamePrompt(addon)) .withFirstPrompt(new NamePrompt(addon, bb))
.withEscapeSequence(t("name.quit")) .withEscapeSequence(t("name.quit"))
.buildConversation(whom).begin(); .buildConversation(whom).begin();
} }

View File

@ -237,6 +237,7 @@ commands:
end: "The End" end: "The End"
title: "Blueprint Bundle Manager" title: "Blueprint Bundle Manager"
edit: "Click to edit" edit: "Click to edit"
rename: "Right-click to rename"
edit-description: "Click to edit description" edit-description: "Click to edit description"
world-name-syntax: "[name] world" world-name-syntax: "[name] world"
world-instructions: | world-instructions: |