mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-23 03:05:16 +01:00
Added Credits GUI for addons and BentoBox
Implements https://github.com/BentoBoxWorld/BentoBox/issues/993
This commit is contained in:
parent
856572941e
commit
551975d6c9
@ -1,24 +1,28 @@
|
||||
package world.bentobox.bentobox.managers;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonParser;
|
||||
import io.github.TheBusyBiscuit.GitHubWebAPI4Java.GitHubWebAPI;
|
||||
import io.github.TheBusyBiscuit.GitHubWebAPI4Java.objects.repositories.GitHubContributor;
|
||||
import io.github.TheBusyBiscuit.GitHubWebAPI4Java.objects.repositories.GitHubRepository;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.Settings;
|
||||
import world.bentobox.bentobox.web.catalog.CatalogEntry;
|
||||
import world.bentobox.bentobox.web.credits.Contributor;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.google.gson.JsonParseException;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import io.github.TheBusyBiscuit.GitHubWebAPI4Java.GitHubWebAPI;
|
||||
import io.github.TheBusyBiscuit.GitHubWebAPI4Java.objects.repositories.GitHubRepository;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.Settings;
|
||||
import world.bentobox.bentobox.web.catalog.CatalogEntry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Handles web-related stuff.
|
||||
@ -32,11 +36,13 @@ public class WebManager {
|
||||
private @Nullable GitHubWebAPI gitHub;
|
||||
private @NonNull List<CatalogEntry> addonsCatalog;
|
||||
private @NonNull List<CatalogEntry> gamemodesCatalog;
|
||||
private @NonNull Map<String, List<Contributor>> contributors;
|
||||
|
||||
public WebManager(@NonNull BentoBox plugin) {
|
||||
this.plugin = plugin;
|
||||
this.addonsCatalog = new ArrayList<>();
|
||||
this.gamemodesCatalog = new ArrayList<>();
|
||||
this.contributors = new HashMap<>();
|
||||
|
||||
// Setup the GitHub connection
|
||||
if (plugin.getSettings().isGithubDownloadData()) {
|
||||
@ -45,43 +51,82 @@ public class WebManager {
|
||||
long connectionInterval = plugin.getSettings().getGithubConnectionInterval() * 20L * 60L;
|
||||
if (connectionInterval <= 0) {
|
||||
// If below 0, it means we shouldn't run this as a repeating task.
|
||||
plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, () -> requestGitHubData(true), 20L);
|
||||
plugin.getServer().getScheduler().runTaskLaterAsynchronously(plugin, this::requestGitHubData, 20L);
|
||||
} else {
|
||||
// Set connection interval to be at least 60 minutes.
|
||||
connectionInterval = Math.max(connectionInterval, 60 * 20 * 60L);
|
||||
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, () -> requestGitHubData(true), 20L, connectionInterval);
|
||||
plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, this::requestGitHubData, 20L, connectionInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void requestGitHubData(boolean clearCache) {
|
||||
public void requestGitHubData() {
|
||||
getGitHub().ifPresent(gh -> {
|
||||
if (plugin.getSettings().isLogGithubDownloadData()) {
|
||||
plugin.log("Downloading data from GitHub...");
|
||||
plugin.log("Updating the Catalog...");
|
||||
}
|
||||
GitHubRepository repo;
|
||||
GitHubRepository weblinkRepo;
|
||||
try {
|
||||
repo = new GitHubRepository(gh, "BentoBoxWorld/weblink");
|
||||
weblinkRepo = new GitHubRepository(gh, "BentoBoxWorld/weblink");
|
||||
} catch (Exception e) {
|
||||
plugin.logError("An unhandled exception occurred when trying to connect to GitHub...");
|
||||
plugin.logError("An unhandled exception occurred when connecting to the GitHub weblink..");
|
||||
plugin.logStacktrace(e);
|
||||
|
||||
// Stop the execution of the method right away.
|
||||
return;
|
||||
weblinkRepo = null;
|
||||
}
|
||||
|
||||
if (weblinkRepo != null) {
|
||||
// Downloading the data
|
||||
String tagsContent = getContent(repo, "catalog/tags.json");
|
||||
String topicsContent = getContent(repo, "catalog/topics.json");
|
||||
String catalogContent = getContent(repo, "catalog/catalog.json");
|
||||
String tagsContent = getContent(weblinkRepo, "catalog/tags.json");
|
||||
String topicsContent = getContent(weblinkRepo, "catalog/topics.json");
|
||||
String catalogContent = getContent(weblinkRepo, "catalog/catalog.json");
|
||||
|
||||
/* Parsing the data */
|
||||
parseCatalogContent(tagsContent, topicsContent, catalogContent);
|
||||
}
|
||||
|
||||
if (plugin.getSettings().isLogGithubDownloadData()) {
|
||||
plugin.log("Updating Contributors information...");
|
||||
}
|
||||
|
||||
/* Download the contributors */
|
||||
List<String> repositories = new ArrayList<>();
|
||||
// Gather all the repositories of installed addons and or catalog entries.
|
||||
repositories.add("BentoBoxWorld/BentoBox");
|
||||
repositories.addAll(plugin.getAddonsManager().getEnabledAddons()
|
||||
.stream().map(addon -> addon.getDescription().getRepository())
|
||||
.filter(repo -> !repo.isEmpty())
|
||||
.collect(Collectors.toList()));
|
||||
repositories.addAll(addonsCatalog.stream().map(CatalogEntry::getRepository)
|
||||
.filter(repo -> !repositories.contains(repo))
|
||||
.collect(Collectors.toList()));
|
||||
repositories.addAll(gamemodesCatalog.stream().map(CatalogEntry::getRepository)
|
||||
.filter(repo -> !repositories.contains(repo))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
for (String repository : repositories) {
|
||||
GitHubRepository addonRepo;
|
||||
try {
|
||||
addonRepo = new GitHubRepository(gh, repository);
|
||||
} catch (Exception e) {
|
||||
plugin.logError("An unhandled exception occurred when gathering contributors data from the '" + repository + "' repository...");
|
||||
plugin.logStacktrace(e);
|
||||
addonRepo = null;
|
||||
}
|
||||
if (addonRepo != null) {
|
||||
plugin.log("Gathering contribution data for: " + repository);
|
||||
gatherContributors(addonRepo);
|
||||
}
|
||||
}
|
||||
|
||||
// People were concerned that the download took ages, so we need to tell them it's over now.
|
||||
if (plugin.getSettings().isLogGithubDownloadData()) {
|
||||
plugin.log("Successfully downloaded data from GitHub.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Parsing the data */
|
||||
|
||||
private void parseCatalogContent(String tagsContent, String topicsContent, String catalogContent) {
|
||||
// Register the tags translations in the locales
|
||||
if (!tagsContent.isEmpty()) {
|
||||
try {
|
||||
@ -117,10 +162,8 @@ public class WebManager {
|
||||
try {
|
||||
JsonObject catalog = new JsonParser().parse(catalogContent).getAsJsonObject();
|
||||
|
||||
if (clearCache) {
|
||||
this.addonsCatalog.clear();
|
||||
this.gamemodesCatalog.clear();
|
||||
}
|
||||
|
||||
catalog.getAsJsonArray("gamemodes").forEach(gamemode -> gamemodesCatalog.add(new CatalogEntry(gamemode.getAsJsonObject())));
|
||||
catalog.getAsJsonArray("addons").forEach(addon -> addonsCatalog.add(new CatalogEntry(addon.getAsJsonObject())));
|
||||
@ -128,7 +171,6 @@ public class WebManager {
|
||||
plugin.log("Could not update the Catalog content: the gathered JSON data is malformed.");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,9 +186,7 @@ public class WebManager {
|
||||
String content = repo.getContent(fileName).getContent().replaceAll("\\n", "");
|
||||
return new String(Base64.getDecoder().decode(content), StandardCharsets.UTF_8);
|
||||
} catch (IllegalAccessException e) {
|
||||
if (plugin.getSettings().isLogGithubDownloadData()) {
|
||||
plugin.log("Could not connect to GitHub.");
|
||||
}
|
||||
// Fail silently
|
||||
} catch (Exception e) {
|
||||
plugin.logError("An unhandled exception occurred when downloading '" + fileName + "' from GitHub...");
|
||||
plugin.logStacktrace(e);
|
||||
@ -154,6 +194,18 @@ public class WebManager {
|
||||
return "";
|
||||
}
|
||||
|
||||
private void gatherContributors(@NonNull GitHubRepository repo) {
|
||||
try {
|
||||
List<Contributor> addonContributors = new LinkedList<>();
|
||||
for (GitHubContributor gitHubContributor : repo.getContributors()) {
|
||||
addonContributors.add(new Contributor(gitHubContributor.getUsername(), gitHubContributor.getContributionsAmount()));
|
||||
}
|
||||
contributors.put(repo.getFullName(), addonContributors);
|
||||
} catch (IllegalAccessException e) {
|
||||
// Silently fail
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of the addons catalog (may be an empty list).
|
||||
* @return the contents of the addons catalog.
|
||||
@ -174,6 +226,17 @@ public class WebManager {
|
||||
return gamemodesCatalog;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param repository
|
||||
* @return
|
||||
* @since 1.9.0
|
||||
*/
|
||||
@NonNull
|
||||
public List<Contributor> getContributors(String repository) {
|
||||
return contributors.getOrDefault(repository, new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an optional that may contain the {@link GitHubWebAPI} instance only and only if {@link Settings#isGithubDownloadData()} is {@code true}.
|
||||
* @return the GitHub instance.
|
||||
|
@ -5,6 +5,7 @@ import java.util.List;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
@ -101,7 +102,11 @@ public class CatalogPanel {
|
||||
|
||||
// Send the link to the releases tab on click
|
||||
itemBuilder.clickHandler((panel, user1, clickType, slot) -> {
|
||||
if (clickType.equals(ClickType.MIDDLE)) {
|
||||
CreditsPanel.openPanel(user1, addon.getRepository());
|
||||
} else {
|
||||
user1.sendRawMessage(ChatColor.GRAY + "" + ChatColor.ITALIC + "https://github.com/" + addon.getRepository() + "/releases");
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
|
@ -0,0 +1,91 @@
|
||||
package world.bentobox.bentobox.panels;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.api.addons.Addon;
|
||||
import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
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.bentobox.web.credits.Contributor;
|
||||
|
||||
/**
|
||||
* @since 1.9.0
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class CreditsPanel {
|
||||
|
||||
private static final String LOCALE_REF = "panel.credits.";
|
||||
private static final int[] PANES = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
||||
|
||||
private CreditsPanel() {}
|
||||
|
||||
public static void openPanel(User user, String repository) {
|
||||
BentoBox plugin = BentoBox.getInstance();
|
||||
|
||||
PanelBuilder builder = new PanelBuilder()
|
||||
.name(user.getTranslation(LOCALE_REF + "title", TextVariables.NAME, repository.split("/")[1]))
|
||||
.size(45);
|
||||
|
||||
// Setup header and corners
|
||||
for (int i : PANES) {
|
||||
builder.item(i, new PanelItemBuilder().icon(Material.LIGHT_BLUE_STAINED_GLASS_PANE).name(" ").build());
|
||||
}
|
||||
|
||||
if (plugin.getWebManager().getContributors(repository).isEmpty()) {
|
||||
looksEmpty(builder, user);
|
||||
} else {
|
||||
for (Contributor contributor : plugin.getWebManager().getContributors(repository)) {
|
||||
int slot = getFirstAvailableSlot(builder);
|
||||
|
||||
if (slot == -1) {
|
||||
break; //TODO support multi paging
|
||||
}
|
||||
|
||||
PanelItem contributorItem = new PanelItemBuilder()
|
||||
.icon(contributor.getName())
|
||||
.name(user.getTranslation(LOCALE_REF + "contributor.name", TextVariables.NAME, contributor.getName()))
|
||||
.description(user.getTranslation(LOCALE_REF + "contributor.description",
|
||||
"[commits]", String.valueOf(contributor.getCommits())))
|
||||
.clickHandler((panel, user1, clickType, slot1) -> {
|
||||
user.sendRawMessage(ChatColor.GRAY + contributor.getURL());
|
||||
return true;
|
||||
})
|
||||
.build();
|
||||
builder.item(getFirstAvailableSlot(builder), contributorItem);
|
||||
}
|
||||
}
|
||||
|
||||
builder.build().open(user);
|
||||
}
|
||||
|
||||
public static void openPanel(User user, Addon addon) {
|
||||
openPanel(user, addon.getDescription().getRepository());
|
||||
}
|
||||
|
||||
private static void looksEmpty(@NonNull PanelBuilder builder, @NonNull User user) {
|
||||
PanelItem emptyHere = new PanelItemBuilder()
|
||||
.icon(Material.STRUCTURE_VOID)
|
||||
.name(user.getTranslation(LOCALE_REF + "empty-here.name"))
|
||||
.description(user.getTranslation(LOCALE_REF + "empty-here.description"))
|
||||
.build();
|
||||
|
||||
builder.item(22, emptyHere);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pb - panel builder
|
||||
* @return first available slot, or -1 if none
|
||||
*/
|
||||
private static int getFirstAvailableSlot(PanelBuilder pb) {
|
||||
for (int i = 0; i < 35; i++) {
|
||||
if (!pb.slotOccupied(i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
@ -64,6 +65,12 @@ public class ManagementPanel {
|
||||
.name(user.getTranslation(LOCALE_REF + "views.gamemodes.gamemode.name", TextVariables.NAME, addon.getDescription().getName()))
|
||||
.description(user.getTranslation(LOCALE_REF + "views.gamemodes.gamemode.description",
|
||||
"[islands]", String.valueOf(addon.getIslands().getIslandCount(gameModeAddon.getOverWorld()))))
|
||||
.clickHandler((panel, user1, clickType, slot) -> {
|
||||
if (clickType.equals(ClickType.MIDDLE)) {
|
||||
CreditsPanel.openPanel(user, addon);
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.build();
|
||||
|
||||
builder.item(startSlot + i, addonItem);
|
||||
@ -92,6 +99,12 @@ public class ManagementPanel {
|
||||
PanelItem addonItem = new PanelItemBuilder()
|
||||
.icon(addon.getDescription().getIcon())
|
||||
.name(ChatColor.WHITE + addon.getDescription().getName())
|
||||
.clickHandler((panel, user1, clickType, slot) -> {
|
||||
if (clickType.equals(ClickType.MIDDLE)) {
|
||||
CreditsPanel.openPanel(user, addon);
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.build();
|
||||
|
||||
builder.item(startSlot + i, addonItem);
|
||||
@ -135,6 +148,19 @@ public class ManagementPanel {
|
||||
|
||||
builder.item(17, catalog);
|
||||
|
||||
// Credits
|
||||
PanelItem credits = new PanelItemBuilder()
|
||||
.icon(Material.KNOWLEDGE_BOOK)
|
||||
.name(user.getTranslation(LOCALE_REF + "buttons.credits.name"))
|
||||
.description(user.getTranslation(LOCALE_REF + "buttons.credits.description"))
|
||||
.clickHandler((panel, user1, clickType, slot) -> {
|
||||
CreditsPanel.openPanel(user, "BentoBoxWorld/BentoBox");
|
||||
return true;
|
||||
})
|
||||
.build();
|
||||
|
||||
builder.item(26, credits);
|
||||
|
||||
// Show it to the user
|
||||
builder.build().open(user);
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
package world.bentobox.bentobox.web.catalog;
|
||||
|
||||
import org.bukkit.Material;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.bukkit.Material;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* @author Poslovitch
|
||||
|
@ -0,0 +1,33 @@
|
||||
package world.bentobox.bentobox.web.credits;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
|
||||
/**
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @author Poslovitch
|
||||
*/
|
||||
public class Contributor {
|
||||
|
||||
private @NonNull String name;
|
||||
private int commits;
|
||||
|
||||
public Contributor(@NonNull String name, int commits) {
|
||||
this.name = name;
|
||||
this.commits = commits;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getCommits() {
|
||||
return commits;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getURL() {
|
||||
return "https://github.com/" + name;
|
||||
}
|
||||
}
|
@ -1197,6 +1197,9 @@ management:
|
||||
catalog:
|
||||
name: "&6Addons Catalog"
|
||||
description: "&aOpens the Addons Catalog"
|
||||
credits:
|
||||
name: "&6Credits"
|
||||
description: "&aOpens the Credits for BentoBox"
|
||||
empty-here:
|
||||
name: "&bThis looks empty here..."
|
||||
description: "&aWhat if you take a look at our catalog?"
|
||||
@ -1279,6 +1282,22 @@ catalog:
|
||||
&aAllow BentoBox to connect to GitHub in
|
||||
&athe configuration or try again later.
|
||||
|
||||
panel:
|
||||
credits:
|
||||
title: "&8[name] &2Credits"
|
||||
contributor:
|
||||
name: "&a[name]"
|
||||
description: |
|
||||
&aCommits: &b[commits]
|
||||
empty-here:
|
||||
name: "&cThis looks empty here..."
|
||||
description: |+
|
||||
&cBentoBox could not gather the Contributors
|
||||
&cfor this Addon.
|
||||
|
||||
&aAllow BentoBox to connect to GitHub in
|
||||
&athe configuration or try again later.
|
||||
|
||||
successfully-loaded: |
|
||||
|
||||
&6 ____ _ ____
|
||||
|
Loading…
Reference in New Issue
Block a user