mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-23 11:15:24 +01:00
First try at making a GitHub-based update checker
This commit is contained in:
parent
2cefdcca3f
commit
0b4b5298ab
2
pom.xml
2
pom.xml
@ -74,7 +74,7 @@
|
||||
<bstats.version>1.7</bstats.version>
|
||||
<vault.version>1.7</vault.version>
|
||||
<placeholderapi.version>2.10.5</placeholderapi.version>
|
||||
<githubapi.version>d5f5e0bbd8</githubapi.version>
|
||||
<githubapi.version>e7597818f5</githubapi.version>
|
||||
<dynmap.version>3.0-SNAPSHOT</dynmap.version>
|
||||
<worldedit.version>7.0.0</worldedit.version>
|
||||
<!-- Revision variable removes warning about dynamic version -->
|
||||
|
@ -273,12 +273,17 @@ public class Settings implements ConfigObject {
|
||||
@ConfigEntry(path = "web.github.connection-interval", since = "1.5.0")
|
||||
private int githubConnectionInterval = 120;
|
||||
|
||||
@ConfigEntry(path = "web.updater.check-updates.bentobox", since = "1.3.0", hidden = true)
|
||||
@ConfigComment("Checks for BentoBox updates.")
|
||||
@ConfigEntry(path = "web.updater.check-updates.bentobox", since = "1.14.0")
|
||||
private boolean checkBentoBoxUpdates = true;
|
||||
|
||||
@ConfigEntry(path = "web.updater.check-updates.addons", since = "1.3.0", hidden = true)
|
||||
@ConfigComment("Checks for addons updates.")
|
||||
@ConfigEntry(path = "web.updater.check-updates.addons", since = "1.14.0")
|
||||
private boolean checkAddonsUpdates = true;
|
||||
|
||||
@ConfigEntry(path = "web.updater.check-updates.include-prereleases", since = "1.14.0")
|
||||
private boolean checkPreReleasesUpdates = false;
|
||||
|
||||
// ---------------------------------------------
|
||||
// Getters and setters
|
||||
|
||||
@ -713,4 +718,12 @@ public class Settings implements ConfigObject {
|
||||
public void setPanelFillerMaterial(Material panelFillerMaterial) {
|
||||
this.panelFillerMaterial = panelFillerMaterial;
|
||||
}
|
||||
|
||||
public boolean isCheckPreReleasesUpdates() {
|
||||
return checkPreReleasesUpdates;
|
||||
}
|
||||
|
||||
public void setCheckPreReleasesUpdates(boolean checkPreReleasesUpdates) {
|
||||
this.checkPreReleasesUpdates = checkPreReleasesUpdates;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import javafx.scene.text.Text;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
||||
@ -14,6 +15,7 @@ import world.bentobox.bentobox.api.localization.TextVariables;
|
||||
import world.bentobox.bentobox.api.user.User;
|
||||
import world.bentobox.bentobox.versions.ServerCompatibility;
|
||||
import world.bentobox.bentobox.versions.ServerCompatibility.ServerSoftware;
|
||||
import world.bentobox.bentobox.versions.UpdateChecker;
|
||||
|
||||
/**
|
||||
* Displays information about Gamemodes, Addons and versioning.
|
||||
@ -85,6 +87,22 @@ public class BentoBoxVersionCommand extends CompositeCommand {
|
||||
.forEach(a -> user.sendMessage("commands.bentobox.version.addon-syntax", TextVariables.NAME, a.getDescription().getName(),
|
||||
TextVariables.VERSION, a.getDescription().getVersion(), "[state]", a.getState().toString()));
|
||||
|
||||
long availableUpdates = getPlugin().getWebManager().getUpdateCheckers().stream()
|
||||
.filter(updateChecker -> updateChecker.getResult() != null)
|
||||
.count();
|
||||
|
||||
if (availableUpdates > 0) {
|
||||
user.sendMessage("commands.bentobox.version.available-updates", TextVariables.NUMBER, String.valueOf(availableUpdates));
|
||||
for (UpdateChecker updateChecker : getPlugin().getWebManager().getUpdateCheckers()) {
|
||||
UpdateChecker.Result result = updateChecker.getResult();
|
||||
if (result != null) {
|
||||
user.sendMessage("commands.bentobox.version.update", "[repo]", updateChecker.getRepository(),
|
||||
TextVariables.VERSION, result.getVersion(),
|
||||
"[link]", "https://github.com/" + updateChecker.getRepository() + "/releases/tag/" + result.getVersion());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -89,8 +89,22 @@ public class JoinLeaveListener implements Listener {
|
||||
|
||||
// Clear inventory if required
|
||||
clearPlayersInventory(Util.getWorld(event.getPlayer().getWorld()), user);
|
||||
|
||||
// Notify player about updates
|
||||
notifyUpdates(user);
|
||||
}
|
||||
|
||||
private void notifyUpdates(User user) {
|
||||
if (user.hasPermission("bentobox.notify-updates")) {
|
||||
long availableUpdates = plugin.getWebManager().getUpdateCheckers().stream()
|
||||
.filter(updateChecker -> updateChecker.getResult() != null)
|
||||
.count();
|
||||
|
||||
if (availableUpdates > 0) {
|
||||
user.sendMessage("updates-available");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void firstTime(User user) {
|
||||
// Make sure the player is loaded into the cache or create the player if they don't exist
|
||||
|
@ -10,6 +10,7 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.github.TheBusyBiscuit.GitHubWebAPI4Java.objects.users.GitHubOrganization;
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
@ -23,6 +24,7 @@ import io.github.TheBusyBiscuit.GitHubWebAPI4Java.objects.repositories.GitHubCon
|
||||
import io.github.TheBusyBiscuit.GitHubWebAPI4Java.objects.repositories.GitHubRepository;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.Settings;
|
||||
import world.bentobox.bentobox.versions.UpdateChecker;
|
||||
import world.bentobox.bentobox.web.catalog.CatalogEntry;
|
||||
import world.bentobox.bentobox.web.credits.Contributor;
|
||||
|
||||
@ -34,17 +36,21 @@ import world.bentobox.bentobox.web.credits.Contributor;
|
||||
*/
|
||||
public class WebManager {
|
||||
|
||||
private @NonNull BentoBox plugin;
|
||||
private @NonNull final BentoBox plugin;
|
||||
private @Nullable GitHubWebAPI gitHub;
|
||||
private @NonNull List<CatalogEntry> addonsCatalog;
|
||||
private @NonNull List<CatalogEntry> gamemodesCatalog;
|
||||
private @NonNull Map<String, List<Contributor>> contributors;
|
||||
private @NonNull final List<CatalogEntry> addonsCatalog;
|
||||
private @NonNull final List<CatalogEntry> gamemodesCatalog;
|
||||
private @NonNull final Map<String, List<Contributor>> contributors;
|
||||
|
||||
@NonNull
|
||||
private final List<UpdateChecker> updateCheckers;
|
||||
|
||||
public WebManager(@NonNull BentoBox plugin) {
|
||||
this.plugin = plugin;
|
||||
this.addonsCatalog = new ArrayList<>();
|
||||
this.gamemodesCatalog = new ArrayList<>();
|
||||
this.contributors = new HashMap<>();
|
||||
this.updateCheckers = new ArrayList<>();
|
||||
|
||||
// Setup the GitHub connection
|
||||
if (plugin.getSettings().isGithubDownloadData()) {
|
||||
@ -100,12 +106,14 @@ public class WebManager {
|
||||
.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()));
|
||||
*/
|
||||
|
||||
/* Download the contributors */
|
||||
if (plugin.getSettings().isLogGithubDownloadData()) {
|
||||
@ -128,6 +136,13 @@ public class WebManager {
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for updates */
|
||||
if (plugin.getSettings().isLogGithubDownloadData()) {
|
||||
plugin.log("Checking for updates...");
|
||||
}
|
||||
|
||||
checkUpdates(gh);
|
||||
|
||||
// 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.");
|
||||
@ -223,6 +238,36 @@ public class WebManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkUpdates(@NonNull GitHubWebAPI gh) {
|
||||
if (updateCheckers.isEmpty()) {
|
||||
// Grab the repositories we will have to go through
|
||||
Map<String, String> repositories = new HashMap<>();
|
||||
|
||||
if (plugin.getSettings().isCheckBentoBoxUpdates()) {
|
||||
repositories.put("BentoBoxWorld/BentoBox", plugin.getDescription().getVersion());
|
||||
}
|
||||
if (plugin.getSettings().isCheckAddonsUpdates()) {
|
||||
repositories.putAll(plugin.getAddonsManager().getEnabledAddons()
|
||||
.stream()
|
||||
.filter(addon -> !addon.getDescription().getRepository().isEmpty())
|
||||
.collect(Collectors.toMap(addon -> addon.getDescription().getRepository(), addon -> addon.getDescription().getVersion())));
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> repo : repositories.entrySet()) {
|
||||
UpdateChecker updateChecker = new UpdateChecker(gh, repo.getKey(), repo.getValue());
|
||||
updateCheckers.add(updateChecker);
|
||||
}
|
||||
}
|
||||
|
||||
for (UpdateChecker updateChecker : updateCheckers) {
|
||||
try {
|
||||
updateChecker.checkUpdates();
|
||||
} catch (IllegalAccessException e) {
|
||||
// Fail silently
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contents of the addons catalog (may be an empty list).
|
||||
* @return the contents of the addons catalog.
|
||||
@ -263,4 +308,13 @@ public class WebManager {
|
||||
public Optional<GitHubWebAPI> getGitHub() {
|
||||
return Optional.ofNullable(gitHub);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of update checkers.
|
||||
* @return the list of update checkers.
|
||||
* @since 1.14.0
|
||||
*/
|
||||
public List<UpdateChecker> getUpdateCheckers() {
|
||||
return updateCheckers;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,111 @@
|
||||
package world.bentobox.bentobox.versions;
|
||||
|
||||
import io.github.TheBusyBiscuit.GitHubWebAPI4Java.GitHubWebAPI;
|
||||
import io.github.TheBusyBiscuit.GitHubWebAPI4Java.objects.repositories.GitHubRelease;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import world.bentobox.bentobox.BentoBox;
|
||||
import world.bentobox.bentobox.util.Util;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Checks for updates through the GitHub API.
|
||||
* @author Poslovitch
|
||||
* @since 1.14.0
|
||||
*/
|
||||
public class UpdateChecker {
|
||||
|
||||
private final BentoBox plugin;
|
||||
private final GitHubWebAPI gitHub;
|
||||
private final String repository;
|
||||
private final String currentVersion;
|
||||
|
||||
@Nullable
|
||||
private Result result;
|
||||
|
||||
public UpdateChecker(GitHubWebAPI gitHub, String repository, String currentVersion) {
|
||||
this.plugin = BentoBox.getInstance();
|
||||
this.gitHub = gitHub;
|
||||
this.repository = repository;
|
||||
this.currentVersion = currentVersion;
|
||||
}
|
||||
|
||||
public void checkUpdates() throws IllegalAccessException {
|
||||
String[] repo = repository.split("/");
|
||||
|
||||
List<GitHubRelease> releases = gitHub.getRepository(repo[0], repo[1]).getReleases();
|
||||
if (!releases.isEmpty()) {
|
||||
for (GitHubRelease release : releases) {
|
||||
if (release.isDraft()) {
|
||||
// Drafts should be ignored (they're not published yet)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (release.isPreRelease() && !plugin.getSettings().isCheckPreReleasesUpdates()) {
|
||||
// We don't care about pre-releases
|
||||
continue;
|
||||
}
|
||||
|
||||
String newVersion = release.getTagName();
|
||||
if (isMoreRecent(newVersion)) {
|
||||
// We found the new version, and it should be the latest.
|
||||
this.result = new Result(newVersion, release.isPreRelease());
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.result = null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMoreRecent(String newVersion) {
|
||||
String[] currentVer = currentVersion.split("\\D");
|
||||
String[] newVer = newVersion.split("\\D");
|
||||
|
||||
for (int i = 0; i < currentVer.length; i++) {
|
||||
int newVersionNumber = 0;
|
||||
if (i < newVer.length && Util.isInteger(newVer[i], false)) {
|
||||
newVersionNumber = Integer.parseInt(newVer[i]);
|
||||
}
|
||||
int currentVersionNumber = Util.isInteger(currentVer[i], false) ? Integer.parseInt(currentVer[i]) : -1;
|
||||
|
||||
if (newVersionNumber > currentVersionNumber) {
|
||||
return false; // The current version is greater than the "new" version -> up to date.
|
||||
}
|
||||
if (newVersionNumber < currentVersionNumber) {
|
||||
return true; // The current version is outdated
|
||||
}
|
||||
// If it is equal, go to the next number
|
||||
}
|
||||
|
||||
return false; // Everything is equal, so return true
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Result getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public String getRepository() {
|
||||
return repository;
|
||||
}
|
||||
|
||||
public static class Result {
|
||||
|
||||
private final String version;
|
||||
private final boolean preRelease;
|
||||
|
||||
public Result(String version, boolean preRelease) {
|
||||
this.version = version;
|
||||
this.preRelease = preRelease;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public boolean isPreRelease() {
|
||||
return preRelease;
|
||||
}
|
||||
}
|
||||
}
|
@ -413,6 +413,8 @@ commands:
|
||||
game-world: "&2 [name] &7 (&3 [addon]&7 ): &3 [worlds]"
|
||||
server: "&2 Running &3 [name] [version]&2 ."
|
||||
database: "&2 Database: &3 [database]"
|
||||
available-updates: "Available updates ([number]):"
|
||||
update: "&2 [repo] &3 [version]&7 : &e [link]"
|
||||
manage:
|
||||
description: "displays the Management Panel"
|
||||
catalog:
|
||||
@ -1405,6 +1407,10 @@ panel:
|
||||
&a Allow BentoBox to connect to GitHub in
|
||||
&a the configuration or try again later.
|
||||
|
||||
updates-available: |
|
||||
[prefix_bentobox]&6 &l Update Checker
|
||||
[prefix_bentobox]&a Updates are available. Check &b /bentobox version &a for details.
|
||||
|
||||
successfully-loaded: |
|
||||
|
||||
&6 ____ _ ____
|
||||
|
@ -39,3 +39,6 @@ permissions:
|
||||
bentobox.version:
|
||||
description: Allows to use /bentobox version
|
||||
default: op
|
||||
bentobox.notify-updates:
|
||||
description: Sends players a message about available updates when they join the server
|
||||
default: op
|
||||
|
Loading…
Reference in New Issue
Block a user