mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-27 13:15:28 +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>
|
<bstats.version>1.7</bstats.version>
|
||||||
<vault.version>1.7</vault.version>
|
<vault.version>1.7</vault.version>
|
||||||
<placeholderapi.version>2.10.5</placeholderapi.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>
|
<dynmap.version>3.0-SNAPSHOT</dynmap.version>
|
||||||
<worldedit.version>7.0.0</worldedit.version>
|
<worldedit.version>7.0.0</worldedit.version>
|
||||||
<!-- Revision variable removes warning about dynamic 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")
|
@ConfigEntry(path = "web.github.connection-interval", since = "1.5.0")
|
||||||
private int githubConnectionInterval = 120;
|
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;
|
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;
|
private boolean checkAddonsUpdates = true;
|
||||||
|
|
||||||
|
@ConfigEntry(path = "web.updater.check-updates.include-prereleases", since = "1.14.0")
|
||||||
|
private boolean checkPreReleasesUpdates = false;
|
||||||
|
|
||||||
// ---------------------------------------------
|
// ---------------------------------------------
|
||||||
// Getters and setters
|
// Getters and setters
|
||||||
|
|
||||||
@ -713,4 +718,12 @@ public class Settings implements ConfigObject {
|
|||||||
public void setPanelFillerMaterial(Material panelFillerMaterial) {
|
public void setPanelFillerMaterial(Material panelFillerMaterial) {
|
||||||
this.panelFillerMaterial = 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.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javafx.scene.text.Text;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
|
||||||
import world.bentobox.bentobox.api.addons.GameModeAddon;
|
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.api.user.User;
|
||||||
import world.bentobox.bentobox.versions.ServerCompatibility;
|
import world.bentobox.bentobox.versions.ServerCompatibility;
|
||||||
import world.bentobox.bentobox.versions.ServerCompatibility.ServerSoftware;
|
import world.bentobox.bentobox.versions.ServerCompatibility.ServerSoftware;
|
||||||
|
import world.bentobox.bentobox.versions.UpdateChecker;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays information about Gamemodes, Addons and versioning.
|
* 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(),
|
.forEach(a -> user.sendMessage("commands.bentobox.version.addon-syntax", TextVariables.NAME, a.getDescription().getName(),
|
||||||
TextVariables.VERSION, a.getDescription().getVersion(), "[state]", a.getState().toString()));
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,8 +89,22 @@ public class JoinLeaveListener implements Listener {
|
|||||||
|
|
||||||
// Clear inventory if required
|
// Clear inventory if required
|
||||||
clearPlayersInventory(Util.getWorld(event.getPlayer().getWorld()), user);
|
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) {
|
private void firstTime(User user) {
|
||||||
// Make sure the player is loaded into the cache or create the player if they don't exist
|
// 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.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import io.github.TheBusyBiscuit.GitHubWebAPI4Java.objects.users.GitHubOrganization;
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
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 io.github.TheBusyBiscuit.GitHubWebAPI4Java.objects.repositories.GitHubRepository;
|
||||||
import world.bentobox.bentobox.BentoBox;
|
import world.bentobox.bentobox.BentoBox;
|
||||||
import world.bentobox.bentobox.Settings;
|
import world.bentobox.bentobox.Settings;
|
||||||
|
import world.bentobox.bentobox.versions.UpdateChecker;
|
||||||
import world.bentobox.bentobox.web.catalog.CatalogEntry;
|
import world.bentobox.bentobox.web.catalog.CatalogEntry;
|
||||||
import world.bentobox.bentobox.web.credits.Contributor;
|
import world.bentobox.bentobox.web.credits.Contributor;
|
||||||
|
|
||||||
@ -34,17 +36,21 @@ import world.bentobox.bentobox.web.credits.Contributor;
|
|||||||
*/
|
*/
|
||||||
public class WebManager {
|
public class WebManager {
|
||||||
|
|
||||||
private @NonNull BentoBox plugin;
|
private @NonNull final BentoBox plugin;
|
||||||
private @Nullable GitHubWebAPI gitHub;
|
private @Nullable GitHubWebAPI gitHub;
|
||||||
private @NonNull List<CatalogEntry> addonsCatalog;
|
private @NonNull final List<CatalogEntry> addonsCatalog;
|
||||||
private @NonNull List<CatalogEntry> gamemodesCatalog;
|
private @NonNull final List<CatalogEntry> gamemodesCatalog;
|
||||||
private @NonNull Map<String, List<Contributor>> contributors;
|
private @NonNull final Map<String, List<Contributor>> contributors;
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private final List<UpdateChecker> updateCheckers;
|
||||||
|
|
||||||
public WebManager(@NonNull BentoBox plugin) {
|
public WebManager(@NonNull BentoBox plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.addonsCatalog = new ArrayList<>();
|
this.addonsCatalog = new ArrayList<>();
|
||||||
this.gamemodesCatalog = new ArrayList<>();
|
this.gamemodesCatalog = new ArrayList<>();
|
||||||
this.contributors = new HashMap<>();
|
this.contributors = new HashMap<>();
|
||||||
|
this.updateCheckers = new ArrayList<>();
|
||||||
|
|
||||||
// Setup the GitHub connection
|
// Setup the GitHub connection
|
||||||
if (plugin.getSettings().isGithubDownloadData()) {
|
if (plugin.getSettings().isGithubDownloadData()) {
|
||||||
@ -100,12 +106,14 @@ public class WebManager {
|
|||||||
.stream().map(addon -> addon.getDescription().getRepository())
|
.stream().map(addon -> addon.getDescription().getRepository())
|
||||||
.filter(repo -> !repo.isEmpty())
|
.filter(repo -> !repo.isEmpty())
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
/*
|
||||||
repositories.addAll(addonsCatalog.stream().map(CatalogEntry::getRepository)
|
repositories.addAll(addonsCatalog.stream().map(CatalogEntry::getRepository)
|
||||||
.filter(repo -> !repositories.contains(repo))
|
.filter(repo -> !repositories.contains(repo))
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
repositories.addAll(gamemodesCatalog.stream().map(CatalogEntry::getRepository)
|
repositories.addAll(gamemodesCatalog.stream().map(CatalogEntry::getRepository)
|
||||||
.filter(repo -> !repositories.contains(repo))
|
.filter(repo -> !repositories.contains(repo))
|
||||||
.collect(Collectors.toList()));
|
.collect(Collectors.toList()));
|
||||||
|
*/
|
||||||
|
|
||||||
/* Download the contributors */
|
/* Download the contributors */
|
||||||
if (plugin.getSettings().isLogGithubDownloadData()) {
|
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.
|
// People were concerned that the download took ages, so we need to tell them it's over now.
|
||||||
if (plugin.getSettings().isLogGithubDownloadData()) {
|
if (plugin.getSettings().isLogGithubDownloadData()) {
|
||||||
plugin.log("Successfully downloaded data from GitHub.");
|
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).
|
* Returns the contents of the addons catalog (may be an empty list).
|
||||||
* @return the contents of the addons catalog.
|
* @return the contents of the addons catalog.
|
||||||
@ -263,4 +308,13 @@ public class WebManager {
|
|||||||
public Optional<GitHubWebAPI> getGitHub() {
|
public Optional<GitHubWebAPI> getGitHub() {
|
||||||
return Optional.ofNullable(gitHub);
|
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]"
|
game-world: "&2 [name] &7 (&3 [addon]&7 ): &3 [worlds]"
|
||||||
server: "&2 Running &3 [name] [version]&2 ."
|
server: "&2 Running &3 [name] [version]&2 ."
|
||||||
database: "&2 Database: &3 [database]"
|
database: "&2 Database: &3 [database]"
|
||||||
|
available-updates: "Available updates ([number]):"
|
||||||
|
update: "&2 [repo] &3 [version]&7 : &e [link]"
|
||||||
manage:
|
manage:
|
||||||
description: "displays the Management Panel"
|
description: "displays the Management Panel"
|
||||||
catalog:
|
catalog:
|
||||||
@ -1405,6 +1407,10 @@ panel:
|
|||||||
&a Allow BentoBox to connect to GitHub in
|
&a Allow BentoBox to connect to GitHub in
|
||||||
&a the configuration or try again later.
|
&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: |
|
successfully-loaded: |
|
||||||
|
|
||||||
&6 ____ _ ____
|
&6 ____ _ ____
|
||||||
|
@ -39,3 +39,6 @@ permissions:
|
|||||||
bentobox.version:
|
bentobox.version:
|
||||||
description: Allows to use /bentobox version
|
description: Allows to use /bentobox version
|
||||||
default: op
|
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