updater should work but not sure so releasing to test
This commit is contained in:
		
					parent
					
						
							
								aa100110bd
							
						
					
				
			
			
				commit
				
					
						00a774e779
					
				
			
		
					 14 changed files with 342 additions and 96 deletions
				
			
		
							
								
								
									
										9
									
								
								pom.xml
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								pom.xml
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -11,6 +11,10 @@
 | 
			
		|||
		<jarsigner.alias>testkey</jarsigner.alias>
 | 
			
		||||
		<jarsigner.storepass>123456</jarsigner.storepass>
 | 
			
		||||
    </properties>
 | 
			
		||||
    
 | 
			
		||||
    <scm>
 | 
			
		||||
		<developerConnection>scm:git:git@git.724.rocks:Minecon724/realweather.git</developerConnection>
 | 
			
		||||
	</scm>
 | 
			
		||||
	  
 | 
			
		||||
	<repositories>
 | 
			
		||||
	    <repository>
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +49,11 @@
 | 
			
		|||
	      	</resource>
 | 
			
		||||
		</resources>
 | 
			
		||||
        <plugins>
 | 
			
		||||
			<plugin>
 | 
			
		||||
	        	<groupId>org.apache.maven.plugins</groupId>
 | 
			
		||||
	        	<artifactId>maven-release-plugin</artifactId>
 | 
			
		||||
	        	<version>3.0.1</version>
 | 
			
		||||
	      	</plugin>
 | 
			
		||||
            <plugin>
 | 
			
		||||
                <groupId>org.apache.maven.plugins</groupId>
 | 
			
		||||
          		<artifactId>maven-shade-plugin</artifactId>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										21
									
								
								release.properties
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								release.properties
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
#release configuration
 | 
			
		||||
#Tue Jun 18 13:22:44 CEST 2024
 | 
			
		||||
completedPhase=check-poms
 | 
			
		||||
exec.pomFileName=pom.xml
 | 
			
		||||
exec.snapshotReleasePluginAllowed=false
 | 
			
		||||
pinExternals=false
 | 
			
		||||
preparationGoals=clean verify
 | 
			
		||||
project.scm.eu.m724\:realweather.developerConnection=scm\:git\:git@git.724.rocks\:Minecon724/realweather.git
 | 
			
		||||
project.scm.eu.m724\:realweather.tag=HEAD
 | 
			
		||||
projectVersionPolicyConfig=<projectVersionPolicyConfig>${projectVersionPolicyConfig}</projectVersionPolicyConfig>\n
 | 
			
		||||
projectVersionPolicyId=default
 | 
			
		||||
pushChanges=true
 | 
			
		||||
releaseStrategyId=default
 | 
			
		||||
remoteTagging=true
 | 
			
		||||
scm.branchCommitComment=@{prefix} prepare branch @{releaseLabel}
 | 
			
		||||
scm.commentPrefix=[maven-release-plugin] 
 | 
			
		||||
scm.developmentCommitComment=@{prefix} prepare for next development iteration
 | 
			
		||||
scm.releaseCommitComment=@{prefix} prepare release @{releaseLabel}
 | 
			
		||||
scm.rollbackCommitComment=@{prefix} rollback the release of @{releaseLabel}
 | 
			
		||||
scm.tagNameFormat=@{project.artifactId}-@{project.version}
 | 
			
		||||
scm.url=scm\:git\:git@git.724.rocks\:Minecon724/realweather.git
 | 
			
		||||
| 
						 | 
				
			
			@ -13,6 +13,6 @@ public class DebugLogger {
 | 
			
		|||
	
 | 
			
		||||
	public static void info(String message, int minDebugLevel, Object... format) {
 | 
			
		||||
		if (debugLevel >= minDebugLevel)
 | 
			
		||||
			baseLogger.info(String.format(message, format));
 | 
			
		||||
			baseLogger.info(message.formatted(format));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ import eu.m724.realweather.mapper.MapperConfig;
 | 
			
		|||
import eu.m724.realweather.thunder.ThunderConfig;
 | 
			
		||||
import eu.m724.realweather.thunder.ThunderMaster;
 | 
			
		||||
import eu.m724.realweather.time.TimeConfig;
 | 
			
		||||
import eu.m724.realweather.updater.UpdaterConfig;
 | 
			
		||||
import eu.m724.realweather.weather.PlayerWeatherDirectory;
 | 
			
		||||
import eu.m724.realweather.weather.WeatherConfig;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -15,6 +16,7 @@ public class GlobalConstants {
 | 
			
		|||
	static TimeConfig timeConfig;
 | 
			
		||||
	static ThunderConfig thunderConfig;
 | 
			
		||||
	static MapperConfig mapperConfig;
 | 
			
		||||
	static UpdaterConfig updaterConfig;
 | 
			
		||||
	
 | 
			
		||||
	static ThunderMaster thunderMaster;
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +36,9 @@ public class GlobalConstants {
 | 
			
		|||
	public static MapperConfig getMapperConfig() {
 | 
			
		||||
		return mapperConfig;
 | 
			
		||||
	}
 | 
			
		||||
	public static UpdaterConfig getUpdaterConfig() {
 | 
			
		||||
		return updaterConfig;
 | 
			
		||||
	}
 | 
			
		||||
	public static ThunderMaster getThunderMaster() {
 | 
			
		||||
		return thunderMaster;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@ import com.google.common.base.Charsets;
 | 
			
		|||
import eu.m724.realweather.commands.AdminCommand;
 | 
			
		||||
import eu.m724.realweather.commands.GeoCommand;
 | 
			
		||||
import eu.m724.realweather.commands.LocalTimeCommand;
 | 
			
		||||
import eu.m724.realweather.commands.UpdateCommand;
 | 
			
		||||
import eu.m724.realweather.mapper.Mapper;
 | 
			
		||||
import eu.m724.realweather.mapper.MapperConfig;
 | 
			
		||||
import eu.m724.realweather.object.UserException;
 | 
			
		||||
| 
						 | 
				
			
			@ -23,6 +24,7 @@ import eu.m724.realweather.time.TimeConfig;
 | 
			
		|||
import eu.m724.realweather.time.TimeMaster;
 | 
			
		||||
import eu.m724.realweather.updater.SignatureValidator;
 | 
			
		||||
import eu.m724.realweather.updater.Updater;
 | 
			
		||||
import eu.m724.realweather.updater.UpdaterConfig;
 | 
			
		||||
import eu.m724.realweather.weather.WeatherConfig;
 | 
			
		||||
import eu.m724.realweather.weather.WeatherMaster;
 | 
			
		||||
import eu.m724.wtapi.provider.exception.ProviderException;
 | 
			
		||||
| 
						 | 
				
			
			@ -31,6 +33,7 @@ public class RealWeatherPlugin extends JavaPlugin {
 | 
			
		|||
	private WeatherMaster weatherMaster;
 | 
			
		||||
	private ThunderMaster thunderMaster;
 | 
			
		||||
	private TimeMaster timeMaster;
 | 
			
		||||
	private Updater updater;
 | 
			
		||||
	
 | 
			
		||||
	private Logger logger;
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			@ -112,6 +115,10 @@ public class RealWeatherPlugin extends JavaPlugin {
 | 
			
		|||
			GlobalConstants.timeConfig = TimeConfig.fromConfiguration(timeConfiguration); 
 | 
			
		||||
			timeMaster = new TimeMaster(GlobalConstants.timeConfig);
 | 
			
		||||
			timeMaster.init();
 | 
			
		||||
			
 | 
			
		||||
			GlobalConstants.updaterConfig = UpdaterConfig.fromConfiguration(configuration.getConfigurationSection("updater"));
 | 
			
		||||
			updater = new Updater(GlobalConstants.updaterConfig);
 | 
			
		||||
			updater.init();
 | 
			
		||||
		} catch (UserException e) {
 | 
			
		||||
			logger.severe("There are errors in your config:");
 | 
			
		||||
			logger.severe(e.getMessage());
 | 
			
		||||
| 
						 | 
				
			
			@ -132,13 +139,12 @@ public class RealWeatherPlugin extends JavaPlugin {
 | 
			
		|||
		GlobalConstants.thunderMaster = thunderMaster;
 | 
			
		||||
 | 
			
		||||
		getCommand("rwadmin").setExecutor(new AdminCommand());
 | 
			
		||||
		getCommand("rwadmin update").setExecutor(new UpdateCommand(updater));
 | 
			
		||||
		getCommand("geo").setExecutor(new GeoCommand());
 | 
			
		||||
		
 | 
			
		||||
		if (GlobalConstants.timeConfig.enabled)
 | 
			
		||||
			getCommand("localtime").setExecutor(new LocalTimeCommand());
 | 
			
		||||
		
 | 
			
		||||
		new Updater().init();
 | 
			
		||||
			
 | 
			
		||||
		DebugLogger.info("ended loading", 1);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,37 @@
 | 
			
		|||
package eu.m724.realweather.commands;
 | 
			
		||||
 | 
			
		||||
import java.util.concurrent.CompletableFuture;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.command.Command;
 | 
			
		||||
import org.bukkit.command.CommandExecutor;
 | 
			
		||||
import org.bukkit.command.CommandSender;
 | 
			
		||||
 | 
			
		||||
import eu.m724.realweather.updater.Updater;
 | 
			
		||||
import eu.m724.realweather.updater.metadata.VersionMetadata;
 | 
			
		||||
 | 
			
		||||
public class UpdateCommand implements CommandExecutor {
 | 
			
		||||
	private Updater updater;
 | 
			
		||||
	
 | 
			
		||||
	public UpdateCommand(Updater updater) {
 | 
			
		||||
		this.updater = updater;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
 | 
			
		||||
		sender.sendMessage("Please wait");
 | 
			
		||||
		CompletableFuture<VersionMetadata> latestFuture = updater.getLatestVersion();
 | 
			
		||||
		
 | 
			
		||||
		latestFuture.thenAccept(metadata -> {
 | 
			
		||||
			if (metadata != null) {
 | 
			
		||||
				sender.sendMessage("An update is available!");
 | 
			
		||||
				sender.sendMessage("RealWeather %s released %s".formatted(metadata.label, metadata.getFormattedDate()));
 | 
			
		||||
				sender.sendMessage("To download: /rwadmin update download");
 | 
			
		||||
			} else {
 | 
			
		||||
				sender.sendMessage("No new updates"); // TODO color
 | 
			
		||||
			}
 | 
			
		||||
		});
 | 
			
		||||
		
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,62 +0,0 @@
 | 
			
		|||
package eu.m724.realweather.updater;
 | 
			
		||||
 | 
			
		||||
import java.net.ProxySelector;
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.net.http.HttpClient;
 | 
			
		||||
import java.net.http.HttpRequest;
 | 
			
		||||
import java.net.http.HttpResponse;
 | 
			
		||||
import java.net.http.HttpClient.Redirect;
 | 
			
		||||
import java.net.http.HttpResponse.BodyHandlers;
 | 
			
		||||
import java.util.concurrent.CompletableFuture;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.Gson;
 | 
			
		||||
 | 
			
		||||
public class MetadataRetriever {
 | 
			
		||||
	private String version;
 | 
			
		||||
	
 | 
			
		||||
	private CompletableFuture<VersionMetadata> currentMetadataCached = null;
 | 
			
		||||
	
 | 
			
		||||
	public MetadataRetriever(Plugin plugin) {
 | 
			
		||||
		this.version = plugin.getDescription().getVersion();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private CompletableFuture<VersionMetadata> getMetadataFromUrl(String url) {
 | 
			
		||||
		HttpRequest request = HttpRequest.newBuilder()
 | 
			
		||||
				.uri(URI.create(url))
 | 
			
		||||
				.header("User-Agent", "rwu/1")
 | 
			
		||||
				.build();
 | 
			
		||||
		
 | 
			
		||||
		CompletableFuture<HttpResponse<String>> responseFuture =
 | 
			
		||||
				HttpClient.newBuilder()
 | 
			
		||||
				.followRedirects(Redirect.NORMAL)
 | 
			
		||||
				.proxy(ProxySelector.getDefault()).build().
 | 
			
		||||
				sendAsync(request, BodyHandlers.ofString());
 | 
			
		||||
		
 | 
			
		||||
		CompletableFuture<VersionMetadata> metadataFuture =
 | 
			
		||||
				responseFuture.thenApply(response -> {
 | 
			
		||||
					if (response.statusCode() != 200)
 | 
			
		||||
						return null;
 | 
			
		||||
					
 | 
			
		||||
					VersionMetadata versionMetadata = new Gson().fromJson(response.body(), VersionMetadata.class);
 | 
			
		||||
					return versionMetadata;
 | 
			
		||||
				});
 | 
			
		||||
		
 | 
			
		||||
		return metadataFuture;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public CompletableFuture<VersionMetadata> getLatestVersionMetadata() {
 | 
			
		||||
		return getMetadataFromUrl("https://git.724.rocks/Minecon724/realweather-metadata/raw/branch/master/latest/latest-v1.json");
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public CompletableFuture<VersionMetadata> getCurrentVersionMetadata() {
 | 
			
		||||
		if (currentMetadataCached != null)
 | 
			
		||||
			currentMetadataCached = getVersionMetadata(version);
 | 
			
		||||
		return currentMetadataCached;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public CompletableFuture<VersionMetadata> getVersionMetadata(String version) {
 | 
			
		||||
		return getMetadataFromUrl("https://git.724.rocks/Minecon724/realweather-metadata/raw/branch/master/releases/" + version + "/meta-v1.json");
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
package eu.m724.realweather.updater;
 | 
			
		||||
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.CompletableFuture;
 | 
			
		||||
import java.util.concurrent.CompletionException;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
| 
						 | 
				
			
			@ -10,18 +10,25 @@ import org.bukkit.event.Listener;
 | 
			
		|||
import org.bukkit.event.player.PlayerJoinEvent;
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
import org.bukkit.scheduler.BukkitRunnable;
 | 
			
		||||
 | 
			
		||||
import eu.m724.realweather.DebugLogger;
 | 
			
		||||
import eu.m724.realweather.GlobalConstants;
 | 
			
		||||
import eu.m724.realweather.object.UserException;
 | 
			
		||||
import eu.m724.realweather.updater.metadata.MetadataRetriever;
 | 
			
		||||
import eu.m724.realweather.updater.metadata.MetadataServerException;
 | 
			
		||||
import eu.m724.realweather.updater.metadata.VersionMetadata;
 | 
			
		||||
import net.md_5.bungee.api.ChatColor;
 | 
			
		||||
import net.md_5.bungee.api.chat.BaseComponent;
 | 
			
		||||
import net.md_5.bungee.api.chat.ComponentBuilder;
 | 
			
		||||
 | 
			
		||||
public class Updater extends BukkitRunnable implements Listener {
 | 
			
		||||
	private Plugin plugin = GlobalConstants.getPlugin();
 | 
			
		||||
	private MetadataRetriever metadataRetriever = new MetadataRetriever(plugin);
 | 
			
		||||
	private UpdaterConfig updaterConfig;
 | 
			
		||||
	private MetadataRetriever metadataRetriever;
 | 
			
		||||
	
 | 
			
		||||
	private VersionMetadata availableUpdate = null;
 | 
			
		||||
	private Plugin plugin = GlobalConstants.getPlugin();
 | 
			
		||||
	
 | 
			
		||||
	private VersionMetadata currentMetadata;
 | 
			
		||||
	private VersionMetadata latestMetadata;
 | 
			
		||||
	private long checkCacheExpires;
 | 
			
		||||
	
 | 
			
		||||
	private BaseComponent updateMessage = null;
 | 
			
		||||
	private BaseComponent updateActionMessage =
 | 
			
		||||
| 
						 | 
				
			
			@ -29,19 +36,91 @@ public class Updater extends BukkitRunnable implements Listener {
 | 
			
		|||
			.append("/rwadmin update").color(ChatColor.AQUA)
 | 
			
		||||
			.build();
 | 
			
		||||
	
 | 
			
		||||
	public void init() {
 | 
			
		||||
		this.runTaskTimerAsynchronously(plugin, 0, 216000); // 3h
 | 
			
		||||
		plugin.getServer().getPluginManager().registerEvents(this, plugin);
 | 
			
		||||
	public Updater(UpdaterConfig updaterConfig) {
 | 
			
		||||
		this.updaterConfig = updaterConfig;
 | 
			
		||||
		this.metadataRetriever = new MetadataRetriever(plugin, updaterConfig.channel);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void init() throws UserException {
 | 
			
		||||
		try {
 | 
			
		||||
			DebugLogger.info("probing for channels...", 1);
 | 
			
		||||
			
 | 
			
		||||
			List<String> channels = metadataRetriever.getChannels().join();
 | 
			
		||||
			if (!channels.contains(updaterConfig.channel)) {
 | 
			
		||||
				throw new UserException(
 | 
			
		||||
						"Invalid channel: %s. Valid ones are: %s"
 | 
			
		||||
						.formatted(updaterConfig.channel, String.join(", ", channels))); // WHY DID NOBODY TELL ME ABOUT .formatted
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			currentMetadata = metadataRetriever.getCurrentVersionMetadata().join();
 | 
			
		||||
			DebugLogger.info("current: %d", 1, currentMetadata.id);
 | 
			
		||||
		} catch (CompletionException e) {
 | 
			
		||||
			int statusCode = ((MetadataServerException) e.getCause()).getStatusCode();
 | 
			
		||||
			if (statusCode >= 500) {
 | 
			
		||||
				DebugLogger.info("Unable to contact the update server! %d", 0, statusCode);
 | 
			
		||||
				DebugLogger.info("As it's a server error, it's probably temporary and not a configuration issue, so proceeding.", 0);
 | 
			
		||||
			} else {
 | 
			
		||||
				DebugLogger.info("Update server returned unexpected status code! %d", 0, statusCode);
 | 
			
		||||
				if (plugin.getDescription().getVersion().endsWith("SNAPSHOT")) {
 | 
			
		||||
					DebugLogger.info("It looks like this is a development snapshot, possibly built from source. So actually this is expected.", 0);
 | 
			
		||||
				} else {
 | 
			
		||||
					DebugLogger.info("This is probably critical. RealWeather will continue without updater.", 0);
 | 
			
		||||
					DebugLogger.info("Try restarting the server. If that doesn't help, contact support.", 0);
 | 
			
		||||
				}
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		if (updaterConfig.notify) {
 | 
			
		||||
			this.runTaskTimerAsynchronously(plugin, 0, 216000); // 3h
 | 
			
		||||
			plugin.getServer().getPluginManager().registerEvents(this, plugin);
 | 
			
		||||
			DebugLogger.info("updater will notify", 1);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		DebugLogger.info("updater loaded", 1);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean installUpdate() {
 | 
			
		||||
		if (availableUpdate == null)
 | 
			
		||||
		if (latestMetadata == null)
 | 
			
		||||
			return false;
 | 
			
		||||
		
 | 
			
		||||
		// TODO dont forget about verifictaion
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public CompletableFuture<VersionMetadata> getLatestVersion() {
 | 
			
		||||
		if (System.currentTimeMillis() < checkCacheExpires)
 | 
			
		||||
			return CompletableFuture.completedFuture(latestMetadata);
 | 
			
		||||
		else
 | 
			
		||||
			return checkForNewVersion().handle((result, ex) -> null);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * this can throw completionexception
 | 
			
		||||
	 * @return
 | 
			
		||||
	 */
 | 
			
		||||
	private CompletableFuture<VersionMetadata> checkForNewVersion() {
 | 
			
		||||
		CompletableFuture<VersionMetadata> latestMetadataFuture =
 | 
			
		||||
				metadataRetriever.getLatestVersionMetadata();
 | 
			
		||||
		
 | 
			
		||||
		CompletableFuture<VersionMetadata> newMetadataFuture =
 | 
			
		||||
				latestMetadataFuture.thenApply(latestMetadata -> {
 | 
			
		||||
					DebugLogger.info("Current version: %s (%d)", 2, currentMetadata.label, currentMetadata.id);
 | 
			
		||||
					DebugLogger.info("Latest version: %s (%d)", 2, latestMetadata.label, latestMetadata.id);
 | 
			
		||||
					
 | 
			
		||||
					if (currentMetadata.id < latestMetadata.id) {
 | 
			
		||||
						this.latestMetadata = latestMetadata;
 | 
			
		||||
						this.checkCacheExpires = System.currentTimeMillis() + 10800000;
 | 
			
		||||
						return latestMetadata;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					this.checkCacheExpires = System.currentTimeMillis() + 3600000;
 | 
			
		||||
					return null;
 | 
			
		||||
				});
 | 
			
		||||
		
 | 
			
		||||
		return newMetadataFuture;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@EventHandler
 | 
			
		||||
	public void onPlayerJoin(PlayerJoinEvent event) {
 | 
			
		||||
		Player player = event.getPlayer();
 | 
			
		||||
| 
						 | 
				
			
			@ -57,30 +136,22 @@ public class Updater extends BukkitRunnable implements Listener {
 | 
			
		|||
	@Override
 | 
			
		||||
	public void run() {
 | 
			
		||||
		DebugLogger.info("Checking for update...", 2);
 | 
			
		||||
		CompletableFuture<VersionMetadata> currentMetadataFuture =
 | 
			
		||||
				metadataRetriever.getCurrentVersionMetadata();
 | 
			
		||||
 | 
			
		||||
		CompletableFuture<VersionMetadata> latestMetadataFuture =
 | 
			
		||||
				metadataRetriever.getLatestVersionMetadata();
 | 
			
		||||
		
 | 
			
		||||
		VersionMetadata currentMetadata = currentMetadataFuture.join();
 | 
			
		||||
		VersionMetadata latestMetadata = latestMetadataFuture.join();
 | 
			
		||||
		CompletableFuture<VersionMetadata> newVersionFuture = checkForNewVersion();
 | 
			
		||||
		
 | 
			
		||||
		DebugLogger.info("Current version: %s (%d)", 2, currentMetadata.label, currentMetadata.id);
 | 
			
		||||
		DebugLogger.info("Latest version: %s (%d)", 2, latestMetadata.label, latestMetadata.id);
 | 
			
		||||
		
 | 
			
		||||
		if (currentMetadata.id >= latestMetadata.id) return;
 | 
			
		||||
 | 
			
		||||
		availableUpdate = latestMetadata;
 | 
			
		||||
		
 | 
			
		||||
		String formattedDate = new SimpleDateFormat("dd.MM").format(new Date(latestMetadata.timestamp));
 | 
			
		||||
		try {
 | 
			
		||||
			newVersionFuture.join();
 | 
			
		||||
		} catch (CompletionException e) {
 | 
			
		||||
			int statusCode = ((MetadataServerException) e.getCause()).getStatusCode();
 | 
			
		||||
			DebugLogger.info("Couldn't check for updates: %d", 0, statusCode);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		updateMessage = new ComponentBuilder("An update is available!\n")
 | 
			
		||||
				.color(ChatColor.YELLOW)
 | 
			
		||||
				.append("RealWeather ").color(ChatColor.GOLD)
 | 
			
		||||
				.append(latestMetadata.label).color(ChatColor.AQUA).bold(true)
 | 
			
		||||
				.append(" released ").color(ChatColor.GOLD)
 | 
			
		||||
				.append(formattedDate).color(ChatColor.AQUA)
 | 
			
		||||
				.append(latestMetadata.getFormattedDate()).color(ChatColor.AQUA)
 | 
			
		||||
				.append("\nCurrent: ").color(ChatColor.GRAY)
 | 
			
		||||
				.append(currentMetadata.label).color(ChatColor.DARK_AQUA)
 | 
			
		||||
				.build();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										17
									
								
								src/main/java/eu/m724/realweather/updater/UpdaterConfig.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/main/java/eu/m724/realweather/updater/UpdaterConfig.java
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
package eu.m724.realweather.updater;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.configuration.ConfigurationSection;
 | 
			
		||||
 | 
			
		||||
public class UpdaterConfig {
 | 
			
		||||
	public boolean notify;
 | 
			
		||||
	public String channel;
 | 
			
		||||
	
 | 
			
		||||
	public static UpdaterConfig fromConfiguration(ConfigurationSection configuration) {
 | 
			
		||||
		UpdaterConfig updaterConfig = new UpdaterConfig();
 | 
			
		||||
		
 | 
			
		||||
		updaterConfig.notify = configuration.getBoolean("notify");
 | 
			
		||||
		updaterConfig.channel = configuration.getString("channel");
 | 
			
		||||
		
 | 
			
		||||
		return updaterConfig;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,107 @@
 | 
			
		|||
package eu.m724.realweather.updater.metadata;
 | 
			
		||||
 | 
			
		||||
import java.net.ProxySelector;
 | 
			
		||||
import java.net.URI;
 | 
			
		||||
import java.net.http.HttpClient;
 | 
			
		||||
import java.net.http.HttpRequest;
 | 
			
		||||
import java.net.http.HttpResponse;
 | 
			
		||||
import java.net.http.HttpClient.Redirect;
 | 
			
		||||
import java.net.http.HttpResponse.BodyHandlers;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.CompletableFuture;
 | 
			
		||||
import java.util.concurrent.CompletionException;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.plugin.Plugin;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.Gson;
 | 
			
		||||
 | 
			
		||||
public class MetadataRetriever {
 | 
			
		||||
	private String version;
 | 
			
		||||
	private String channel;
 | 
			
		||||
	
 | 
			
		||||
	private CompletableFuture<VersionMetadata> currentMetadataCached = null;
 | 
			
		||||
	
 | 
			
		||||
	public MetadataRetriever(Plugin plugin, String channel) {
 | 
			
		||||
		this.version = plugin.getDescription().getVersion();
 | 
			
		||||
		this.channel = channel;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	/**
 | 
			
		||||
	 * the completablefuture can throw a completionexception with {@link eu.m724.realweather.updater.metadata.MetadataServerException}
 | 
			
		||||
	 */
 | 
			
		||||
	private CompletableFuture<VersionMetadata> getMetadataOf(String version) {
 | 
			
		||||
		String url = String.format(
 | 
			
		||||
				"https://git.724.rocks/Minecon724/realweather-metadata/raw/branch/master/data/%s/%s/%s",
 | 
			
		||||
				channel, version, "meta-v1.json");
 | 
			
		||||
		
 | 
			
		||||
		HttpRequest request = HttpRequest.newBuilder()
 | 
			
		||||
				.uri(URI.create(url))
 | 
			
		||||
				.header("User-Agent", "rwu/1") // real weather updater v1
 | 
			
		||||
				.build();
 | 
			
		||||
		
 | 
			
		||||
		CompletableFuture<HttpResponse<String>> responseFuture =
 | 
			
		||||
				HttpClient.newBuilder()
 | 
			
		||||
				.followRedirects(Redirect.NORMAL)
 | 
			
		||||
				.proxy(ProxySelector.getDefault()).build().
 | 
			
		||||
				sendAsync(request, BodyHandlers.ofString());
 | 
			
		||||
		
 | 
			
		||||
		CompletableFuture<VersionMetadata> metadataFuture =
 | 
			
		||||
				responseFuture.thenApply(response -> {
 | 
			
		||||
					if (response.statusCode() != 200)
 | 
			
		||||
						throw new CompletionException(new MetadataServerException(response.statusCode()));
 | 
			
		||||
					
 | 
			
		||||
					VersionMetadata versionMetadata = new Gson().fromJson(response.body(), VersionMetadata.class);
 | 
			
		||||
					return versionMetadata;
 | 
			
		||||
				});
 | 
			
		||||
		
 | 
			
		||||
		return metadataFuture;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public CompletableFuture<List<String>> getChannels() {
 | 
			
		||||
		String url = "https://git.724.rocks/Minecon724/realweather-metadata/raw/branch/master/data/channels.txt";
 | 
			
		||||
		
 | 
			
		||||
		HttpRequest request = HttpRequest.newBuilder()
 | 
			
		||||
				.uri(URI.create(url))
 | 
			
		||||
				.header("User-Agent", "rwu/1") // real weather updater v1
 | 
			
		||||
				.build();
 | 
			
		||||
		
 | 
			
		||||
		CompletableFuture<HttpResponse<String>> responseFuture =
 | 
			
		||||
				HttpClient.newBuilder()
 | 
			
		||||
				.followRedirects(Redirect.NORMAL)
 | 
			
		||||
				.proxy(ProxySelector.getDefault()).build().
 | 
			
		||||
				sendAsync(request, BodyHandlers.ofString());
 | 
			
		||||
		
 | 
			
		||||
		CompletableFuture<List<String>> channelsFuture =
 | 
			
		||||
				responseFuture.thenApply(response -> {
 | 
			
		||||
					if (response.statusCode() != 200)
 | 
			
		||||
						throw new CompletionException(new MetadataServerException(response.statusCode()));
 | 
			
		||||
					
 | 
			
		||||
					return response.body().lines().toList();
 | 
			
		||||
				});
 | 
			
		||||
		
 | 
			
		||||
		return channelsFuture; // TODO remove repeated code?
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * the {@link CompletableFuture} can throw a {@link CompletionException} with {@link MetadataServerException}
 | 
			
		||||
	 */
 | 
			
		||||
	public CompletableFuture<VersionMetadata> getLatestVersionMetadata() {
 | 
			
		||||
		return getVersionMetadata("latest");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * the completablefuture can throw a completionexception with {@link MetadataServerException}
 | 
			
		||||
	 */
 | 
			
		||||
	public CompletableFuture<VersionMetadata> getCurrentVersionMetadata() {
 | 
			
		||||
		if (currentMetadataCached == null)
 | 
			
		||||
			currentMetadataCached = getVersionMetadata(version);
 | 
			
		||||
		return currentMetadataCached; // TODO reconsider this
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * the completablefuture can throw a completionexception with {@link MetadataServerException}
 | 
			
		||||
	 */
 | 
			
		||||
	public CompletableFuture<VersionMetadata> getVersionMetadata(String version) {
 | 
			
		||||
		return getMetadataOf(version); // TODO remove this and rename that function?
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,16 @@
 | 
			
		|||
package eu.m724.realweather.updater.metadata;
 | 
			
		||||
 | 
			
		||||
public class MetadataServerException extends Exception {
 | 
			
		||||
	private int statusCode;
 | 
			
		||||
 | 
			
		||||
	private static final long serialVersionUID = -782470406494196579L;
 | 
			
		||||
	
 | 
			
		||||
	public MetadataServerException(int statusCode) {
 | 
			
		||||
		this.statusCode = statusCode;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public int getStatusCode() {
 | 
			
		||||
		return statusCode;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,4 +1,7 @@
 | 
			
		|||
package eu.m724.realweather.updater;
 | 
			
		||||
package eu.m724.realweather.updater.metadata;
 | 
			
		||||
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.Date;
 | 
			
		||||
 | 
			
		||||
public class VersionMetadata {
 | 
			
		||||
	/**
 | 
			
		||||
| 
						 | 
				
			
			@ -26,4 +29,10 @@ public class VersionMetadata {
 | 
			
		|||
	 * filename of the jar file in the version directory
 | 
			
		||||
	 */
 | 
			
		||||
	public String file;
 | 
			
		||||
	
 | 
			
		||||
	public String sha256;
 | 
			
		||||
	
 | 
			
		||||
	public String getFormattedDate() {
 | 
			
		||||
		return new SimpleDateFormat("dd.MM").format(new Date(timestamp));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -6,9 +6,14 @@
 | 
			
		|||
enabled: true
 | 
			
		||||
 | 
			
		||||
updater:
 | 
			
		||||
  # notify players about plugin updates
 | 
			
		||||
  # revelant permission node: realweather.update.notify
 | 
			
		||||
  # Notify players and console about plugin updates
 | 
			
		||||
  # This also controls automatic checking
 | 
			
		||||
  # You can still update with /rwadmin update
 | 
			
		||||
  # Revelant permission node: realweather.update.notify
 | 
			
		||||
  notify: true
 | 
			
		||||
  # stable for stable releases
 | 
			
		||||
  # testing for latest builds (untested hence the name)
 | 
			
		||||
  channel: testing
 | 
			
		||||
  
 | 
			
		||||
# 0 - no debug
 | 
			
		||||
# 1 - debug loading modules
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,12 +16,15 @@ commands:
 | 
			
		|||
    description: RealWeather admin command
 | 
			
		||||
    permission: realweather.admin
 | 
			
		||||
    permission-message: You do not have permission to use this command.
 | 
			
		||||
    # usage is processed in code
 | 
			
		||||
  rwadmin update:
 | 
			
		||||
    description: Update RealWeather
 | 
			
		||||
    permission: realweather.admin.update
 | 
			
		||||
    permission-message: You do not have permission to use this command.
 | 
			
		||||
    
 | 
			
		||||
  geo:
 | 
			
		||||
    description: Convert lat,lon to x,y,z and vice versa
 | 
			
		||||
    permission: realweather.command.geo
 | 
			
		||||
    permission-message: You do not have permission to use this command.
 | 
			
		||||
    # usage is processed in code
 | 
			
		||||
  localtime:
 | 
			
		||||
    description: Get real time in current location
 | 
			
		||||
    permission: realweather.command.localtime
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +35,8 @@ permissions:
 | 
			
		|||
  
 | 
			
		||||
  realweather.admin:
 | 
			
		||||
    description: Allows admin management with /rwadmin
 | 
			
		||||
  realweather.admin.update:
 | 
			
		||||
    description: Allows installing updates with /rwadmin update
 | 
			
		||||
    
 | 
			
		||||
  realweather.command.geo:
 | 
			
		||||
    description: Allows /geo
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue