mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-02 04:56:50 +01:00
Added a built-in update checker. See http://wiki.bukkit.org/Bukkit.yml#auto-updater for new bukkit.yml options.
This commit is contained in:
parent
64264f61b8
commit
236cfed616
8 changed files with 317 additions and 0 deletions
5
pom.xml
5
pom.xml
|
@ -130,6 +130,11 @@
|
|||
<version>1.2.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<!-- This builds a completely 'ready to start' jar with all dependencies inside -->
|
||||
|
|
|
@ -135,6 +135,7 @@ public class ServerConfigurationManager {
|
|||
if ((joinMessage != null) && (joinMessage.length() > 0)) {
|
||||
this.server.serverConfigurationManager.sendAll(new Packet3Chat(joinMessage));
|
||||
}
|
||||
this.cserver.onPlayerJoin(playerJoinEvent.getPlayer());
|
||||
// CraftBukkit end
|
||||
|
||||
worldserver.addEntity(entityplayer);
|
||||
|
|
|
@ -78,6 +78,8 @@ import org.bukkit.craftbukkit.map.CraftMapView;
|
|||
import org.bukkit.craftbukkit.potion.CraftPotionBrewer;
|
||||
import org.bukkit.scheduler.BukkitWorker;
|
||||
import org.bukkit.craftbukkit.scheduler.CraftScheduler;
|
||||
import org.bukkit.craftbukkit.updater.AutoUpdater;
|
||||
import org.bukkit.craftbukkit.updater.BukkitDLUpdaterService;
|
||||
import org.bukkit.craftbukkit.util.DatFileFilter;
|
||||
import org.bukkit.craftbukkit.util.Versioning;
|
||||
import org.bukkit.util.permissions.DefaultPermissions;
|
||||
|
@ -106,6 +108,7 @@ public final class CraftServer implements Server {
|
|||
private YamlConfiguration configuration;
|
||||
private final Yaml yaml = new Yaml(new SafeConstructor());
|
||||
private final Map<String, OfflinePlayer> offlinePlayers = new MapMaker().softValues().makeMap();
|
||||
private AutoUpdater updater;
|
||||
|
||||
static {
|
||||
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);
|
||||
|
@ -137,6 +140,12 @@ public final class CraftServer implements Server {
|
|||
saveConfig();
|
||||
((SimplePluginManager) pluginManager).useTimings(configuration.getBoolean("settings.plugin-profiling", false));
|
||||
|
||||
updater = new AutoUpdater(new BukkitDLUpdaterService(configuration.getString("auto-updater.host")), getLogger(), configuration.getString("auto-updater.preferred-channel"));
|
||||
updater.setEnabled(configuration.getBoolean("auto-updater.enabled"));
|
||||
updater.getOnBroken().addAll(configuration.getStringList("auto-updater.on-broken"));
|
||||
updater.getOnUpdate().addAll(configuration.getStringList("auto-updater.on-update"));
|
||||
updater.check(serverVersion);
|
||||
|
||||
loadPlugins();
|
||||
enablePlugins(PluginLoadOrder.STARTUP);
|
||||
|
||||
|
@ -1013,4 +1022,14 @@ public final class CraftServer implements Server {
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void onPlayerJoin(Player player) {
|
||||
if ((updater.isEnabled()) && (player.hasPermission(Server.BROADCAST_CHANNEL_ADMINISTRATIVE))) {
|
||||
if ((updater.getCurrent().isBroken()) && (updater.getOnBroken().contains(updater.WARN_OPERATORS))) {
|
||||
player.sendMessage(ChatColor.DARK_RED + "The version of CraftBukkit that this server is running is known to be broken. Please consider updating to the latest version at dl.bukkit.org.");
|
||||
} else if ((updater.isUpdateAvailable()) && (updater.getOnUpdate().contains(updater.WARN_OPERATORS))) {
|
||||
player.sendMessage(ChatColor.DARK_PURPLE + "The version of CraftBukkit that this server is running is out of date. Please consider updating to the latest version at dl.bukkit.org.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
package org.bukkit.craftbukkit.updater;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class ArtifactDetails {
|
||||
private String brokenReason;
|
||||
private boolean isBroken;
|
||||
private int buildNumber;
|
||||
private String htmlUrl;
|
||||
private String version;
|
||||
private Date created;
|
||||
private FileDetails file;
|
||||
|
||||
public FileDetails getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public void setFile(FileDetails file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public String getBrokenReason() {
|
||||
return brokenReason;
|
||||
}
|
||||
|
||||
public void setBrokenReason(String brokenReason) {
|
||||
this.brokenReason = brokenReason;
|
||||
}
|
||||
|
||||
public int getBuildNumber() {
|
||||
return buildNumber;
|
||||
}
|
||||
|
||||
public void setBuildNumber(int buildNumber) {
|
||||
this.buildNumber = buildNumber;
|
||||
}
|
||||
|
||||
public Date getCreated() {
|
||||
return created;
|
||||
}
|
||||
|
||||
public void setCreated(Date created) {
|
||||
this.created = created;
|
||||
}
|
||||
|
||||
public String getHtmlUrl() {
|
||||
return htmlUrl;
|
||||
}
|
||||
|
||||
public void setHtmlUrl(String htmlUrl) {
|
||||
this.htmlUrl = htmlUrl;
|
||||
}
|
||||
|
||||
public boolean isBroken() {
|
||||
return isBroken;
|
||||
}
|
||||
|
||||
public void setBroken(boolean isBroken) {
|
||||
this.isBroken = isBroken;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public static class FileDetails {
|
||||
private String url;
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
}
|
107
src/main/java/org/bukkit/craftbukkit/updater/AutoUpdater.java
Normal file
107
src/main/java/org/bukkit/craftbukkit/updater/AutoUpdater.java
Normal file
|
@ -0,0 +1,107 @@
|
|||
package org.bukkit.craftbukkit.updater;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class AutoUpdater {
|
||||
public static final String WARN_CONSOLE = "warn-console";
|
||||
public static final String WARN_OPERATORS = "warn-ops";
|
||||
|
||||
private final BukkitDLUpdaterService service;
|
||||
private final List<String> onUpdate = new ArrayList<String>();
|
||||
private final List<String> onBroken = new ArrayList<String>();
|
||||
private final Logger log;
|
||||
private final String channel;
|
||||
private boolean enabled;
|
||||
private ArtifactDetails current = null;
|
||||
private ArtifactDetails latest = null;
|
||||
|
||||
public AutoUpdater(BukkitDLUpdaterService service, Logger log, String channel) {
|
||||
this.service = service;
|
||||
this.log = log;
|
||||
this.channel = channel;
|
||||
}
|
||||
|
||||
public String getChannel() {
|
||||
return channel;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean isEnabled) {
|
||||
this.enabled = isEnabled;
|
||||
}
|
||||
|
||||
public List<String> getOnBroken() {
|
||||
return onBroken;
|
||||
}
|
||||
|
||||
public List<String> getOnUpdate() {
|
||||
return onUpdate;
|
||||
}
|
||||
|
||||
public boolean isUpdateAvailable() {
|
||||
if ((latest == null) || (current == null) || (!isEnabled())) {
|
||||
return false;
|
||||
} else {
|
||||
return latest.getCreated().after(current.getCreated());
|
||||
}
|
||||
}
|
||||
|
||||
public ArtifactDetails getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
public ArtifactDetails getLatest() {
|
||||
return latest;
|
||||
}
|
||||
|
||||
public void check(final String currentSlug) {
|
||||
if (!isEnabled()) return;
|
||||
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
current = service.getArtifact(currentSlug);
|
||||
latest = service.getArtifact("latest-" + channel);
|
||||
|
||||
if (isUpdateAvailable()) {
|
||||
if ((current.isBroken()) && (onBroken.contains(WARN_CONSOLE))) {
|
||||
log.severe("----- Bukkit Auto Updater -----");
|
||||
log.severe("Your version of CraftBukkit is known to be broken. It is strongly advised that you update to a more recent version ASAP.");
|
||||
log.severe("Known issues with your version:");
|
||||
|
||||
for (String line : current.getBrokenReason().split("\n")) {
|
||||
log.severe("> " + line);
|
||||
}
|
||||
|
||||
log.severe("Newer version " + latest.getVersion() + " (build #" + latest.getBuildNumber() + ") was released on " + latest.getCreated() + ".");
|
||||
log.severe("Details: " + latest.getHtmlUrl());
|
||||
log.severe("Download: " + latest.getFile().getUrl());
|
||||
log.severe("----- ------------------- -----");
|
||||
} else if (onUpdate.contains(WARN_CONSOLE)) {
|
||||
log.warning("----- Bukkit Auto Updater -----");
|
||||
log.warning("Your version of CraftBukkit is out of date. Version " + latest.getVersion() + " (build #" + latest.getBuildNumber() + ") was released on " + latest.getCreated() + ".");
|
||||
log.warning("Details: " + latest.getHtmlUrl());
|
||||
log.warning("Download: " + latest.getFile().getUrl());
|
||||
log.warning("----- ------------------- -----");
|
||||
}
|
||||
} else if ((current != null) && (current.isBroken()) && (onBroken.contains(WARN_CONSOLE))) {
|
||||
log.severe("----- Bukkit Auto Updater -----");
|
||||
log.severe("Your version of CraftBukkit is known to be broken. It is strongly advised that you update to a more recent version ASAP.");
|
||||
log.severe("Known issues with your version:");
|
||||
|
||||
for (String line : current.getBrokenReason().split("\n")) {
|
||||
log.severe("> " + line);
|
||||
}
|
||||
|
||||
log.severe("Unfortunately, there is not yet a newer version suitable for your server. We would advise you wait an hour or two, or try out a dev build.");
|
||||
log.severe("----- ------------------- -----");
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package org.bukkit.craftbukkit.updater;
|
||||
|
||||
import com.google.gson.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.text.DateFormat;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class BukkitDLUpdaterService {
|
||||
private static final String API_PREFIX = "/api/1.0/downloads/projects/craftbukkit/view/";
|
||||
private static final DateDeserializer dateDeserializer = new DateDeserializer();
|
||||
private final String host;
|
||||
|
||||
public BukkitDLUpdaterService(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public ArtifactDetails getArtifact(String slug) {
|
||||
try {
|
||||
return fetchArtifact(slug);
|
||||
} catch (UnsupportedEncodingException ex) {
|
||||
Logger.getLogger(BukkitDLUpdaterService.class.getName()).log(Level.WARNING, "Could not get Artifact details for the auto-updater", ex);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(BukkitDLUpdaterService.class.getName()).log(Level.WARNING, "Could not get Artifact details for the auto-updater", ex);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ArtifactDetails fetchArtifact(String slug) throws UnsupportedEncodingException, IOException {
|
||||
URL url = new URL("http", host, API_PREFIX + slug);
|
||||
InputStreamReader reader = null;
|
||||
|
||||
try {
|
||||
reader = new InputStreamReader(url.openStream());
|
||||
Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, dateDeserializer).setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
|
||||
ArtifactDetails fromJson = gson.fromJson(reader, ArtifactDetails.class);
|
||||
|
||||
return fromJson;
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
reader.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class DateDeserializer implements JsonDeserializer<Date> {
|
||||
private static final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
public Date deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException {
|
||||
try {
|
||||
return format.parse(je.getAsString());
|
||||
} catch (ParseException ex) {
|
||||
throw new JsonParseException("Date is not formatted correctly", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,6 +24,12 @@ settings:
|
|||
ticks-per:
|
||||
animal-spawns: 400
|
||||
monster-spawns: 1
|
||||
auto-updater:
|
||||
enabled: true
|
||||
on-broken: [warn-console, warn-ops]
|
||||
on-update: [warn-console, warn-ops]
|
||||
preferred-channel: rb
|
||||
host: dl.bukkit.org
|
||||
aliases:
|
||||
icanhasbukkit:
|
||||
- version
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package org.bukkit.craftbukkit.updater;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BukkitDLUpdaterServiceTest {
|
||||
@Test(expected=IOException.class)
|
||||
public void testHostNotFound() throws UnsupportedEncodingException, IOException {
|
||||
BukkitDLUpdaterService service = new BukkitDLUpdaterService("404.example.org");
|
||||
|
||||
service.fetchArtifact("rb");
|
||||
}
|
||||
|
||||
@Test(expected=FileNotFoundException.class)
|
||||
public void testArtifactNotFound() throws UnsupportedEncodingException, IOException {
|
||||
BukkitDLUpdaterService service = new BukkitDLUpdaterService("dl.bukkit.org");
|
||||
|
||||
service.fetchArtifact("meep");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArtifactExists() throws UnsupportedEncodingException, IOException {
|
||||
BukkitDLUpdaterService service = new BukkitDLUpdaterService("dl.bukkit.org");
|
||||
|
||||
assertNotNull(service.fetchArtifact("latest-dev"));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue