mirror of
https://github.com/BentoBoxWorld/Challenges.git
synced 2024-11-28 13:36:06 +01:00
Implement WebManager that will download Challenges Libraries from GitHub.
Implement GUI for selecting and downloading Challenges Libraries.
This commit is contained in:
parent
29a77147b5
commit
f611727d4e
@ -21,6 +21,7 @@ import world.bentobox.challenges.config.Settings;
|
||||
import world.bentobox.challenges.handlers.*;
|
||||
import world.bentobox.challenges.listeners.ResetListener;
|
||||
import world.bentobox.challenges.listeners.SaveListener;
|
||||
import world.bentobox.challenges.web.WebManager;
|
||||
import world.bentobox.level.Level;
|
||||
|
||||
|
||||
@ -39,6 +40,11 @@ public class ChallengesAddon extends Addon {
|
||||
|
||||
private ChallengesImportManager importManager;
|
||||
|
||||
/**
|
||||
* This class manages web content loading.
|
||||
*/
|
||||
private WebManager webManager;
|
||||
|
||||
private Settings settings;
|
||||
|
||||
private boolean hooked;
|
||||
@ -138,6 +144,9 @@ public class ChallengesAddon extends Addon {
|
||||
// Challenge import setup
|
||||
this.importManager = new ChallengesImportManager(this);
|
||||
|
||||
// Web content loading
|
||||
this.webManager = new WebManager(this);
|
||||
|
||||
List<GameModeAddon> hookedGameModes = new ArrayList<>();
|
||||
|
||||
this.getPlugin().getAddonsManager().getGameModeAddons().forEach(gameModeAddon -> {
|
||||
@ -315,6 +324,14 @@ public class ChallengesAddon extends Addon {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the webManager
|
||||
*/
|
||||
public WebManager getWebManager() {
|
||||
return this.webManager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the challenge settings.
|
||||
*/
|
||||
|
@ -126,6 +126,77 @@ public class ChallengesImportManager
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method loads downloaded challenges into memory.
|
||||
* @param user User who calls downloaded challenge loading
|
||||
* @param world Target world.
|
||||
* @param downloadString String that need to be loaded via DefaultDataHolder.
|
||||
* @return <code>true</code> if everything was successful, otherwise <code>false</code>.
|
||||
*/
|
||||
public boolean loadDownloadedChallenges(User user, World world, String downloadString)
|
||||
{
|
||||
ChallengesManager manager = this.addon.getChallengesManager();
|
||||
|
||||
// If exist any challenge or level that is bound to current world, then do not load default challenges.
|
||||
if (manager.hasAnyChallengeData(world.getName()))
|
||||
{
|
||||
if (user.isPlayer())
|
||||
{
|
||||
user.sendMessage("challenges.errors.exist-challenges-or-levels");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.addon.logWarning("challenges.errors.exist-challenges-or-levels");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// This prefix will be used to all challenges. That is a unique way how to separate challenged for
|
||||
// each game mode.
|
||||
String uniqueIDPrefix = Utils.getGameMode(world) + "_";
|
||||
DefaultDataHolder downloadedChallenges = new DefaultJSONHandler(this.addon).loadWebObject(downloadString);
|
||||
|
||||
// All new challenges should get correct ID. So we need to map it to loaded challenges.
|
||||
downloadedChallenges.getChallengeList().forEach(challenge -> {
|
||||
// Set correct challenge ID
|
||||
challenge.setUniqueId(uniqueIDPrefix + challenge.getUniqueId());
|
||||
// Set up correct level ID if it is necessary
|
||||
if (!challenge.getLevel().isEmpty())
|
||||
{
|
||||
challenge.setLevel(uniqueIDPrefix + challenge.getLevel());
|
||||
}
|
||||
// Load challenge in memory
|
||||
manager.loadChallenge(challenge, false, user, user == null);
|
||||
});
|
||||
|
||||
downloadedChallenges.getLevelList().forEach(challengeLevel -> {
|
||||
// Set correct level ID
|
||||
challengeLevel.setUniqueId(uniqueIDPrefix + challengeLevel.getUniqueId());
|
||||
// Set correct world name
|
||||
challengeLevel.setWorld(Util.getWorld(world).getName());
|
||||
// Reset names for all challenges.
|
||||
challengeLevel.setChallenges(challengeLevel.getChallenges().stream().
|
||||
map(challenge -> uniqueIDPrefix + challenge).
|
||||
collect(Collectors.toSet()));
|
||||
// Load level in memory
|
||||
manager.loadLevel(challengeLevel, false, user, user == null);
|
||||
});
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
this.addon.getChallengesManager().save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Default generation
|
||||
// ---------------------------------------------------------------------
|
||||
@ -320,6 +391,16 @@ public class ChallengesImportManager
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates and adds to list all objects from default.json file.
|
||||
* @return List of all objects from default.json that is with T instance.
|
||||
*/
|
||||
DefaultDataHolder loadWebObject(String downloadedObject)
|
||||
{
|
||||
return this.gson.fromJson(downloadedObject, DefaultDataHolder.class);
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Variables
|
||||
// ---------------------------------------------------------------------
|
||||
|
@ -53,7 +53,7 @@ public abstract class CommonGUI
|
||||
/**
|
||||
* This variable stores parent gui.
|
||||
*/
|
||||
private CommonGUI parentGUI;
|
||||
protected CommonGUI parentGUI;
|
||||
|
||||
/**
|
||||
* Variable stores Challenges addon.
|
||||
@ -136,6 +136,7 @@ public abstract class CommonGUI
|
||||
|
||||
protected static final String COMPLETE = "complete";
|
||||
|
||||
protected static final String DOWNLOAD = "download";
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Constructors
|
||||
@ -205,6 +206,40 @@ public abstract class CommonGUI
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor that inits panels with minimal requirements.
|
||||
* @param parentGUI Parent panel for current panel.
|
||||
*/
|
||||
public CommonGUI(CommonGUI parentGUI)
|
||||
{
|
||||
this.addon = parentGUI.addon;
|
||||
this.world = parentGUI.world;
|
||||
this.user = parentGUI.user;
|
||||
|
||||
this.topLabel = parentGUI.topLabel;
|
||||
this.permissionPrefix = parentGUI.permissionPrefix;
|
||||
|
||||
this.parentGUI = parentGUI;
|
||||
|
||||
this.pageIndex = 0;
|
||||
|
||||
this.returnButton = new PanelItemBuilder().
|
||||
name(this.user.getTranslation("challenges.gui.buttons.return")).
|
||||
icon(Material.OAK_DOOR).
|
||||
clickHandler((panel, user1, clickType, i) -> {
|
||||
|
||||
if (this.parentGUI == null)
|
||||
{
|
||||
this.user.closeInventory();
|
||||
return true;
|
||||
}
|
||||
|
||||
this.parentGUI.build();
|
||||
return true;
|
||||
}).build();
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Common methods
|
||||
// ---------------------------------------------------------------------
|
||||
|
@ -63,7 +63,8 @@ public class AdminGUI extends CommonGUI
|
||||
EDIT_SETTINGS,
|
||||
DEFAULT_IMPORT_CHALLENGES,
|
||||
DEFAULT_EXPORT_CHALLENGES,
|
||||
COMPLETE_WIPE
|
||||
COMPLETE_WIPE,
|
||||
LIBRARY
|
||||
}
|
||||
|
||||
|
||||
@ -122,6 +123,8 @@ public class AdminGUI extends CommonGUI
|
||||
|
||||
// Import Challenges
|
||||
panelBuilder.item(15, this.createButton(Button.DEFAULT_IMPORT_CHALLENGES));
|
||||
panelBuilder.item(24, this.createButton(Button.LIBRARY));
|
||||
|
||||
// Not added as I do not think admins should use it. It still will be able via command.
|
||||
// panelBuilder.item(33, this.createButton(Button.DEFAULT_EXPORT_CHALLENGES));
|
||||
|
||||
@ -439,6 +442,21 @@ public class AdminGUI extends CommonGUI
|
||||
|
||||
break;
|
||||
}
|
||||
case LIBRARY:
|
||||
{
|
||||
permissionSuffix = DOWNLOAD;
|
||||
|
||||
name = this.user.getTranslation("challenges.gui.buttons.admin.library");
|
||||
description = this.user.getTranslation("challenges.gui.descriptions.admin.library");
|
||||
icon = new ItemStack(Material.COBWEB);
|
||||
clickHandler = (panel, user, clickType, slot) -> {
|
||||
ListLibraryGUI.open(this);
|
||||
return true;
|
||||
};
|
||||
glow = false;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// This should never happen.
|
||||
return null;
|
||||
|
@ -0,0 +1,212 @@
|
||||
package world.bentobox.challenges.panel.admin;
|
||||
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import world.bentobox.bentobox.api.panels.PanelItem;
|
||||
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
|
||||
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.challenges.ChallengesAddon;
|
||||
import world.bentobox.challenges.panel.CommonGUI;
|
||||
import world.bentobox.challenges.utils.GuiUtils;
|
||||
import world.bentobox.challenges.web.object.LibraryEntry;
|
||||
|
||||
|
||||
/**
|
||||
* This class contains all necessary elements to create GUI that lists all challenges.
|
||||
* It allows to edit them or remove, depending on given input mode.
|
||||
*/
|
||||
public class ListLibraryGUI extends CommonGUI
|
||||
{
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Constructor
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @param parentGUI ParentGUI object.
|
||||
*/
|
||||
public ListLibraryGUI(CommonGUI parentGUI)
|
||||
{
|
||||
super(parentGUI);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param addon Addon where panel operates.
|
||||
* @param world World from which panel was created.
|
||||
* @param user User who created panel.
|
||||
* @param topLabel Command top label which creates panel (f.e. island or ai)
|
||||
* @param permissionPrefix Command permission prefix (f.e. bskyblock.)
|
||||
*/
|
||||
public ListLibraryGUI(ChallengesAddon addon,
|
||||
World world,
|
||||
User user,
|
||||
String topLabel,
|
||||
String permissionPrefix)
|
||||
{
|
||||
super(addon, world, user, topLabel, permissionPrefix, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This static method allows to easier open Library GUI.
|
||||
* @param parentGui ParentGUI object.
|
||||
*/
|
||||
public static void open(CommonGUI parentGui)
|
||||
{
|
||||
new ListLibraryGUI(parentGui).build();
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Methods
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void build()
|
||||
{
|
||||
PanelBuilder panelBuilder = new PanelBuilder().user(this.user).name(
|
||||
this.user.getTranslation("challenges.gui.title.admin.library-title"));
|
||||
|
||||
GuiUtils.fillBorder(panelBuilder);
|
||||
|
||||
List<LibraryEntry> libraryEntries = this.addon.getWebManager().getLibraryEntries();
|
||||
|
||||
final int MAX_ELEMENTS = 21;
|
||||
|
||||
if (this.pageIndex < 0)
|
||||
{
|
||||
this.pageIndex = libraryEntries.size() / MAX_ELEMENTS;
|
||||
}
|
||||
else if (this.pageIndex > (libraryEntries.size() / MAX_ELEMENTS))
|
||||
{
|
||||
this.pageIndex = 0;
|
||||
}
|
||||
|
||||
int entryIndex = MAX_ELEMENTS * this.pageIndex;
|
||||
|
||||
// I want first row to be only for navigation and return button.
|
||||
int index = 10;
|
||||
|
||||
while (entryIndex < ((this.pageIndex + 1) * MAX_ELEMENTS) &&
|
||||
entryIndex < libraryEntries.size() &&
|
||||
index < 36)
|
||||
{
|
||||
if (!panelBuilder.slotOccupied(index))
|
||||
{
|
||||
panelBuilder.item(index, this.createEntryIcon(libraryEntries.get(entryIndex++)));
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
// Navigation buttons only if necessary
|
||||
if (libraryEntries.size() > MAX_ELEMENTS)
|
||||
{
|
||||
panelBuilder.item(18, this.getButton(CommonButtons.PREVIOUS));
|
||||
panelBuilder.item(26, this.getButton(CommonButtons.NEXT));
|
||||
}
|
||||
|
||||
panelBuilder.item(44, this.returnButton);
|
||||
|
||||
panelBuilder.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method creates button for given library entry.
|
||||
* @param libraryEntry LibraryEntry which button must be created.
|
||||
* @return Entry button.
|
||||
*/
|
||||
private PanelItem createEntryIcon(LibraryEntry libraryEntry)
|
||||
{
|
||||
PanelItemBuilder itemBuilder = new PanelItemBuilder().
|
||||
name(ChatColor.translateAlternateColorCodes('&', libraryEntry.getName())).
|
||||
description(this.generateEntryDescription(libraryEntry)).
|
||||
icon(libraryEntry.getIcon()).
|
||||
glow(false);
|
||||
|
||||
itemBuilder.clickHandler((panel, user1, clickType, i) -> {
|
||||
|
||||
if (!this.blockedForDownland)
|
||||
{
|
||||
this.blockedForDownland = true;
|
||||
|
||||
this.user.sendMessage("challenges.messages.admin.start-downloading");
|
||||
|
||||
// Run download task after 5 ticks.
|
||||
this.addon.getPlugin().getServer().getScheduler().
|
||||
runTaskLaterAsynchronously(
|
||||
this.addon.getPlugin(),
|
||||
() -> this.addon.getWebManager().requestEntryGitHubData(this.user, this.world, libraryEntry),
|
||||
5L);
|
||||
|
||||
if (this.parentGUI != null)
|
||||
{
|
||||
this.parentGUI.build();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.user.closeInventory();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return itemBuilder.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method generated description for LibraryEntry object.
|
||||
* @param entry LibraryEntry object which description must be generated.
|
||||
* @return List of strings that will be placed in ItemStack lore message.
|
||||
*/
|
||||
private List<String> generateEntryDescription(LibraryEntry entry)
|
||||
{
|
||||
List<String> description = new ArrayList<>();
|
||||
|
||||
description.add(this.user.getTranslation(REFERENCE_DESCRIPTION + "library-author",
|
||||
"[author]",
|
||||
entry.getAuthor()));
|
||||
description.add(entry.getDescription());
|
||||
|
||||
description.add(this.user.getTranslation(REFERENCE_DESCRIPTION + "library-gamemode",
|
||||
"[gamemode]",
|
||||
entry.getForGameMode()));
|
||||
description.add(this.user.getTranslation(REFERENCE_DESCRIPTION + "library-lang",
|
||||
"[lang]",
|
||||
entry.getLanguage()));
|
||||
description.add(this.user.getTranslation(REFERENCE_DESCRIPTION + "library-version",
|
||||
"[version]",
|
||||
entry.getVersion()));
|
||||
|
||||
return GuiUtils.stringSplit(description,
|
||||
this.addon.getChallengesSettings().getLoreLineLength());
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Instance Variables
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* This variable will protect against spam-click.
|
||||
*/
|
||||
private boolean blockedForDownland;
|
||||
|
||||
/**
|
||||
* Reference string to description.
|
||||
*/
|
||||
private static final String REFERENCE_DESCRIPTION = "challenges.gui.descriptions.admin.";
|
||||
}
|
225
src/main/java/world/bentobox/challenges/web/WebManager.java
Normal file
225
src/main/java/world/bentobox/challenges/web/WebManager.java
Normal file
@ -0,0 +1,225 @@
|
||||
package world.bentobox.challenges.web;
|
||||
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.bukkit.World;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
import io.github.TheBusyBiscuit.GitHubWebAPI4Java.GitHubWebAPI;
|
||||
import io.github.TheBusyBiscuit.GitHubWebAPI4Java.objects.repositories.GitHubRepository;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.challenges.ChallengesAddon;
|
||||
import world.bentobox.challenges.web.object.LibraryEntry;
|
||||
|
||||
|
||||
/**
|
||||
* This class manages content downloading from web repository.
|
||||
*/
|
||||
public class WebManager
|
||||
{
|
||||
/**
|
||||
* Default constructor
|
||||
* @param addon Challenges Addon object.
|
||||
*/
|
||||
public WebManager(ChallengesAddon addon)
|
||||
{
|
||||
this.addon = addon;
|
||||
this.plugin = addon.getPlugin();
|
||||
|
||||
this.library = new ArrayList<>(0);
|
||||
|
||||
if (this.plugin.getSettings().isGithubDownloadData())
|
||||
{
|
||||
long connectionInterval = this.plugin.getSettings().getGithubConnectionInterval() * 20L * 60L;
|
||||
|
||||
if (connectionInterval <= 0)
|
||||
{
|
||||
// If below 0, it means we shouldn't run this as a repeating task.
|
||||
this.plugin.getServer().getScheduler().runTaskLaterAsynchronously(this.plugin,
|
||||
() -> this.requestCatalogGitHubData(true),
|
||||
20L);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set connection interval to be at least 60 minutes.
|
||||
connectionInterval = Math.max(connectionInterval, 60 * 20 * 60L);
|
||||
this.plugin.getServer().getScheduler().runTaskTimerAsynchronously(this.plugin,
|
||||
() -> this.requestCatalogGitHubData(true),
|
||||
20L,
|
||||
connectionInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method requests catalog entries from challenges library.
|
||||
* @param clearCache Boolean that indicates if all cached values must be cleared.
|
||||
*/
|
||||
public void requestCatalogGitHubData(boolean clearCache)
|
||||
{
|
||||
this.plugin.getWebManager().getGitHub().ifPresent(gh ->
|
||||
{
|
||||
if (this.plugin.getSettings().isLogGithubDownloadData())
|
||||
{
|
||||
this.plugin.log("Downloading data from GitHub...");
|
||||
}
|
||||
|
||||
GitHubRepository repo = new GitHubRepository(gh, "BentoBoxWorld/weblink");
|
||||
|
||||
String catalogContent = "";
|
||||
|
||||
// Downloading the data
|
||||
try
|
||||
{
|
||||
catalogContent = repo.getContent("challenges/catalog.json").getContent().replaceAll("\\n", "");
|
||||
}
|
||||
catch (IllegalAccessException e)
|
||||
{
|
||||
if (this.plugin.getSettings().isLogGithubDownloadData())
|
||||
{
|
||||
this.plugin.log("Could not connect to GitHub.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.plugin.logError("An error occurred when downloading data from GitHub...");
|
||||
this.plugin.logStacktrace(e);
|
||||
}
|
||||
|
||||
// People were concerned that the download took ages, so we need to tell them it's over now.
|
||||
if (this.plugin.getSettings().isLogGithubDownloadData())
|
||||
{
|
||||
this.plugin.log("Successfully downloaded data from GitHub.");
|
||||
}
|
||||
|
||||
// Decoding the Base64 encoded contents
|
||||
catalogContent = new String(Base64.getDecoder().decode(catalogContent),
|
||||
StandardCharsets.UTF_8);
|
||||
|
||||
/* Parsing the data */
|
||||
|
||||
// Register the catalog data
|
||||
if (!catalogContent.isEmpty())
|
||||
{
|
||||
if (clearCache)
|
||||
{
|
||||
this.library.clear();
|
||||
}
|
||||
|
||||
JsonObject catalog = new JsonParser().parse(catalogContent).getAsJsonObject();
|
||||
catalog.getAsJsonArray("challenges").forEach(gamemode ->
|
||||
this.library.add(new LibraryEntry(gamemode.getAsJsonObject())));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method requests GitHub data for given LibraryEntry object.
|
||||
* @param user User who inits request.
|
||||
* @param world Target world where challenges should be loaded.
|
||||
* @param entry Entry that contains information about requested object.
|
||||
* @return {@code true} if request was successful, {@code false} otherwise.
|
||||
*/
|
||||
public boolean requestEntryGitHubData(User user, World world, LibraryEntry entry)
|
||||
{
|
||||
Optional<GitHubWebAPI> gitAPI = this.plugin.getWebManager().getGitHub();
|
||||
|
||||
if (gitAPI.isPresent())
|
||||
{
|
||||
if (this.plugin.getSettings().isLogGithubDownloadData())
|
||||
{
|
||||
this.plugin.log("Downloading data from GitHub...");
|
||||
}
|
||||
|
||||
GitHubRepository repo = new GitHubRepository(gitAPI.get(), "BentoBoxWorld/weblink");
|
||||
|
||||
String challengeLibrary = "";
|
||||
|
||||
// Downloading the data
|
||||
try
|
||||
{
|
||||
|
||||
challengeLibrary = repo.getContent("challenges/library/" + entry.getRepository() + ".json").
|
||||
getContent().
|
||||
replaceAll("\\n", "");
|
||||
}
|
||||
catch (IllegalAccessException e)
|
||||
{
|
||||
if (this.plugin.getSettings().isLogGithubDownloadData())
|
||||
{
|
||||
this.plugin.log("Could not connect to GitHub.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.plugin.logError("An error occurred when downloading data from GitHub...");
|
||||
this.plugin.logStacktrace(e);
|
||||
}
|
||||
|
||||
// People were concerned that the download took ages, so we need to tell them it's over now.
|
||||
if (this.plugin.getSettings().isLogGithubDownloadData())
|
||||
{
|
||||
this.plugin.log("Successfully downloaded data from GitHub.");
|
||||
}
|
||||
|
||||
// Decoding the Base64 encoded contents
|
||||
challengeLibrary = new String(Base64.getDecoder().decode(challengeLibrary),
|
||||
StandardCharsets.UTF_8);
|
||||
|
||||
/* Parsing the data */
|
||||
|
||||
// Process downloaded library data
|
||||
if (!challengeLibrary.isEmpty())
|
||||
{
|
||||
this.addon.getImportManager().loadDownloadedChallenges(user, world, challengeLibrary);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Getters
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* This method returns all library entries that are downlaoded.
|
||||
* @return existing Library entries.
|
||||
*/
|
||||
public List<LibraryEntry> getLibraryEntries()
|
||||
{
|
||||
List<LibraryEntry> entries = new ArrayList<>(this.library);
|
||||
entries.sort(Comparator.comparingInt(LibraryEntry::getSlot));
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Variables
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Challenges Addon variable.
|
||||
*/
|
||||
private ChallengesAddon addon;
|
||||
|
||||
/**
|
||||
* BentoBox plugin variable.
|
||||
*/
|
||||
private BentoBox plugin;
|
||||
|
||||
/**
|
||||
* This list contains all entries that were downloaded from GitHub.
|
||||
*/
|
||||
private List<LibraryEntry> library;
|
||||
}
|
@ -0,0 +1,186 @@
|
||||
package world.bentobox.challenges.web.object;
|
||||
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.bukkit.Material;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
|
||||
/**
|
||||
* This objects allows to load each Challenges Catalog library entry.
|
||||
*/
|
||||
public class LibraryEntry
|
||||
{
|
||||
/**
|
||||
* Default constructor.
|
||||
* @param object Json Object that must be translated to LibraryEntry.
|
||||
*/
|
||||
public LibraryEntry(@NonNull JsonObject object)
|
||||
{
|
||||
this.name = object.get("name").getAsString();
|
||||
|
||||
Material material = Material.matchMaterial(object.get("icon").getAsString());
|
||||
this.icon = (material != null) ? material : Material.PAPER;
|
||||
|
||||
this.description = object.get("description").getAsString();
|
||||
this.repository = object.get("repository").getAsString();
|
||||
this.language = object.get("language").getAsString();
|
||||
|
||||
this.slot = object.get("slot").getAsInt();
|
||||
|
||||
this.forGameMode = object.get("for").getAsString();
|
||||
this.author = object.get("author").getAsString();
|
||||
this.version = object.get("version").getAsString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the name value.
|
||||
* @return the value of name.
|
||||
*/
|
||||
@NonNull
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the icon value.
|
||||
* @return the value of icon.
|
||||
*/
|
||||
@NonNull
|
||||
public Material getIcon()
|
||||
{
|
||||
return icon;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the description value.
|
||||
* @return the value of description.
|
||||
*/
|
||||
@NonNull
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the repository value.
|
||||
* @return the value of repository.
|
||||
*/
|
||||
@NonNull
|
||||
public String getRepository()
|
||||
{
|
||||
return repository;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the language value.
|
||||
* @return the value of language.
|
||||
*/
|
||||
@NonNull
|
||||
public String getLanguage()
|
||||
{
|
||||
return language;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the slot value.
|
||||
* @return the value of slot.
|
||||
*/
|
||||
@NonNull
|
||||
public int getSlot()
|
||||
{
|
||||
return slot;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the forGameMode value.
|
||||
* @return the value of forGameMode.
|
||||
*/
|
||||
@NonNull
|
||||
public String getForGameMode()
|
||||
{
|
||||
return forGameMode;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the author value.
|
||||
* @return the value of author.
|
||||
*/
|
||||
@NonNull
|
||||
public String getAuthor()
|
||||
{
|
||||
return author;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method returns the version value.
|
||||
* @return the value of version.
|
||||
*/
|
||||
@NonNull
|
||||
public String getVersion()
|
||||
{
|
||||
return version;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Section: Variables
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Name of entry object
|
||||
*/
|
||||
private @NonNull String name;
|
||||
|
||||
/**
|
||||
* Defaults to {@link Material#PAPER}.
|
||||
*/
|
||||
private @NonNull Material icon;
|
||||
|
||||
/**
|
||||
* Description of entry object.
|
||||
*/
|
||||
private @NonNull String description;
|
||||
|
||||
/**
|
||||
* File name in challenges library.
|
||||
*/
|
||||
private @NonNull String repository;
|
||||
|
||||
/**
|
||||
* Language of content.
|
||||
*/
|
||||
private @Nullable String language;
|
||||
|
||||
/**
|
||||
* Desired slot number.
|
||||
*/
|
||||
private int slot;
|
||||
|
||||
/**
|
||||
* Main GameMode for which challenges were created.
|
||||
*/
|
||||
private @Nullable String forGameMode;
|
||||
|
||||
/**
|
||||
* Author (-s) who created current configuration.
|
||||
*/
|
||||
private @Nullable String author;
|
||||
|
||||
/**
|
||||
* Version of Challenges Addon, for which challenges were created.
|
||||
*/
|
||||
private @Nullable String version;
|
||||
}
|
@ -67,6 +67,8 @@ challenges:
|
||||
select-entity: '&aSelect Entity'
|
||||
toggle-environment: '&aToggle Environment'
|
||||
edit-text-fields: '&aEdit Text Fields'
|
||||
|
||||
library-title: '&aDownloadable Libraries'
|
||||
challenges: '&6Challenges'
|
||||
game-modes: '&6Choose GameMode'
|
||||
|
||||
@ -161,6 +163,8 @@ challenges:
|
||||
default-import: 'Import Default Challenges'
|
||||
default-export: 'Export Existing Challenges'
|
||||
complete-wipe: 'Wipe Addon Databases'
|
||||
|
||||
library: 'Web Library'
|
||||
next: 'Next'
|
||||
previous: 'Previous'
|
||||
return: 'Return'
|
||||
@ -261,6 +265,14 @@ challenges:
|
||||
default-import: 'Allows to import default challenges.'
|
||||
default-export: 'Allows to export existing challenges into defaults.json file.'
|
||||
complete-wipe: 'Allows to completely clear all challenges addon databases. Includes player data!'
|
||||
|
||||
library: 'Opens GUI that shows all available public Challenges Libraries.'
|
||||
|
||||
library-author: 'by &e[author]'
|
||||
library-version: '&9Made on Challenges [version]'
|
||||
library-lang: '&aLanguage: [lang]'
|
||||
library-gamemode: '&aPrimary for [gamemode]'
|
||||
|
||||
current-value: '|&6Current value: [value].'
|
||||
enabled: 'Active'
|
||||
disabled: 'Disabled'
|
||||
@ -368,6 +380,8 @@ challenges:
|
||||
migrate-start: '&2Start migrating challenges addon data.'
|
||||
migrate-end: '&2Challenges addon data is updated to new format.'
|
||||
migrate-not: '&2All data is valid.'
|
||||
|
||||
start-downloading: '&5Starting to download and import Challenges Library.'
|
||||
you-completed-challenge: '&2You completed the [value] &r&2challenge!'
|
||||
you-repeated-challenge: '&2You repeated the [value] &r&2challenge!'
|
||||
you-repeated-challenge-multiple: '&2You repeated the [value] &r&2challenge [count] times!'
|
||||
|
Loading…
Reference in New Issue
Block a user