43 Commits

Author SHA1 Message Date
Jack
a7b1f7c6e8 slight update to the README 2024-06-27 18:35:34 -04:00
Jack
e1154c59ca version set to v1.3.0 2024-06-27 18:29:54 -04:00
Jack
616b754afe change config version scheme (and update it to v1.3.0) 2024-06-27 18:27:34 -04:00
Jack
8d15534257 re-write some comments in config.yml 2024-06-27 18:27:11 -04:00
Jack
05dcde1b91 added bStats chart for SunriseSunset config value 2024-06-27 18:19:29 -04:00
Jack
1ec4d708f0 renamed EventHandler to EventHandlers 2024-06-27 18:17:11 -04:00
Jack
b616a71674 renamed Configurator to ConfigManager 2024-06-27 18:16:33 -04:00
Jack
4c4f861645 add support for real-world and custom sunrise/sunset times (closes #2) 2024-06-27 18:13:37 -04:00
Jack
c605b60903 renamed EventHandler command methods 2024-06-26 22:36:56 -04:00
Jack
4543087258 updated setAPIKey exception logging to a more "robust" method 2024-06-26 22:35:12 -04:00
Jack
cdb6d057e4 update bStats to 3.0.2 2024-06-24 21:39:16 -04:00
Jack
b816761511 update Gradle to 8.8 2024-06-24 21:32:32 -04:00
Jack
6eab85374d remove unnecessary spaces in the authors array 2024-06-23 18:23:33 -04:00
Jack
85a792228c explicitly set to load POSTWORLD 2024-06-23 18:22:33 -04:00
Jack
e623611301 add options to disable beds during night/thunder 2024-06-23 17:58:02 -04:00
Jack
b5a212d4ef change EventHandler priorities to LOWEST 2024-06-23 17:21:37 -04:00
Jack
79d1fc7b88 change message when commands are cancelled 2024-06-23 17:21:02 -04:00
Jack
b751b4ad3e fix "this.config is null" crash 2024-06-23 17:17:34 -04:00
Jack
1f303459cb grammar is hard 2023-11-02 08:57:19 -04:00
Jack Fitch
ef8ae1f6f4 add link to Wiki in config.yml 2023-04-24 20:04:59 -04:00
Jack Fitch
0f152ec892 Merge remote-tracking branch 'origin/master' 2023-04-24 20:02:40 -04:00
Jack Fitch
15c7532cad add Configurator and EventHandler classes (and some more debug output) 2023-04-24 20:02:23 -04:00
Jack
7573f46deb add commands to upcoming features 2023-04-24 12:31:46 -04:00
Jack Fitch
fb63f55ad3 clean up import statements 2023-04-22 20:53:39 -04:00
Jack Fitch
c782ee604a add option to enable /time set and /weather commands 2023-04-22 20:53:24 -04:00
Jack Fitch
f94cb36afe add RequestObject class and option to sync weather with coordinates 2023-04-22 20:44:34 -04:00
Jack
b086fa8143 update shadow plugin to 8.1.1 2023-04-19 13:01:46 -04:00
Jack
291261761c update Gradle to 8.1 2023-04-19 12:59:09 -04:00
Jack
ffa6474ba2 add Folia support to upcoming features 2023-04-17 08:42:47 -04:00
Jack Fitch
4ca9026f25 added 4SplitImage media 2023-03-08 16:47:38 -05:00
Jack Fitch
914249cc49 finally finally finish issue templates 2023-03-08 15:51:46 -05:00
Jack Fitch
dfb89d7e40 finally finish issue templates 2023-03-08 15:46:30 -05:00
Jack
9461db7d7e remove Wiki from upcoming features 2023-03-07 20:38:13 -05:00
Jack
454394e14c add multi-world support to the upcoming features 2023-03-07 20:31:05 -05:00
Jack Fitch
5d5867ed35 change README image 2023-03-07 19:02:11 -05:00
Jack Fitch
e16375557f add media images 2023-03-07 19:00:12 -05:00
Jack
fd449bf81a add title image 2023-03-07 18:06:18 -05:00
Jack
acc7acb4af add installation instructions 2023-02-28 16:30:33 -05:00
Jack
302e485640 tiny changes 2023-02-28 13:39:59 -05:00
Jack
175e9f7e67 add config.yml 2022-10-28 22:24:33 -04:00
Jack Fitch
380927d34d update issue templates 2022-10-28 22:22:17 -04:00
Jack Fitch
9724e20b85 update issue templates 2022-10-28 22:19:50 -04:00
Jack
5c46c34542 add issue templates 2022-10-28 16:37:36 -04:00
21 changed files with 800 additions and 198 deletions

71
.github/ISSUE_TEMPLATE/BUG-REPORT.yml vendored Normal file
View File

@@ -0,0 +1,71 @@
name: Bug report
description: Report problems/issues here
labels: bug
body:
- type: checkboxes
attributes:
label: Have you searched the wiki and looked for existing issues for this?
description: Check the wiki first in case this is a common issue. If it isn't make sure that [no one else has reported it](https://github.com/Jack1424/RealTimeWeather/issues?q=is%3Aissue+label%3Abug+).
options:
- label: This is not a common issue or cannot be fixed by the solutions provided
required: true
- label: This issue has not been reported yet
required: true
- type: textarea
attributes:
label: What's happening
description: Describe the issue that you're having. Make sure to be clear and concise.
validations:
required: true
- type: textarea
attributes:
label: What's supposed to happen
description: Describe what should be happening
validations:
required: true
- type: dropdown
attributes:
label: Server Software
description: What type of server are you running RealTimeWeather on?
options:
- Bukkit
- Paper
- Spigot
- Purpur
- Other
validations:
required: true
- type: input
attributes:
label: Minecraft version
description: What version of Minecraft is your server running?
placeholder: 'Example: 1.19.3'
validations:
required: true
- type: input
attributes:
label: Server log
description: If applicable, paste the link to your server log here
placeholder: Get a link at https://pastebin.com/
validations:
required: false
- type: input
attributes:
label: RTW configuration
description: If applicable, paste the link to your configuration file here **(REMEMBER TO REMOVE YOUR API KEY)**
placeholder: Get a link at https://pastebin.com/
validations:
required: false
- type: textarea
attributes:
label: Additional information
description: Put any more information (including screenshots and videos) that you might have here
validations:
required: false

View File

@@ -0,0 +1,18 @@
name: Feature request
description: Use this to request new features and/or changes
labels: enhancement
body:
- type: checkboxes
attributes:
label: Is there already a request similar to this?
description: Check the [other feature requests](https://github.com/Jack1424/RealTimeWeather/issues?q=label%3Aenhancement+) and ensure that this hasn't been requested yet
options:
- label: There are not and have never been any feature requests similar to this
required: true
- type: textarea
attributes:
label: What's your suggestion?
description: Use the space below to describe your suggestion. Feel free to attach any relevant files/links.
validations:
required: true

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1 @@
blank_issues_enabled: false

View File

@@ -1,18 +1,26 @@
# RealTimeWeather [![Build Status](https://app.travis-ci.com/Jack1424/RealTimeWeather.svg?branch=master)](https://app.travis-ci.com/Jack1424/RealTimeWeather)
A lightweight Minecraft Java server plugin that allows you to sync your server's time and weather with the real world.
![4SplitSingleLineCloseColors](https://raw.githubusercontent.com/Jack1424/RealTimeWeather/master/media/4SplitColors.png)
[![Build Status](https://app.travis-ci.com/Jack1424/RealTimeWeather.svg?branch=master)](https://app.travis-ci.com/Jack1424/RealTimeWeather)
### A lightweight Minecraft server plugin that allows you to sync your server's time and weather with the real world
___
**Current Features:**
- Lightweight
- Easy setup
- Supports all Minecraft versions from 1.7+
- Constant time syncing
- Weather syncing (rain and thunder)
- Constant time syncing (including custom or real-world sunrise/sunset times)
- Weather syncing (rain/snow and thunder)
**Upcoming Features:**
- [ ] Use WeatherPlusAPI (more weather states)
- [X] Support for more Minecraft versions
- [ ] Wiki
- [ ] Commands
- [ ] Multi-world support
- [ ] Folia support
## Contributions
## Installation
Just download the [latest version](https://github.com/Jack1424/RealTimeWeather/releases/latest) of RTW and put it in your `plugins` directory.
You'll need to run your server at least once to generate the configuration file.
After running (and then stopping) your server, simply change the values in the configuration file to what you'd like, and you're good to go.
## Contributions/Support
I'm open to any help/ideas that you have. Just open an issue or a pull request, and I'll be sure to look at it as soon as I can. Builds with `gradlew shadowJar`.
License: GPL-3.0

View File

@@ -1,10 +1,10 @@
plugins {
id 'java'
id 'com.github.johnrengelman.shadow' version '7.1.2'
id 'com.github.johnrengelman.shadow' version '8.1.1'
}
group = 'io.github.Jack1424'
version = '1.2.0'
version = '1.3.0'
repositories {
mavenCentral()
@@ -19,7 +19,7 @@ repositories {
}
dependencies {
implementation("org.bstats:bstats-bukkit:3.0.0")
implementation("org.bstats:bstats-bukkit:3.0.2")
implementation("org.bukkit:bukkit:1.13-R0.1-SNAPSHOT")
}

Binary file not shown.

View File

@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

51
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright <EFBFBD> 2015-2021 the original authors.
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -32,10 +32,10 @@
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
# * functions;
# * expansions <EFBFBD>$var<EFBFBD>, <EFBFBD>${var}<EFBFBD>, <EFBFBD>${var:-default}<EFBFBD>, <EFBFBD>${var+SET}<EFBFBD>,
# <EFBFBD>${var#prefix}<EFBFBD>, <EFBFBD>${var%suffix}<EFBFBD>, and <EFBFBD>$( cmd )<EFBFBD>;
# * compound commands having a testable exit status, especially <EFBFBD>case<EFBFBD>;
# * various built-in commands including <EFBFBD>command<EFBFBD>, <EFBFBD>set<EFBFBD>, and <EFBFBD>ulimit<EFBFBD>.
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
# * compound commands having a testable exit status, especially «case»;
# * various built-in commands including «command», «set», and «ulimit».
#
# Important for patching:
#
@@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,13 +80,11 @@ do
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -133,22 +131,29 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -193,11 +198,15 @@ if "$cygwin" || "$msys" ; then
done
fi
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
@@ -205,6 +214,12 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \
"$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.

35
gradlew.bat vendored
View File

@@ -14,7 +14,7 @@
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,7 +25,8 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@@ -40,13 +41,13 @@ if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if %ERRORLEVEL% equ 0 goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -56,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
goto fail
@@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
if %ERRORLEVEL% equ 0 goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
:mainEnd
if "%OS%"=="Windows_NT" endlocal

BIN
media/4SplitCloseColors.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 KiB

BIN
media/4SplitColors.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 KiB

BIN
media/4SplitImage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1008 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

BIN
media/IconColors.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 KiB

View File

@@ -0,0 +1,311 @@
package io.github.jack1424.realtimeweather;
import io.github.jack1424.realtimeweather.requests.WeatherRequestObject;
import org.bukkit.configuration.file.FileConfiguration;
import org.json.simple.parser.ParseException;
import javax.naming.ConfigurationException;
import java.io.IOException;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.zone.ZoneRulesException;
import java.util.Objects;
import java.util.TimeZone;
public class ConfigManager {
private final RealTimeWeather rtw;
private final FileConfiguration configFile;
private TimeZone timeZone;
private boolean debug, timeEnabled, weatherEnabled, blockTimeSetCommand, blockWeatherCommand, disableBedsAtNight, disableBedsDuringThunder;
private long timeSyncInterval, weatherSyncInterval;
private String sunriseSunset, sunriseSunsetLatitude, sunriseSunsetLongitude, apiKey, weatherLatitude, weatherLongitude, disableBedsAtNightMessage, disableBedsDuringThunderMessage, sunriseCustomTime, sunsetCustomTime;
public ConfigManager(RealTimeWeather rtw) {
this.rtw = rtw;
configFile = rtw.getConfig();
}
public void refreshValues() {
setDebugEnabled(configFile.getBoolean("Debug"));
setTimeEnabled(configFile.getBoolean("SyncTime"));
if (isTimeEnabled())
try {
setBlockTimeSetCommand(configFile.getBoolean("BlockTimeSetCommand"));
setDisableBedsAtNight(configFile.getBoolean("DisableBedsAtNight"));
setDisableBedsAtNightMessage(configFile.getString("DisableBedsAtNightMessage"));
setTimeSyncInterval(configFile.getLong("TimeSyncInterval"));
setTimeZone(configFile.getString("Timezone"));
setSunriseSunset(configFile.getString("SunriseSunset"));
if (getSunriseSunset().equals("real")) {
setSunriseSunsetLatitude(configFile.getString("SunriseSunsetLatitude"));
setSunriseSunsetLongitude(configFile.getString("SunriseSunsetLongitude"));
} else if (getSunriseSunset().equals("custom")) {
setSunriseCustomTime(configFile.getString("SunriseCustomTime"));
setSunsetCustomTime(configFile.getString("SunsetCustomTime"));
}
} 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"));
setDisableBedsDuringThunder(configFile.getBoolean("DisableBedsDuringThunder"));
setDisableBedsDuringThunderMessage(configFile.getString("DisableBedsDuringThunderMessage"));
setWeatherSyncInterval(configFile.getLong("WeatherSyncInterval"));
setAPIKey(configFile.getString("APIKey"));
setWeatherLatitude(configFile.getString("WeatherLatitude"));
setWeatherLongitude(configFile.getString("WeatherLongitude"));
} 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 boolean getDisableBedsAtNight() {
return disableBedsAtNight;
}
public void setDisableBedsAtNight(boolean value) {
disableBedsAtNight = value;
rtw.debug("DisableBedsAtNight set to " + value);
}
public String getDisableBedsAtNightMessage() {
return disableBedsAtNightMessage;
}
public void setDisableBedsAtNightMessage(String value) {
disableBedsAtNightMessage = value;
rtw.debug("NightDisabledBedMessage 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 String getSunriseSunset() {
return sunriseSunset;
}
public void setSunriseSunset(String value) throws ConfigurationException {
value = value.toLowerCase();
if (value.equals("default") || value.equals("real") || value.equals("custom")) {
sunriseSunset = value;
rtw.debug("SunriseSunset set to " + value);
} else {
throw new ConfigurationException("SunriseSunset value invalid (must be default or real or custom)");
}
}
public String getSunriseSunsetLatitude() {
return sunriseSunsetLatitude;
}
public void setSunriseSunsetLatitude(String value) {
sunriseSunsetLatitude = value;
rtw.debug("SunriseSunsetLatitude set to " + value);
}
public String getSunriseSunsetLongitude() {
return sunriseSunsetLongitude;
}
public void setSunriseSunsetLongitude(String value) {
sunriseSunsetLongitude = value;
rtw.debug("SunriseSunsetLongitude set to " + value);
}
public String getSunriseCustomTime() {
return sunriseCustomTime;
}
public void setSunriseCustomTime(String value) throws ConfigurationException {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mm:ss a");
sunriseCustomTime = LocalTime.parse(value, formatter).format(formatter);
rtw.debug("SunriseCustomTime set to " + value);
} catch (DateTimeParseException e) {
throw new ConfigurationException("SunriseCustomTime value invalid (check format)");
}
}
public String getSunsetCustomTime() {
return sunsetCustomTime;
}
public void setSunsetCustomTime(String value) throws ConfigurationException {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("h:mm:ss a");
sunsetCustomTime = LocalTime.parse(value, formatter).format(formatter);
rtw.debug("SunsetCustomTime set to " + value);
} catch (DateTimeParseException e) {
throw new ConfigurationException("SunsetCustomTime value invalid (check format)");
}
}
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 boolean getDisableBedsDuringThunder() {
return disableBedsDuringThunder;
}
public void setDisableBedsDuringThunder(boolean value) {
disableBedsDuringThunder = value;
rtw.debug("DisableBedsDuringThunder set to " + value);
}
public String getDisableBedsDuringThunderMessage() {
return disableBedsDuringThunderMessage;
}
public void setDisableBedsDuringThunderMessage(String value) {
disableBedsDuringThunderMessage = value;
rtw.debug("ThunderDisabledBedMessage 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 WeatherRequestObject(Objects.requireNonNull(value), "0", "0");
} catch (NullPointerException e) {
throw new ConfigurationException("The APIKey cannot be blank");
}
catch (IOException | ParseException e) {
rtw.getLogger().severe(e.getMessage());
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 getWeatherLatitude() {
return weatherLatitude;
}
public void setWeatherLatitude(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)");
}
weatherLatitude = value;
rtw.debug("Latitude set to " + value);
}
public String getWeatherLongitude() {
return weatherLongitude;
}
public void setWeatherLongitude(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)");
}
weatherLongitude = value;
rtw.debug("Longitude set to " + value);
}
}

View File

@@ -0,0 +1,54 @@
package io.github.jack1424.realtimeweather;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.server.ServerCommandEvent;
public class EventHandlers implements Listener {
private final ConfigManager config;
public EventHandlers(RealTimeWeather rtw) {
config = rtw.getConfigurator();
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onCommandPreprocess(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 disabled by RealTimeWeather");
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onConsoleCommand(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 disabled by RealTimeWeather");
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerBedEnter(PlayerBedEnterEvent event) {
Player player = event.getPlayer();
World playerWorld = player.getWorld();
long worldTime = playerWorld.getTime();
if (config.isTimeEnabled() && config.getDisableBedsAtNight() && ((!playerWorld.hasStorm() && worldTime >= 12542 && worldTime <= 23459)
|| (playerWorld.hasStorm() && worldTime >= 12010 && worldTime <= 23991))) {
event.setCancelled(true);
player.sendMessage(config.getDisableBedsAtNightMessage());
}
if (config.isWeatherEnabled() && config.getDisableBedsDuringThunder() && playerWorld.isThundering()) {
event.setCancelled(true);
player.sendMessage(config.getDisableBedsDuringThunderMessage());
}
}
}

View File

@@ -1,56 +1,46 @@
package io.github.jack1424.realtimeweather;
import io.github.jack1424.realtimeweather.requests.*;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
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.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.net.URL;
import java.time.ZoneId;
import java.time.zone.ZoneRulesException;
import java.util.*;
import javax.naming.ConfigurationException;
import java.time.LocalTime;
import java.util.Calendar;
import java.util.logging.Logger;
@SuppressWarnings("deprecation")
public final class RealTimeWeather extends JavaPlugin implements Listener {
public final class RealTimeWeather extends JavaPlugin {
private Logger logger;
private ZoneId timezone;
private boolean timeEnabled, weatherEnabled, debug;
private ConfigManager config;
@Override
public void onEnable() {
logger = getLogger();
logger.info("Starting...");
logger.info("Loading configuration...");
saveDefaultConfig();
config = new ConfigManager(this);
config.refreshValues();
debug = getConfig().getBoolean("Debug");
timeEnabled = getConfig().getBoolean("SyncTime");
if (timeEnabled)
debug("TimeSync: " + config.isTimeEnabled());
if (config.isTimeEnabled())
setupTime();
weatherEnabled = getConfig().getBoolean("SyncWeather");
if (weatherEnabled)
debug("WeatherSync: " + config.isWeatherEnabled());
if (config.isWeatherEnabled())
setupWeather();
getServer().getPluginManager().registerEvents(this, this);
getServer().getPluginManager().registerEvents(new EventHandlers(this), this);
debug("Enabling metrics...");
Metrics metrics = new Metrics(this, 16709);
metrics.addCustomChart(new SimplePie("weather_sync_enabled", () -> String.valueOf(weatherEnabled)));
metrics.addCustomChart(new SimplePie("time_sync_enabled", () -> String.valueOf(timeEnabled)));
metrics.addCustomChart(new SimplePie("weather_sync_enabled", () -> String.valueOf(config.isWeatherEnabled())));
metrics.addCustomChart(new SimplePie("sunrise_sunset_source", () -> String.valueOf(config.getSunriseSunset())));
metrics.addCustomChart(new SimplePie("time_sync_enabled", () -> String.valueOf(config.isTimeEnabled())));
logger.info("Started!");
}
@@ -61,163 +51,129 @@ public final class RealTimeWeather extends JavaPlugin implements Listener {
if (world.getEnvironment().equals(World.Environment.NORMAL)) {
debug("Re-enabling normal daylight and weather cycles...");
if (timeEnabled)
if (config.isTimeEnabled())
world.setGameRuleValue("doDaylightCycle", "true");
if (weatherEnabled)
if (config.isWeatherEnabled())
world.setGameRuleValue("doWeatherCycle", "true");
}
logger.info("Stopping...");
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onOperatorSet(PlayerCommandPreprocessEvent event) {
if ((timeEnabled && event.getMessage().contains("time set")) || (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 ((timeEnabled && event.getCommand().contains("time set")) || (weatherEnabled && event.getCommand().contains("weather"))) {
event.setCancelled(true);
event.getSender().sendMessage("Command cancelled (RealTimeWeather is controlling this)");
}
}
private void setupTime() {
long timeSyncInterval;
try {
timezone = ZoneId.of(Objects.requireNonNull(getConfig().getString("Timezone")));
timeSyncInterval = getConfig().getLong("TimeSyncInterval");
} 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("Syncing time with " + timezone.toString());
debug("Syncing time with " + config.getTimeZone().getDisplayName());
if (config.getSunriseSunset().equals("real"))
debug("Syncing sunrise/sunset with " + config.getSunriseSunsetLatitude() + " " + config.getSunriseSunsetLongitude());
if (config.getSunriseSunset().equals("custom"))
debug("Using custom sunrise/sunset times. Sunrise: " + config.getSunriseCustomTime() + ", Sunset: " + config.getSunsetCustomTime());
for (World world : getServer().getWorlds())
if (world.getEnvironment().equals(World.Environment.NORMAL))
world.setGameRuleValue("doDaylightCycle", "false");
getServer().getScheduler().scheduleSyncRepeatingTask(this, () -> {
if (timeEnabled) {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone(timezone));
if (config.isTimeEnabled()) {
Calendar cal = Calendar.getInstance(config.getTimeZone());
for (World world : getServer().getWorlds())
if (world.getEnvironment().equals(World.Environment.NORMAL))
world.setTime((1000 * cal.get(Calendar.HOUR_OF_DAY)) + (16 * (cal.get(Calendar.MINUTE) + 1)) - 6000);
if (config.getSunriseSunset().equals("real")) {
SunriseSunsetRequestObject sunriseSunset;
try {
sunriseSunset = new SunriseSunsetRequestObject(config.getTimeZone(), config.getWeatherLatitude(), config.getWeatherLongitude());
world.setTime(calculateWorldTime(cal, sunriseSunset.getSunriseTime(), sunriseSunset.getSunsetTime()));
} catch (Exception e) {
logger.severe(e.getMessage());
logger.severe("Error getting sunrise/sunset times, using default sunrise/sunset times");
try {
config.setSunriseSunset("default");
} catch (ConfigurationException ex) {
throw new RuntimeException(ex);
}
world.setTime(calculateWorldTime(cal, "5:02:27 AM", "6:36:36 PM"));
return;
}
} else if (config.getSunriseSunset().equals("custom"))
world.setTime(calculateWorldTime(cal, config.getSunriseCustomTime(), config.getSunsetCustomTime()));
else
world.setTime(calculateWorldTime(cal, "5:02:27 AM", "6:36:36 PM"));
}
}, 0L, timeSyncInterval);
}, 0L, config.getTimeSyncInterval());
}
private void setupWeather() {
long weatherSyncInterval;
String apiKey = getConfig().getString("APIKey");
String zipCode = getConfig().getString("ZipCode");
String countryCode = getConfig().getString("CountryCode");
String lat, lon;
try {
weatherSyncInterval = getConfig().getLong("WeatherSyncInterval");
HttpsURLConnection con = (HttpsURLConnection) new URL(String.format("https://api.openweathermap.org/geo/1.0/zip?zip=%s,%s&appid=%s", zipCode, countryCode, apiKey)).openConnection();
con.setRequestMethod("GET");
con.connect();
int response = con.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");
}
JSONObject obj = makeWeatherRequest(con.getURL());
lat = String.valueOf(obj.get("lat"));
lon = String.valueOf(obj.get("lon"));
new WeatherRequestObject(config.getAPIKey(), config.getWeatherLatitude(), config.getWeatherLongitude());
} catch (Exception e) {
debug(e.getMessage());
logger.severe(e.getMessage());
logger.severe("Disabling weather sync...");
weatherEnabled = false;
config.setWeatherEnabled(false);
return;
}
for (World world : getServer().getWorlds())
if (world.getEnvironment().equals(World.Environment.NORMAL))
world.setGameRuleValue("doWeatherCycle", "false");
debug("Enabling weather sync...");
getServer().getScheduler().scheduleSyncRepeatingTask(this, () -> {
debug("Syncing weather...");
boolean rain = false, thunder = false;
try {
JSONObject obj = makeWeatherRequest(new URL(String.format("https://api.openweathermap.org/data/2.5/weather?lat=%s&lon=%s&appid=%s", lat, lon, apiKey)));
JSONArray conditions = (JSONArray) obj.get("weather");
WeatherRequestObject request = new WeatherRequestObject(config.getAPIKey(), config.getWeatherLatitude(), config.getWeatherLongitude());
for (Object rawCondition : conditions) {
JSONObject condition = (JSONObject) rawCondition;
int id = Integer.parseInt(String.valueOf(condition.get("id")));
debug("Weather ID: " + id);
while (id >= 10)
id /= 10;
if (!rain)
rain = id == 2 || id == 3 || id == 5 || id == 6;
if (!thunder)
thunder = id == 2;
}
debug("Setting weather (Rain: " + request.isRaining() + ", Thunder: " + request.isThundering() + ")...");
for (World world : getServer().getWorlds())
if (world.getEnvironment().equals(World.Environment.NORMAL)) {
world.setStorm(request.isRaining());
world.setThundering(request.isThundering());
}
} catch (Exception e) {
logger.severe("There was an error when attempting to get weather information");
debug(e.getMessage());
}
}, 0L, config.getWeatherSyncInterval());
debug("Setting weather (Rain: " + rain + ", Thunder: " + thunder + ")...");
for (World world : getServer().getWorlds())
if (world.getEnvironment().equals(World.Environment.NORMAL)) {
world.setStorm(rain);
world.setThundering(thunder);
}
}, 0L, weatherSyncInterval);
debug("Weather sync enabled");
}
private JSONObject makeWeatherRequest(URL url) throws IOException, ParseException {
Scanner scanner = new Scanner(url.openStream());
StringBuilder data = new StringBuilder();
while (scanner.hasNext()) {
data.append(scanner.nextLine());
private long calculateWorldTime(Calendar cal, String sunriseTime, String sunsetTime) {
String[] sunriseTimeSplit = sunriseTime.split(":");
String[] sunsetTimeSplit = sunsetTime.split(":");
long sunriseMinutes = Long.parseLong(sunriseTimeSplit[0]) * 60 + Long.parseLong(sunriseTimeSplit[1]) + Long.parseLong(sunriseTimeSplit[2].substring(0, 2)) / 60;
long sunsetMinutes = Long.parseLong(sunsetTimeSplit[0]) * 60 + Long.parseLong(sunsetTimeSplit[1]) + Long.parseLong(sunsetTimeSplit[2].substring(0, 2)) / 60;
if (sunriseTimeSplit[2].substring(3).equalsIgnoreCase("PM"))
sunriseMinutes += 720;
if (sunsetTimeSplit[2].substring(3).equalsIgnoreCase("PM"))
sunsetMinutes += 720;
LocalTime currentTime = LocalTime.of(cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE));
int currentMinutes = currentTime.getHour() * 60 + currentTime.getMinute();
if (currentMinutes >= sunriseMinutes && currentMinutes < sunsetMinutes) {
return ((currentMinutes - sunriseMinutes) / (sunsetMinutes - sunriseMinutes) * 13569) + 23041;
} else {
if (currentMinutes < sunriseMinutes) {
currentMinutes += 1440;
}
return ((currentMinutes - sunsetMinutes) / (1440 - sunsetMinutes + sunriseMinutes) * 13569) + 12610;
}
scanner.close();
JSONParser parser = new JSONParser();
return (JSONObject) parser.parse(data.toString());
}
private void debug(String message) {
if (debug) {
public ConfigManager getConfigurator() {
return config;
}
public void debug(String message) {
if (config.debugEnabled()) {
logger.info("[DEBUG] " + message);
}
}

View File

@@ -0,0 +1,59 @@
package io.github.jack1424.realtimeweather.requests;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import javax.naming.ConfigurationException;
import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.net.ProtocolException;
import java.net.URL;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
public class SunriseSunsetRequestObject {
private String sunriseTime, sunsetTime;
public SunriseSunsetRequestObject(TimeZone timeZone, String lat, String lon) throws IOException, ParseException, ConfigurationException {
URL url = new URL(String.format("https://api.sunrisesunset.io/json?lat=%s&lng=%s&timezone=UTC", lat, lon));
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.connect();
int responseCode = con.getResponseCode();
if (responseCode > 399)
throw new ProtocolException("Server/client error (HTTP error " + responseCode + ")");
Scanner scanner = new Scanner(url.openStream());
StringBuilder data = new StringBuilder();
while (scanner.hasNext()) {
data.append(scanner.nextLine());
}
scanner.close();
JSONObject response = (JSONObject) ((JSONObject) new JSONParser().parse(data.toString())).get("results");
sunriseTime = response.get("sunrise").toString();
sunsetTime = response.get("sunset").toString();
if (sunriseTime.equalsIgnoreCase("null") || sunsetTime.equalsIgnoreCase("null"))
throw new ConfigurationException("Time(s) returned null. Check the sunrise/sunset longitude and latitude.");
DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("h:mm:ss a");
LocalDate currentDate = LocalDate.now(ZoneId.of("UTC"));
sunriseTime = ZonedDateTime.of(currentDate, LocalTime.parse(sunriseTime, timeFormatter), ZoneId.of("UTC")).withZoneSameInstant(timeZone.toZoneId()).format(timeFormatter);
sunsetTime = ZonedDateTime.of(currentDate, LocalTime.parse(sunsetTime, timeFormatter), ZoneId.of("UTC")).withZoneSameInstant(timeZone.toZoneId()).format(timeFormatter);
}
public String getSunriseTime() {
return sunriseTime;
}
public String getSunsetTime() {
return sunsetTime;
}
}

View File

@@ -0,0 +1,66 @@
package io.github.jack1424.realtimeweather.requests;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import javax.naming.ConfigurationException;
import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.Scanner;
public class WeatherRequestObject {
private boolean rain = false, thunder = false;
public WeatherRequestObject(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));
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.connect();
int responseCode = con.getResponseCode();
if (responseCode > 499) {
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());
StringBuilder data = new StringBuilder();
while (scanner.hasNext()) {
data.append(scanner.nextLine());
}
scanner.close();
JSONArray conditions = (JSONArray) ((JSONObject) new JSONParser().parse(data.toString())).get("weather");
for (Object rawCondition : conditions) {
int id = Integer.parseInt(String.valueOf(((JSONObject) rawCondition).get("id")));
while (id >= 10)
id /= 10;
if (!rain)
rain = id == 2 || id == 3 || id == 5 || id == 6;
if (!thunder)
thunder = id == 2;
}
}
public boolean isRaining() {
return rain;
}
public boolean isThundering() {
return thunder;
}
}

View File

@@ -1,26 +1,62 @@
# RealTimeWeather Configuration File (v1)
# Configure RTM below BEFORE using it
# RealTimeWeather Configuration File (v1.3.0)
# You can find detailed instructions at: https://github.com/Jack1424/RealTimeWeather/wiki#editing-the-configuration-file
################################# TIME SYNC SETTINGS #################################################################
# Set to true to enable time syncing, or false to disable #
# All time-related settings will be ignored if this is set to false #
SyncTime: false
#
# #
# Set to false to enable the /time set command (not recommended) #
BlockTimeSetCommand: true
# #
# Prevent players from sleeping in beds at night (they will still be able to set their spawn point) #
# If you disable this, strange things could happen #
DisableBedsAtNight: true
# The message sent to players when they try to sleep at night when beds are disabled #
DisableBedsAtNightMessage: ''
# #
# You can change the time between time syncs from the default (5 seconds) below #
TimeSyncInterval: 100
# #
# Enter the time zone that you want to sync your world(s) with #
# This location CAN be different from your chosen weather location #
# You can find a full list of timezones here: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List #
Timezone: 'America/New_York'
Timezone: 'Etc/UTC'
# #
# Set to default to use "default" Minecraft sunrise/sunset times (always 5:02 AM and 6:36 PM respectfully) #
# Set to real to sync the sunrise/sunset times with a real world location (configure below) #
# Set to custom to use custom sunrise/sunset times (configure below) #
SunriseSunset: default
# Enter the latitude and longitude of the location that you want to sync the sunrise and sunset with #
# If you set this to a place with no sunrise/sunset (like the North Pole), the default times will be used #
# NOTE: You can find the latitude and longitude of a location at https://www.latlong.net/ #
# This feature is provided for free by SunriseSunset.io #
SunriseSunsetLatitude: '0'
SunriseSunsetLongitude: '0'
# Enter the times that you would like to use for sunrise and sunset #
# You MUST include the seconds (even if they're just 00) #
# Sunrise is defined as 23041 ticks and sunset is 12610 ticks in-game #
SunriseCustomTime: '5:02:27 AM'
SunsetCustomTime: '6:36:36 PM'
######################################################################################################################
################################# WEATHER SYNC SETTINGS ##############################################################
# Set to true to enable weather syncing, or false to disable #
# All weather-related settings will be ignored if this is set to false #
SyncWeather: false
#
# #
# Set to false to enable the /weather command (not recommended) #
BlockWeatherCommand: true
# #
# Prevent players from sleeping in beds during a thunderstorm (they will still be able to set their spawn point) #
# If you disable this, it could break weather syncing #
DisableBedsDuringThunder: true
# The message sent to players when they try to sleep during a thunderstorm when beds are disabled #
DisableBedsDuringThunderMessage: ''
# #
# You can change the time between weather syncs from the default (5 minutes) below #
# Due to OpenWeather's restrictions, setting this value below 2400 (2 minutes) will cause problems #
# Setting this value below 200 (10 seconds) is not recommended #
# The minimum safe value on a free API plan is 40 (2 seconds) #
# You can find a handy tick calculator here: https://mapmaking.fr/tick/ #
WeatherSyncInterval: 6000
# #
@@ -28,16 +64,17 @@ WeatherSyncInterval: 6000
# Then, create an API key at https://openweathermap.org/appid and copy it #
# Finally, paste the API key below and DO NOT SHARE IT WITH OTHERS #
APIKey: 'API_KEY'
# Enter the zip code and country code of the location that you want to sync your world(s) weather with #
# NOTE: A list of country codes can be found at https://en.wikipedia.org/wiki/ISO_3166-1#Current_codes #
ZipCode: '10001'
CountryCode: 'US'
# #
# Enter the latitude and longitude of the location that you want to sync your world(s) weather with #
# NOTE: You can find the latitude and longitude of a location at https://www.latlong.net/ #
WeatherLatitude: '0'
WeatherLongitude: '0'
# #
######################################################################################################################
# Set to true for various console messages when time and weather sync are executed
# This is useful if the plugin is not working, and you want to find out what's wrong
# This will also provide java error messages when an error is caught and managed by RTM
# Note: There will be no messages during a time sync because they happen every second
# Note: Java exceptions and fatal plugin errors will still be logged regardless of the debug value
# This will also provide error messages even when an error is caught and managed by RTM
# Note: There will be no messages during a time sync because they happen very frequently
# Note: Unhandled plugin errors will still be logged regardless of the debug value
Debug: false

View File

@@ -2,5 +2,6 @@ name: RealTimeWeather
version: '${version}'
description: Sync your server time and weather with the real world
main: io.github.jack1424.realtimeweather.RealTimeWeather
authors: [ Jack1424 ]
load: POSTWORLD
authors: [Jack1424]
website: https://github.com/Jack1424/RealTimeWeather