add Configurator and EventHandler classes (and some more debug output)

This commit is contained in:
Jack Fitch
2023-04-24 20:02:23 -04:00
parent fb63f55ad3
commit 15c7532cad
4 changed files with 281 additions and 103 deletions

View File

@@ -0,0 +1,201 @@
package io.github.jack1424.realtimeweather;
import org.bukkit.configuration.file.FileConfiguration;
import org.json.simple.parser.ParseException;
import javax.naming.ConfigurationException;
import java.io.IOException;
import java.time.ZoneId;
import java.time.zone.ZoneRulesException;
import java.util.Objects;
import java.util.TimeZone;
public class Configurator {
private final RealTimeWeather rtw;
private final FileConfiguration configFile;
private TimeZone timeZone;
private boolean debug, timeEnabled, weatherEnabled, blockTimeSetCommand, blockWeatherCommand;
private long timeSyncInterval, weatherSyncInterval;
private String apiKey, lat, lon;
public Configurator(RealTimeWeather rtw) {
this.rtw = rtw;
configFile = rtw.getConfig();
refreshValues();
}
public void refreshValues() {
setDebugEnabled(configFile.getBoolean("Debug"));
setTimeEnabled(configFile.getBoolean("SyncTime"));
if (isTimeEnabled())
try {
setBlockTimeSetCommand(configFile.getBoolean("BlockTimeSetCommand"));
setTimeSyncInterval(configFile.getLong("TimeSyncInterval"));
setTimeZone(configFile.getString("Timezone"));
} catch (ConfigurationException e) {
rtw.getLogger().severe((e.getMessage()));
rtw.getLogger().severe("Error loading time configuration. Check that the values in your configuration file are valid.");
rtw.getLogger().severe("Disabling time sync...");
setTimeEnabled(false);
}
setWeatherEnabled(configFile.getBoolean("SyncWeather"));
if (isWeatherEnabled())
try {
setBlockWeatherCommand(configFile.getBoolean("BlockWeatherCommand"));
setWeatherSyncInterval(configFile.getLong("WeatherSyncInterval"));
setAPIKey(configFile.getString("APIKey"));
setLat(configFile.getString("Latitude"));
setLon(configFile.getString("Longitude"));
} catch (ConfigurationException e) {
rtw.getLogger().severe(e.getMessage());
rtw.getLogger().severe("Error loading weather configuration. Check that the values in your configuration file are valid.");
rtw.getLogger().severe("Disabling weather sync...");
setWeatherEnabled(false);
}
}
public boolean debugEnabled() {
return debug;
}
public void setDebugEnabled(boolean value) {
debug = value;
rtw.getLogger().warning("Debug set to " + value);
}
public boolean isTimeEnabled() {
return timeEnabled;
}
public void setTimeEnabled(boolean value) {
timeEnabled = value;
rtw.debug("SyncTime set to " + value);
}
public boolean getBlockTimeSetCommand() {
return blockTimeSetCommand;
}
public void setBlockTimeSetCommand(boolean value) {
blockTimeSetCommand = value;
rtw.debug("BlockTimeSetCommand set to " + value);
}
public long getTimeSyncInterval() {
return timeSyncInterval;
}
public void setTimeSyncInterval(long value) throws ConfigurationException {
if (value < 0)
throw new ConfigurationException("Time sync interval cannot be less than 0");
timeSyncInterval = value;
rtw.debug("TimeSyncInterval set to " + value);
}
public TimeZone getTimeZone() {
return timeZone;
}
public void setTimeZone(String value) throws ConfigurationException {
try {
timeZone = TimeZone.getTimeZone(ZoneId.of(Objects.requireNonNull(value)));
} catch (ZoneRulesException | NullPointerException e) {
throw new ConfigurationException("Timezone not valid");
}
rtw.debug("TimeZone set to " + value);
}
public boolean isWeatherEnabled() {
return weatherEnabled;
}
public void setWeatherEnabled(boolean value) {
weatherEnabled = value;
rtw.debug("SyncWeather set to " + value);
}
public boolean getBlockWeatherCommand() {
return blockWeatherCommand;
}
public void setBlockWeatherCommand(boolean value) {
blockWeatherCommand = value;
rtw.debug("BlockWeatherCommand set to " + value);
}
public long getWeatherSyncInterval() {
return weatherSyncInterval;
}
public void setWeatherSyncInterval(long value) throws ConfigurationException {
if (value < 0)
throw new ConfigurationException("WeatherSyncInterval cannot be less than 0");
weatherSyncInterval = value;
rtw.debug("WeatherSyncInterval set to " + value);
}
public String getAPIKey() {
return apiKey;
}
public void setAPIKey(String value) throws ConfigurationException {
try {
new RequestObject(Objects.requireNonNull(value), "0", "0");
} catch (NullPointerException e) {
throw new ConfigurationException("The APIKey cannot be blank");
}
catch (IOException | ParseException e) {
e.printStackTrace();
throw new ConfigurationException("There was an error when validating this APIKey (this does not mean that the API key is invalid)");
}
apiKey = value;
rtw.debug("APIKey set to " + value);
}
public String getLat() {
return lat;
}
public void setLat(String value) throws ConfigurationException {
try {
double doubleValue = Double.parseDouble(Objects.requireNonNull(value));
if (doubleValue < -90 || doubleValue > 90)
throw new ConfigurationException("The entered latitude cannot be less than -90 or greater than 90");
} catch (NullPointerException e) {
throw new ConfigurationException("The latitude cannot be blank");
} catch (NumberFormatException e) {
throw new ConfigurationException("The entered latitude might not be a number (or is too long)");
}
lat = value;
rtw.debug("Latitude set to " + value);
}
public String getLon() {
return lon;
}
public void setLon(String value) throws ConfigurationException {
try {
double doubleValue = Double.parseDouble(Objects.requireNonNull(value));
if (doubleValue < -180 || doubleValue > 180)
throw new ConfigurationException("The entered longitude cannot be less than -180 or greater than 180");
} catch (NullPointerException e) {
throw new ConfigurationException("The longitude cannot be blank");
} catch (NumberFormatException e) {
throw new ConfigurationException("The entered longitude might not be a number (or is too long)");
}
lon = value;
rtw.debug("Longitude set to " + value);
}
}

View File

@@ -0,0 +1,32 @@
package io.github.jack1424.realtimeweather;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.server.ServerCommandEvent;
public class EventHandler implements Listener {
private final Configurator config;
public EventHandler(RealTimeWeather rtw) {
config = rtw.getConfigurator();
}
@org.bukkit.event.EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onOperatorSet(PlayerCommandPreprocessEvent event) {
if ((config.getBlockTimeSetCommand() && config.isTimeEnabled() && event.getMessage().contains("time set"))
|| (config.getBlockWeatherCommand() && config.isWeatherEnabled() && event.getMessage().contains("weather"))) {
event.setCancelled(true);
event.getPlayer().sendMessage("Command cancelled (RealTimeWeather is controlling this)");
}
}
@org.bukkit.event.EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onOperatorSetConsole(ServerCommandEvent event) {
if ((config.getBlockTimeSetCommand() && config.isTimeEnabled() && event.getCommand().contains("time set"))
|| (config.getBlockWeatherCommand() && config.isWeatherEnabled() && event.getCommand().contains("weather"))) {
event.setCancelled(true);
event.getSender().sendMessage("Command cancelled (RealTimeWeather is controlling this)");
}
}
}

View File

@@ -3,49 +3,39 @@ package io.github.jack1424.realtimeweather;
import org.bstats.bukkit.Metrics; import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie; import org.bstats.charts.SimplePie;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.server.ServerCommandEvent;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.time.ZoneId;
import java.time.zone.ZoneRulesException;
import java.util.Calendar; import java.util.Calendar;
import java.util.Objects;
import java.util.TimeZone;
import java.util.logging.Logger; import java.util.logging.Logger;
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public final class RealTimeWeather extends JavaPlugin implements Listener { public final class RealTimeWeather extends JavaPlugin {
private Logger logger; private Logger logger;
private ZoneId timezone; private Configurator config;
private boolean timeEnabled, weatherEnabled, debug, blockTimeSetCommand, blockWeatherCommand;
@Override @Override
public void onEnable() { public void onEnable() {
logger = getLogger(); logger = getLogger();
logger.info("Starting..."); logger.info("Starting...");
logger.info("Loading configuration...");
saveDefaultConfig(); saveDefaultConfig();
config = new Configurator(this);
debug = getConfig().getBoolean("Debug"); debug("TimeSync: " + config.isTimeEnabled());
if (config.isTimeEnabled())
timeEnabled = getConfig().getBoolean("SyncTime");
if (timeEnabled)
setupTime(); setupTime();
weatherEnabled = getConfig().getBoolean("SyncWeather"); debug("WeatherSync: " + config.isWeatherEnabled());
if (weatherEnabled) if (config.isWeatherEnabled())
setupWeather(); setupWeather();
getServer().getPluginManager().registerEvents(this, this); getServer().getPluginManager().registerEvents(new EventHandler(this), this);
debug("Enabling metrics..."); debug("Enabling metrics...");
Metrics metrics = new Metrics(this, 16709); Metrics metrics = new Metrics(this, 16709);
metrics.addCustomChart(new SimplePie("weather_sync_enabled", () -> String.valueOf(weatherEnabled))); metrics.addCustomChart(new SimplePie("weather_sync_enabled", () -> String.valueOf(config.isWeatherEnabled())));
metrics.addCustomChart(new SimplePie("time_sync_enabled", () -> String.valueOf(timeEnabled))); metrics.addCustomChart(new SimplePie("time_sync_enabled", () -> String.valueOf(config.isTimeEnabled())));
logger.info("Started!"); logger.info("Started!");
} }
@@ -56,100 +46,41 @@ public final class RealTimeWeather extends JavaPlugin implements Listener {
if (world.getEnvironment().equals(World.Environment.NORMAL)) { if (world.getEnvironment().equals(World.Environment.NORMAL)) {
debug("Re-enabling normal daylight and weather cycles..."); debug("Re-enabling normal daylight and weather cycles...");
if (timeEnabled) if (config.isTimeEnabled())
world.setGameRuleValue("doDaylightCycle", "true"); world.setGameRuleValue("doDaylightCycle", "true");
if (weatherEnabled) if (config.isWeatherEnabled())
world.setGameRuleValue("doWeatherCycle", "true"); world.setGameRuleValue("doWeatherCycle", "true");
} }
logger.info("Stopping..."); logger.info("Stopping...");
} }
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onOperatorSet(PlayerCommandPreprocessEvent event) {
if ((blockTimeSetCommand && timeEnabled && event.getMessage().contains("time set")) || (blockWeatherCommand && weatherEnabled && event.getMessage().contains("weather"))) {
event.setCancelled(true);
event.getPlayer().sendMessage("Command cancelled (RealTimeWeather is controlling this)");
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onOperatorSetConsole(ServerCommandEvent event) {
if ((blockTimeSetCommand && timeEnabled && event.getCommand().contains("time set")) || (blockWeatherCommand && weatherEnabled && event.getCommand().contains("weather"))) {
event.setCancelled(true);
event.getSender().sendMessage("Command cancelled (RealTimeWeather is controlling this)");
}
}
private void setupTime() { private void setupTime() {
long timeSyncInterval;
try {
timezone = ZoneId.of(Objects.requireNonNull(getConfig().getString("Timezone")));
timeSyncInterval = getConfig().getLong("TimeSyncInterval");
blockTimeSetCommand = getConfig().getBoolean("BlockTimeSetCommand");
} catch (NullPointerException|ZoneRulesException e) {
logger.severe("Error loading timezone. Check that the values in your configuration file are valid.");
debug(e.getMessage());
logger.severe("Disabling time sync...");
timeEnabled = false;
return;
}
debug("Enabling time zone sync..."); debug("Enabling time zone sync...");
debug("Syncing time with " + timezone.toString()); debug("Syncing time with " + config.getTimeZone().getDisplayName());
for (World world : getServer().getWorlds()) for (World world : getServer().getWorlds())
if (world.getEnvironment().equals(World.Environment.NORMAL)) if (world.getEnvironment().equals(World.Environment.NORMAL))
world.setGameRuleValue("doDaylightCycle", "false"); world.setGameRuleValue("doDaylightCycle", "false");
getServer().getScheduler().scheduleSyncRepeatingTask(this, () -> { getServer().getScheduler().scheduleSyncRepeatingTask(this, () -> {
if (timeEnabled) { if (config.isTimeEnabled()) {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(timezone)); Calendar cal = Calendar.getInstance(config.getTimeZone());
for (World world : getServer().getWorlds()) for (World world : getServer().getWorlds())
if (world.getEnvironment().equals(World.Environment.NORMAL)) if (world.getEnvironment().equals(World.Environment.NORMAL))
world.setTime((1000 * cal.get(Calendar.HOUR_OF_DAY)) + (16 * (cal.get(Calendar.MINUTE) + 1)) - 6000); world.setTime((1000 * cal.get(Calendar.HOUR_OF_DAY)) + (16 * (cal.get(Calendar.MINUTE) + 1)) - 6000);
} }
}, 0L, timeSyncInterval); }, 0L, config.getTimeSyncInterval());
} }
private void setupWeather() { private void setupWeather() {
long weatherSyncInterval;
String apiKey = getConfig().getString("APIKey");
String lat = getConfig().getString("Latitude"), lon = getConfig().getString("Longitude");
try { try {
weatherSyncInterval = getConfig().getLong("WeatherSyncInterval"); new RequestObject(config.getAPIKey(), config.getLat(), config.getLon());
blockWeatherCommand = getConfig().getBoolean("blockWeatherCommand");
RequestObject request = new RequestObject(apiKey, lat, lon);
int response = request.getResponseCode();
if (response > 499) {
logger.severe("There was a server error when requesting weather information. Please try again later");
throw new Exception("Server/client error");
}
else if (response > 399) {
String message = "Error when getting weather information: ";
if (response == 401)
logger.severe(message + "API key incorrect");
else if (response == 404)
logger.severe(message + "Zip/Country code incorrect");
else
logger.severe("Unknown error");
logger.severe("Please check that the values set in the config file are correct");
throw new Exception("Configuration error");
}
} catch (Exception e) { } catch (Exception e) {
debug(e.getMessage()); logger.severe(e.getMessage());
logger.severe("Disabling weather sync..."); logger.severe("Disabling weather sync...");
weatherEnabled = false; config.setWeatherEnabled(false);
return; return;
} }
@@ -157,11 +88,13 @@ public final class RealTimeWeather extends JavaPlugin implements Listener {
if (world.getEnvironment().equals(World.Environment.NORMAL)) if (world.getEnvironment().equals(World.Environment.NORMAL))
world.setGameRuleValue("doWeatherCycle", "false"); world.setGameRuleValue("doWeatherCycle", "false");
debug("Enabling weather sync...");
getServer().getScheduler().scheduleSyncRepeatingTask(this, () -> { getServer().getScheduler().scheduleSyncRepeatingTask(this, () -> {
debug("Syncing weather..."); debug("Syncing weather...");
try { try {
RequestObject request = new RequestObject(apiKey, lat, lon); RequestObject request = new RequestObject(config.getAPIKey(), config.getLat(), config.getLon());
debug("Setting weather (Rain: " + request.isRaining() + ", Thunder: " + request.isThundering() + ")..."); debug("Setting weather (Rain: " + request.isRaining() + ", Thunder: " + request.isThundering() + ")...");
for (World world : getServer().getWorlds()) for (World world : getServer().getWorlds())
@@ -173,11 +106,17 @@ public final class RealTimeWeather extends JavaPlugin implements Listener {
logger.severe("There was an error when attempting to get weather information"); logger.severe("There was an error when attempting to get weather information");
debug(e.getMessage()); debug(e.getMessage());
} }
}, 0L, weatherSyncInterval); }, 0L, config.getWeatherSyncInterval());
debug("Weather sync enabled");
} }
private void debug(String message) { public Configurator getConfigurator() {
if (debug) { return config;
}
public void debug(String message) {
if (config.debugEnabled()) {
logger.info("[DEBUG] " + message); logger.info("[DEBUG] " + message);
} }
} }

View File

@@ -5,24 +5,34 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser; import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException; import org.json.simple.parser.ParseException;
import javax.naming.ConfigurationException;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import java.io.IOException; import java.io.IOException;
import java.net.ProtocolException;
import java.net.URL; import java.net.URL;
import java.util.Scanner; import java.util.Scanner;
public class RequestObject { public class RequestObject {
private final int responseCode;
private boolean rain = false, thunder = false; private boolean rain = false, thunder = false;
public RequestObject(String apiKey, String lat, String lon) throws IOException, ParseException { public RequestObject(String apiKey, String lat, String lon) throws IOException, ParseException, ConfigurationException {
URL url = new URL(String.format("https://api.openweathermap.org/data/2.5/weather?lat=%s&lon=%s&appid=%s", lat, lon, apiKey)); URL url = new URL(String.format("https://api.openweathermap.org/data/2.5/weather?lat=%s&lon=%s&appid=%s", lat, lon, apiKey));
HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setRequestMethod("GET"); con.setRequestMethod("GET");
con.connect(); con.connect();
responseCode = con.getResponseCode(); int responseCode = con.getResponseCode();
if (responseCode > 399) if (responseCode > 499) {
return; throw new ProtocolException("Server/client error (HTTP error " + responseCode + ")");
}
else if (responseCode > 399) {
String message = "Error when getting weather information: ";
if (responseCode == 401)
throw new ConfigurationException(message + "API key invalid. Check the Wiki for troubleshooting steps.");
else
throw new ProtocolException(message + "Unknown error");
}
Scanner scanner = new Scanner(url.openStream()); Scanner scanner = new Scanner(url.openStream());
StringBuilder data = new StringBuilder(); StringBuilder data = new StringBuilder();
@@ -46,10 +56,6 @@ public class RequestObject {
} }
} }
public int getResponseCode() {
return responseCode;
}
public boolean isRaining() { public boolean isRaining() {
return rain; return rain;
} }