mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-25 22:56:45 +01:00
Update notifications.
This commit is contained in:
parent
806124b047
commit
0b77b863ba
@ -37,6 +37,12 @@ shadowJar {
|
|||||||
dependencies {
|
dependencies {
|
||||||
include(dependency(':Core'))
|
include(dependency(':Core'))
|
||||||
include(dependency('org.bstats:bstats-bukkit:1.4'))
|
include(dependency('org.bstats:bstats-bukkit:1.4'))
|
||||||
|
// update notification stuff
|
||||||
|
include(dependency('com.github.Sauilitired:Jenkins4J:2.0-SNAPSHOT'))
|
||||||
|
include(dependency('com.squareup.retrofit2:retrofit:2.4.0'))
|
||||||
|
include(dependency('com.squareup.okhttp3:okhttp:3.14.0'))
|
||||||
|
include(dependency('com.squareup.okio:okio:2.2.2'))
|
||||||
|
include(dependency('org.jetbrains.kotlin:kotlin-stdlib:1.3.21'))
|
||||||
}
|
}
|
||||||
// relocate('org.mcstats', 'com.plotsquared.stats')
|
// relocate('org.mcstats', 'com.plotsquared.stats')
|
||||||
archiveName = "${parent.name}-${project.name}-${parent.version}.jar"
|
archiveName = "${parent.name}-${project.name}-${parent.version}.jar"
|
||||||
|
@ -137,6 +137,33 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
|
|||||||
}
|
}
|
||||||
|
|
||||||
new PlotSquared(this, "Bukkit");
|
new PlotSquared(this, "Bukkit");
|
||||||
|
|
||||||
|
// Check for updates
|
||||||
|
if (PlotSquared.get().getUpdateUtility() != null) {
|
||||||
|
final UpdateUtility updateUtility = PlotSquared.get().getUpdateUtility();
|
||||||
|
updateUtility.checkForUpdate(this.getPluginVersionString(), ((updateDescription, throwable) -> {
|
||||||
|
Bukkit.getScheduler().runTask(BukkitMain.this, () -> {
|
||||||
|
getLogger().info("-------- PlotSquared Update Check --------");
|
||||||
|
if (throwable != null) {
|
||||||
|
getLogger().severe(String.format("Could not check for update. Reason: %s",
|
||||||
|
throwable.getMessage()));
|
||||||
|
} else {
|
||||||
|
if (updateDescription == null) {
|
||||||
|
getLogger().info("You appear to be running the latest version of PlotSquared. Congratulations!");
|
||||||
|
} else {
|
||||||
|
getLogger().info("There appears to be a PlotSquared update available!");
|
||||||
|
getLogger().info(String.format("You are running version %s,"
|
||||||
|
+ " the newest available version is %s", getPluginVersionString(), updateDescription.getVersion()));
|
||||||
|
getLogger().info(String.format("Update URL: %s", updateDescription.getUrl()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getLogger().info("-------- PlotSquared Update Check --------");
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
getLogger().warning("Update checking disabled. Skipping.");
|
||||||
|
}
|
||||||
|
|
||||||
if (Settings.Enabled_Components.METRICS) {
|
if (Settings.Enabled_Components.METRICS) {
|
||||||
this.startMetrics();
|
this.startMetrics();
|
||||||
} else {
|
} else {
|
||||||
|
@ -631,6 +631,29 @@ import java.util.regex.Pattern;
|
|||||||
}
|
}
|
||||||
EventUtil.manager.doJoinTask(pp);
|
EventUtil.manager.doJoinTask(pp);
|
||||||
}, 20);
|
}, 20);
|
||||||
|
|
||||||
|
if (pp.hasPermission(Captions.PERMISSION_ADMIN_UPDATE_NOTIFICATION.s()) &&
|
||||||
|
PlotSquared.get().getUpdateUtility() != null) {
|
||||||
|
final UpdateUtility updateUtility = PlotSquared.get().getUpdateUtility();
|
||||||
|
final BukkitMain bukkitMain = BukkitMain.getPlugin(BukkitMain.class);
|
||||||
|
updateUtility.checkForUpdate(bukkitMain.getPluginVersionString(), ((updateDescription, throwable) -> {
|
||||||
|
if (throwable != null) {
|
||||||
|
bukkitMain.getLogger().severe(String.format("Could not check for update. Reason: %s",
|
||||||
|
throwable.getMessage()));
|
||||||
|
} else {
|
||||||
|
if (updateDescription != null) {
|
||||||
|
new PlotMessage("-------- ").color("$2").text("PlotSquared Update Notification").color("$1").text(" --------").color("$2")
|
||||||
|
.send(pp);
|
||||||
|
new PlotMessage("There appears to be a PlotSquared update available!").color("$1").send(pp);
|
||||||
|
new PlotMessage(String.format("You are running version %s,"
|
||||||
|
+ " the newest available version is %s", bukkitMain.getPluginVersionString(), updateDescription.getVersion())).color("$1").send(pp);
|
||||||
|
new PlotMessage("Update URL").color("$1").text(": ").color("$2").text(updateDescription.getUrl()).tooltip("Download update").send(pp);
|
||||||
|
new PlotMessage("-------- ").color("$2").text("PlotSquared Update Notification").color("$1").text(" --------").color("$2")
|
||||||
|
.send(pp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||||
|
@ -1,9 +1,19 @@
|
|||||||
|
repositories {
|
||||||
|
maven { url 'https://jitpack.io' }
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
compile 'org.yaml:snakeyaml:1.23'
|
compile 'org.yaml:snakeyaml:1.23'
|
||||||
compile 'com.google.code.gson:gson:2.8.5'
|
compile 'com.google.code.gson:gson:2.8.5'
|
||||||
compileOnly 'org.projectlombok:lombok:1.18.4'
|
compileOnly 'org.projectlombok:lombok:1.18.4'
|
||||||
|
|
||||||
|
compile 'com.github.Sauilitired:Jenkins4J:2.0-SNAPSHOT'
|
||||||
|
compile 'com.squareup.okhttp3:okhttp:3.14.0'
|
||||||
|
compile 'com.squareup.okio:okio:2.2.2'
|
||||||
|
compile 'org.jetbrains.kotlin:kotlin-stdlib:1.3.21'
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceCompatibility = 1.8
|
sourceCompatibility = 1.8
|
||||||
targetCompatibility = 1.8
|
targetCompatibility = 1.8
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ import java.util.zip.ZipInputStream;
|
|||||||
@Setter @Getter private ILogger logger;
|
@Setter @Getter private ILogger logger;
|
||||||
// Platform / Version / Update URL
|
// Platform / Version / Update URL
|
||||||
private PlotVersion version;
|
private PlotVersion version;
|
||||||
|
@Nullable @Getter private UpdateUtility updateUtility;
|
||||||
// Files and configuration
|
// Files and configuration
|
||||||
@Getter private File jarFile = null; // This file
|
@Getter private File jarFile = null; // This file
|
||||||
private File storageFile;
|
private File storageFile;
|
||||||
@ -1610,6 +1611,24 @@ import java.util.zip.ZipInputStream;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Settings.load(configFile);
|
Settings.load(configFile);
|
||||||
|
try {
|
||||||
|
copyFile("updater.properties", "config");
|
||||||
|
try (BufferedReader bufferedReader =
|
||||||
|
new BufferedReader(new InputStreamReader(new FileInputStream(new File(new File(this.IMP.getDirectory(),
|
||||||
|
"config"), "updater.properties"))))) {
|
||||||
|
final Properties properties = new Properties();
|
||||||
|
properties.load(bufferedReader);
|
||||||
|
final boolean enabled = Boolean.valueOf(properties.getOrDefault("enabled", true).toString());
|
||||||
|
if (enabled) {
|
||||||
|
this.updateUtility = new UpdateUtility(properties.getProperty("path"),
|
||||||
|
properties.getProperty("job"), properties.getProperty("artifact"));
|
||||||
|
}
|
||||||
|
} catch (final IOException throwable) {
|
||||||
|
throwable.printStackTrace();
|
||||||
|
}
|
||||||
|
} catch (final Throwable throwable) {
|
||||||
|
throwable.printStackTrace();
|
||||||
|
}
|
||||||
try (InputStream stream = getClass().getResourceAsStream("/plugin.properties");
|
try (InputStream stream = getClass().getResourceAsStream("/plugin.properties");
|
||||||
BufferedReader br = new BufferedReader(new InputStreamReader(stream))) {
|
BufferedReader br = new BufferedReader(new InputStreamReader(stream))) {
|
||||||
//java.util.Scanner scanner = new java.util.Scanner(stream).useDelimiter("\\A");
|
//java.util.Scanner scanner = new java.util.Scanner(stream).useDelimiter("\\A");
|
||||||
|
@ -41,7 +41,8 @@ public enum Captions {
|
|||||||
"plots.admin.interact.blockedcommands", "static.permissions"), PERMISSION_WORLDEDIT_BYPASS(
|
"plots.admin.interact.blockedcommands", "static.permissions"), PERMISSION_WORLDEDIT_BYPASS(
|
||||||
"plots.worldedit.bypass", "static.permissions"), PERMISSION_PLOT_TOGGLE_TITLES(
|
"plots.worldedit.bypass", "static.permissions"), PERMISSION_PLOT_TOGGLE_TITLES(
|
||||||
"plots.toggle.titles", "static.permissions"), PERMISSION_PLOT_TOGGLE_CHAT(
|
"plots.toggle.titles", "static.permissions"), PERMISSION_PLOT_TOGGLE_CHAT(
|
||||||
"plots.toggle.chat", "static.permissions"), PERMISSION_ADMIN_EXIT_DENIED(
|
"plots.toggle.chat", "static.permissions"), PERMISSION_ADMIN_UPDATE_NOTIFICATION(
|
||||||
|
"plots.admin.update.notify", "static.permissions"), PERMISSION_ADMIN_EXIT_DENIED(
|
||||||
"plots.admin.exit.denied", "static.permissions"), PERMISSION_ADMIN_ENTRY_DENIED(
|
"plots.admin.exit.denied", "static.permissions"), PERMISSION_ADMIN_ENTRY_DENIED(
|
||||||
"plots.admin.entry.denied", "static.permissions"), PERMISSION_ADMIN_ENTRY_FORCEFIELD(
|
"plots.admin.entry.denied", "static.permissions"), PERMISSION_ADMIN_ENTRY_FORCEFIELD(
|
||||||
"plots.admin.entry.forcefield", "static.permissions"), PERMISSION_COMMANDS_CHAT(
|
"plots.admin.entry.forcefield", "static.permissions"), PERMISSION_COMMANDS_CHAT(
|
||||||
@ -1066,5 +1067,4 @@ public enum Captions {
|
|||||||
} else {
|
} else {
|
||||||
caller.sendMessage(msg);
|
caller.sendMessage(msg);
|
||||||
}
|
}
|
||||||
}
|
}}
|
||||||
}
|
|
||||||
|
@ -0,0 +1,148 @@
|
|||||||
|
package com.github.intellectualsites.plotsquared.plot.util;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.incendo.jenkins.Jenkins;
|
||||||
|
import org.incendo.jenkins.objects.ArtifactDescription;
|
||||||
|
import org.incendo.jenkins.objects.BuildInfo;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class UpdateUtility {
|
||||||
|
|
||||||
|
private final String jobName;
|
||||||
|
private final Pattern artifactPattern;
|
||||||
|
|
||||||
|
private final Jenkins jenkins;
|
||||||
|
|
||||||
|
public UpdateUtility(@NonNull final String jenkinsPath, @NonNull final String jobName,
|
||||||
|
@NonNull final String artifactPattern) {
|
||||||
|
this.jobName = jobName;
|
||||||
|
this.artifactPattern = Pattern.compile(artifactPattern);
|
||||||
|
this.jenkins = Jenkins.newBuilder().withPath(jenkinsPath).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fetchLatestBuildInfo(final BiConsumer<BuildInfo, Throwable> whenDone) {
|
||||||
|
this.jenkins.getJobInfo(jobName).whenCompleteAsync((jobInfo, exception) -> {
|
||||||
|
if (jobInfo == null && exception != null) {
|
||||||
|
whenDone.accept(null, exception);
|
||||||
|
} else if (jobInfo != null) {
|
||||||
|
jobInfo.getLastSuccessfulBuild().getBuildInfo()
|
||||||
|
.whenComplete(whenDone);
|
||||||
|
} else {
|
||||||
|
whenDone.accept(null, new IllegalStateException(
|
||||||
|
String.format("Could not fetch job info for job %s", this.jobName)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getMatchingArtifact(final BiConsumer<ArtifactDescription, Throwable> whenDone) {
|
||||||
|
this.fetchLatestBuildInfo((buildInfo, throwable) -> {
|
||||||
|
if (throwable != null) {
|
||||||
|
whenDone.accept(null, throwable);
|
||||||
|
} else {
|
||||||
|
final Collection<ArtifactDescription> artifacts = buildInfo.getArtifacts();
|
||||||
|
final Optional<ArtifactDescription> artifact = artifacts.stream().filter(artifactDescription -> {
|
||||||
|
final String name = artifactDescription.getFileName();
|
||||||
|
final Matcher matcher = artifactPattern.matcher(name);
|
||||||
|
return matcher.matches();
|
||||||
|
}).findAny();
|
||||||
|
if (artifact.isPresent()) {
|
||||||
|
final ArtifactDescription artifactDescription = artifact.get();
|
||||||
|
whenDone.accept(artifactDescription, null);
|
||||||
|
} else {
|
||||||
|
whenDone.accept(null,
|
||||||
|
new NullPointerException(String.format("Could not find any matching artifacts in build %d", buildInfo.getId())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkForUpdate(final String currentVersion,
|
||||||
|
final BiConsumer<UpdateDescription, Throwable> whenDone) {
|
||||||
|
this.getMatchingArtifact(((artifactDescription, throwable) -> {
|
||||||
|
if (throwable != null) {
|
||||||
|
whenDone.accept(null, new RuntimeException(
|
||||||
|
String.format("Failed to read artifact description: %s", throwable.getMessage()), throwable));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
final String version = this.isNewer(currentVersion, artifactDescription);
|
||||||
|
if (version != null) {
|
||||||
|
whenDone.accept(new UpdateDescription(version, artifactDescription.getUrl()),
|
||||||
|
null);
|
||||||
|
} else {
|
||||||
|
whenDone.accept(null, null);
|
||||||
|
}
|
||||||
|
} catch (final Throwable exception) {
|
||||||
|
whenDone.accept(null,
|
||||||
|
new RuntimeException(String.format("Failed to compare versions: %s",
|
||||||
|
exception.getMessage()), exception));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String isNewer(@NonNull final String currentVersion, @NonNull final ArtifactDescription artifact) {
|
||||||
|
final Matcher matcher = artifactPattern.matcher(artifact.getFileName());
|
||||||
|
if (!matcher.matches()) {
|
||||||
|
throw new IllegalArgumentException("Artifact file name does not match artifact pattern");
|
||||||
|
}
|
||||||
|
final String version = matcher.group("version");
|
||||||
|
if (version == null) {
|
||||||
|
throw new IllegalArgumentException("Given artifact does not contain version");
|
||||||
|
}
|
||||||
|
return compareVersions(currentVersion, version) < 0 ? version : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two given versions in the format $major.$minor
|
||||||
|
* @param oldVersion current version
|
||||||
|
* @param newVersion other version
|
||||||
|
* @return -1 if the current version is older, 1 is the versions are the same,
|
||||||
|
* and 1 if the current version is newer
|
||||||
|
*/
|
||||||
|
private int compareVersions(@NonNull final String oldVersion, @NonNull final String newVersion) {
|
||||||
|
// Versions look this this: major.minor :P
|
||||||
|
final int[] oldNums = splitVersion(oldVersion);
|
||||||
|
final int[] newNums = splitVersion(newVersion);
|
||||||
|
|
||||||
|
if (oldNums == null || newNums == null) {
|
||||||
|
throw new IllegalArgumentException("Could not extract version data");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare major version
|
||||||
|
if (oldNums[0] != -1 && newNums[0] != -1) {
|
||||||
|
if (oldNums[0] < newNums[0]) {
|
||||||
|
return -1;
|
||||||
|
} else if (oldNums[0] > newNums[0]) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare minor versions
|
||||||
|
return Integer.compare(oldNums[1], newNums[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] splitVersion(@NonNull final String versionString) {
|
||||||
|
final String[] parts = versionString.split("\\.");
|
||||||
|
switch (parts.length) {
|
||||||
|
case 0: return new int[] {-1, -1};
|
||||||
|
case 1: return new int[] {-1, Integer.parseInt(parts[0])};
|
||||||
|
case 2: return new int[] {Integer.parseInt(parts[0]), Integer.parseInt(parts[1])};
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public static class UpdateDescription {
|
||||||
|
private final String version;
|
||||||
|
private final String url;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
8
Core/src/main/resources/updater.properties
Normal file
8
Core/src/main/resources/updater.properties
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# Whether update notifications are enabled
|
||||||
|
enabled=true
|
||||||
|
# CI path
|
||||||
|
path=https://ci.athion.net/
|
||||||
|
# Job name
|
||||||
|
job=PlotSquared-Releases
|
||||||
|
# Artifact pattern
|
||||||
|
artifact=^PlotSquared-Bukkit-(?<version>[0-9.]+).jar$
|
@ -76,5 +76,6 @@ subprojects {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url "http://maven.sk89q.com/repo/" }
|
maven { url "http://maven.sk89q.com/repo/" }
|
||||||
maven { url "http://repo.maven.apache.org/maven2" }
|
maven { url "http://repo.maven.apache.org/maven2" }
|
||||||
|
maven { url 'https://jitpack.io' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user