10 Commits
1.0 ... 1.1

6 changed files with 1131 additions and 1222 deletions

205
README.md
View File

@@ -1,141 +1,108 @@
# RealTimeWeather # RealTimeWeather
Ein Minecraft-Plugin, das Echtzeit-Wetter und -Zeit in deine Welten bringt! **RealTimeWeather** synchronisiert das In-Game-Wetter und die Tageszeit mit Daten von OpenWeatherMap und bietet eine benutzerfreundliche GUI, Wettervorhersagen und anpassbare Anzeigeoptionen. Entwickelt für Minecraft 1.21.1. **RealTimeWeather** ist ein Bukkit/Spigot/Paper-Plugin, das echte Wetter- und Zeitdaten aus der realen Welt in deine Minecraft-Welt synchronisiert und live auf der Actionbar anzeigt inklusive Temperatur, Wettericon, Luftfeuchtigkeit, Windstärke und Sonnenauf-/untergang.
## Funktionen ## ⭐ Features
- **Echtzeit-Wetter**: Synchronisiert Regen, Gewitter oder klares Wetter mit realen Wetterdaten eines konfigurierbaren Orts. - Echte Wetter- und Uhrzeit-Synchronisation pro Welt
- **Echtzeit-Zeit**: Passt die Minecraft-Tageszeit an die aktuelle Uhrzeit an (deaktiviert den Tageszyklus). - Anzeige auf der Actionbar:
- **Actionbar-Anzeige**: Zeigt Datum, Uhrzeit, Wetter-Symbol (z. B. 🌧️) und Temperatur in der Actionbar an, mit Optionen für Position (oben links/rechts) und Symbolanzeige. Datum, Uhrzeit, Wetter-Icon, Temperatur, Luftfeuchtigkeit 💧, Windgeschwindigkeit 🌬️, Sonnenaufgang 🌅 & Sonnenuntergang 🌇
- **Wettervorhersage**: 5-Tage-Wettervorhersage über den Befehl `/weatherforecast`. - Eigene Location pro Spieler möglich (GUI & Befehl)
- **GUI**: Intuitive Benutzeroberfläche zum Festlegen von Orten, Umschalten der Anzeige und Abrufen von Informationen. - Ingame-Vorhersage (5 Tage) als Command
- **Mehrsprachenunterstützung**: Unterstützt Deutsch (`de`) und Englisch (`en`) über `lang.yml`, mit einfacher Erweiterung für weitere Sprachen. - Wetterumschaltung auf Server synchron mit echten Wetterdaten (optional)
- **Weltspezifische Konfiguration**: Unterschiedliche Einstellungen für jede Welt in `config.yml`. - Volle Mehrsprachigkeit über lang.yml
- **Spielerindividuelle Orte**: Spieler können ihren eigenen Ort mit `/wetter setlocation` festlegen. - Kompatibel mit Minecraft 1.19.x 1.21.x
- **Berechtigungen**: Admin-Befehle sind durch Berechtigungen geschützt.
## Installation ## 🔧 Installation
1. **Download**: Lade die `RealTimeWeather.jar` aus den [Releases](https://github.com/M_Viper/RealTimeWeather/releases) herunter. 1. **Kopiere die Dateien:**<br>
2. **Plugin-Ordner**: Kopiere die JAR-Datei in den `plugins`-Ordner deines Minecraft-Servers. Die JAR nach `/plugins/` kopieren, Server neu starten.
3. **API-Schlüssel**: Registriere dich bei [OpenWeatherMap](https://openweathermap.org/) für einen kostenlosen API-Schlüssel. 2. **OpenWeatherMap API-Key** im `/plugins/RealTimeWeather/config.yml` eintragen:
4. **Konfiguration**: Bearbeite die `config.yml` im Ordner `plugins/RealTimeWeather/` und füge deinen API-Schlüssel ein.
5. **Server starten**: Starte deinen Server, um das Plugin zu laden. Die `lang.yml` wird automatisch generiert.
## Konfiguration api-key: "DEIN_OPENWEATHERMAP_API_KEY"
Die Konfigurationsdateien befinden sich im Ordner `plugins/RealTimeWeather/`. Registriere gratis unter https://openweathermap.org.
### config.yml 3. **Plugin starten/neu laden:**<br>
`reload` Befehl (`/wetter reload`) oder Server-Neustart.
## ⚙️ Kurzes Setup
- Die wichtigsten Einstellungen sind in der `config.yml` dokumentiert (siehe unten).
- Du kannst für jede Welt eigene Locations, Anzeige-Modi oder Wettertypen setzen.
## 🕹️ Kommandos
| Befehl | Beschreibung |
|-----------------------|-----------------------------------------------|
| `/wetter help` | Alle Befehle und Kurzinfos anzeigen |
| `/wetter reload` | Konfiguration und Sprache neu laden |
| `/wetter setlocation <city,country>` | Eigene Stadt für Anzeige wählen |
| `/wetter query` | Zeigt das aktuelle Wetter für dich an |
| `/wetter info` | Infos zum Plugin |
| `/wetter gui` | Öffnet das GUI mit Schnell-Optionen |
| `/weatherforecast` | 5-Tage-Wetterprognose deiner Location |
| `/toggleweather` | Actionbar-Wetteranzeige für Welt (de)aktivieren |
## 📊 Live-Anzeige (Actionbar)
Beispiel:
08.08.2025 18:31 ☁️ 21.7°C | 💧 68% | 🌬️ 2.5 m/s | 🌅 05:48 | 🌇 21:34
```yml
## 📝 Beispiel-config.yml
```yaml
api-key: "DEIN_API_KEY_HIER" api-key: "DEIN_API_KEY_HIER"
update-interval: 60 # Sekunden update-interval: 60
defaults: defaults:
enabled: true # Plugin für Welten ohne spezifische Konfiguration aktivieren enabled: true
location: "Berlin,de" # Stadt,Ländercode location: "Berlin,de"
units: "metric" # metric = Celsius, imperial = Fahrenheit units: "metric"
time-format: "24h" # "24h" oder "12h" time-format: "24h"
display-actionbar: true display-actionbar: true
display-weather-icon: true display-weather-icon: true
display-position: "top-right" # top-left oder top-right
padding-right: 100 # Anzahl der Leerzeichen für top-right display-position / padding-right werden zentriert ignoriert
display-position: "top-right"
padding-right: 100
sync-in-game-weather: true
worlds: worlds:
world: world:
enabled: true enabled: true
location: "London,uk" location: "Berlin,de"
units: "imperial" units: "metric"
time-format: "12h" time-format: "24h"
display-actionbar: true display-actionbar: true
display-weather-icon: true display-weather-icon: true
display-position: "top-left" display-position: "top-left"
padding-right: 50 padding-right: 50
world_nether: sync-in-game-weather: true
enabled: false world_nether:
location: "Tokyo,jp" enabled: false
units: "metric" location: "Berlin,de"
time-format: "24h" units: "metric"
display-actionbar: true time-format: "24h"
display-weather-icon: false display-actionbar: true
display-position: "top-right" display-weather-icon: false
padding-right: 150 display-position: "top-right"
padding-right: 150
sync-in-game-weather: false
``` ```
# RealTimeWeather
Ein Minecraft-Plugin, das Echtzeit-Wetter und -Zeit in deine Welten bringt. Synchronisiert Wetter und Tageszeit mit OpenWeatherMap-Daten. Entwickelt für Minecraft 1.21.1 - 1.21.8. ## 🧑‍💻 Erweiterungen
## Konfiguration - Anzeige von Feuchtigkeit, Wind & Sonnenzeiten kann leicht deaktiviert/angepasst werden (siehe Actionbar-Code).
- Ländercodes und Städte werden in OpenWeatherMap-Syntax verwendet, z.B. `London,gb`, `Frankfurt,de`.
## ❤️ Lizenz
### lang.yml [MIT License](LICENSE)
Enthält Übersetzungen für Deutsch (`de`) und Englisch (`en`). Beispiel für Deutsch: ---
```yaml > Fragen, Feature-Wünsche oder Bugreports gerne als Gitea-Issue!
languages:
de:
help_header: "RealTimeWeather-Befehle"
help_help: "Diese Hilfenachricht anzeigen"
help_reload: "Die Plugin-Konfiguration neu laden (Berechtigung: realtimeweather.reload)"
help_setlocation: "Eigenen Wetterort für den Spieler festlegen (z.B. Berlin,de)"
help_query: "Aktuelles Wetter für den Spielerort oder die Welt anzeigen"
help_info: "Plugin-Informationen anzeigen"
help_gui: "GUI für Wettersteuerung öffnen"
help_weatherforecast: "Wettervorhersage für 5 Tage anzeigen"
help_toggleweather: "Wetteranzeige in der Actionbar ein-/ausschalten"
usage: "Verwendung: /wetter reload | setlocation <Ort> | query | info | gui | help"
usage_setlocation: "Verwendung: /wetter setlocation <Stadt,Land>"
no_permission: "Du hast keine Berechtigung für diesen Befehl!"
reload_success: "Konfiguration erfolgreich neu geladen!"
only_players: "Dieser Befehl ist nur für Spieler!"
plugin_disabled: "Plugin ist für die Welt {world} deaktiviert!"
location_set: "Ort auf {location} gesetzt!"
invalid_location: "Ungültiger Ort: {location}"
forecast_error: "Fehler beim Abrufen der Wetterdaten für {location}: {error}"
gui_title: "Wettersteuerung"
gui_setlocation: "Ort festlegen"
gui_setlocation_lore: "Eigenen Wetterort festlegen"
gui_toggleweather: "Wetteranzeige umschalten"
gui_toggleweather_lore: "Wetter-Actionbar ein-/ausschalten"
gui_forecast: "Wettervorhersage"
gui_forecast_lore: "5-Tage-Wettervorhersage anzeigen"
gui_info: "Info"
gui_info_lore: "Plugin-Informationen anzeigen"
gui_setlocation_prompt: "Gib den Ort ein (z.B. Berlin,de)"
toggle_enabled: "Wetteranzeige für {world} aktiviert!"
toggle_disabled: "Wetteranzeige für {world} deaktiviert!"
forecast_header: "Wettervorhersage für {location}"
weather:
clear: "Klar"
clouds: "Bewölkt"
rain: "Regen"
thunderstorm: "Gewitter"
snow: "Schnee"
mist: "Nebel"
fog: "Nebel"
haze: "Dunst"
en:
# Ähnliche Schlüssel wie oben, auf Englisch
```
# RealTimeWeather
Ein Minecraft-Plugin, das Echtzeit-Wetter und -Zeit in deine Welten bringt. Entwickelt für Minecraft 1.21.1.
## Befehle
- `/wetter help`: Zeigt die Hilfeübersicht an.
- `/wetter reload`: Lädt die Konfiguration neu (Berechtigung: `realtimeweather.reload`).
- `/wetter setlocation <city,country>`: Legt einen individuellen Ort für den Spieler fest.
- `/wetter query`: Zeigt aktuelles Wetter für den Spielerort oder die Welt.
- `/wetter info`: Zeigt Plugin-Informationen an.
- `/wetter gui`: Öffnet die Wetter-GUI.
- `/weatherforecast`: Zeigt die 5-Tage-Wettervorhersage.
- `/toggleweather`: Schaltet die Wetteranzeige in der Actionbar ein/aus.
## Berechtigungen
- `realtimeweather.reload`: Erlaubt `/wetter reload`.
- `realtimeweather.admin`: Erlaubt Admin-Benachrichtigungen bei Wetterabfrage-Fehlern.

View File

@@ -1,123 +1,158 @@
package dev.viper.weathertime; package dev.viper.weathertime;
import org.json.JSONObject; import org.json.JSONObject;
import org.json.JSONArray;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.URL; import java.net.URL;
import java.time.Instant; import java.time.Instant;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.logging.Logger; import java.util.logging.Logger;
public class WeatherFetcher { /**
* Holt Wetter und Zeitdaten asynchron von OpenWeatherMap.
private final String apiKey; * Liefert WeatherTimeData zurück, mit konsistentem Modell und Fehlerhandling.
private final String location; * Erweiterung: Erfasst Luftfeuchtigkeit, Windgeschwindigkeit, Sonnenauf- und -untergang.
private final String units; */
private final Logger logger; public class WeatherFetcher {
public WeatherFetcher(String apiKey, String location, String units, Logger logger) { private final String apiKey;
this.apiKey = apiKey; private final String location;
this.location = location; private final String units;
this.units = units.toLowerCase(); private final Logger logger;
this.logger = logger;
if (!this.units.equals("metric") && !this.units.equals("imperial")) { public WeatherFetcher(String apiKey, String location, String units, Logger logger) {
logger.warning("Ungültige Einheit für " + location + ": " + units + ". Verwende 'metric' als Fallback."); this.apiKey = apiKey == null ? "" : apiKey.trim();
} this.location = location == null ? "Berlin,de" : location.trim();
} this.units = units == null ? "metric" : units.trim().toLowerCase();
this.logger = logger;
public WeatherData fetch() throws Exception { if (!this.units.equals("metric") && !this.units.equals("imperial")) {
String effectiveUnits = units.equals("metric") || units.equals("imperial") ? units : "metric"; logger.warning("Ungültige Einheit für " + this.location + ": " + this.units + ". Verwende 'metric' als Fallback.");
}
String urlString = String.format( }
"https://api.openweathermap.org/data/2.5/weather?q=%s&appid=%s&units=%s",
location, apiKey, effectiveUnits); /**
* Holt die aktuellen Wetter- und Zeitdaten inklusive Zusatzinfos.
URL url = new URL(urlString); * Wirft RuntimeExceptions mit klaren Messages bei Fehlern.
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); */
connection.setRequestMethod("GET"); public WeatherTimeData fetchAsWeatherTimeData() throws Exception {
connection.setConnectTimeout(5000); if (apiKey.isEmpty()) throw new RuntimeException("API-Key fehlt.");
connection.setReadTimeout(5000); String effectiveUnits = (units.equals("metric") || units.equals("imperial")) ? units : "metric";
String urlString = String.format(
int status = connection.getResponseCode(); "https://api.openweathermap.org/data/2.5/weather?q=%s&appid=%s&units=%s",
if (status != 200) { location, apiKey, effectiveUnits);
logger.warning("HTTP-Fehlercode: " + status + " für Ort: " + location);
throw new RuntimeException("HTTP-Fehlercode: " + status + " für Ort: " + location); try {
} JSONObject json;
try (BufferedReader in = new BufferedReader(new InputStreamReader(openConnectionStream(urlString)))) {
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder content = new StringBuilder();
StringBuilder content = new StringBuilder(); String inputLine;
String inputLine; while ((inputLine = in.readLine()) != null) {
content.append(inputLine);
while ((inputLine = in.readLine()) != null) { }
content.append(inputLine); json = new JSONObject(content.toString());
} }
in.close();
connection.disconnect(); // Fehlerfall: Antwort-Code ungleich 200
if (json.has("cod") && json.getInt("cod") != 200) {
JSONObject json = new JSONObject(content.toString()); String msg = json.has("message") ? json.getString("message") : "Unbekannter Fehler";
long dt = json.getLong("dt"); logger.warning("API Error für " + location + ": " + msg);
int timezoneShift; throw new RuntimeException(msg);
try { }
timezoneShift = json.getInt("timezone");
} catch (Exception e) { long dt = json.getLong("dt");
logger.warning("Fehler beim Abrufen der Zeitzone für Ort: " + location + ": " + e.getMessage()); int timezoneShift = json.optInt("timezone", 0); // Zeitzonen-Offset in Sekunden
throw new RuntimeException("Fehler beim Abrufen der Zeitzone für Ort: " + location, e);
} ZonedDateTime dateTime = Instant.ofEpochSecond(dt)
ZonedDateTime dateTime = Instant.ofEpochSecond(dt).atZone(ZoneId.of("UTC")).plusSeconds(timezoneShift); .atZone(ZoneId.of("UTC"))
String weatherMain = json.getJSONArray("weather").getJSONObject(0).getString("main"); .plusSeconds(timezoneShift);
double temperature = json.getJSONObject("main").getDouble("temp");
String weatherMain = json.getJSONArray("weather").getJSONObject(0).getString("main");
if (effectiveUnits.equals("imperial") && (temperature < -50 || temperature > 150)) { double temperature = json.getJSONObject("main").getDouble("temp");
logger.warning("Unrealistische Temperatur für " + location + ": " + temperature + "°F. API-Fehler?");
} else if (effectiveUnits.equals("metric") && (temperature < -50 || temperature > 60)) { if (effectiveUnits.equals("imperial") && (temperature < -50 || temperature > 150)) {
logger.warning("Unrealistische Temperatur für " + location + ": " + temperature + "°C. API-Fehler?"); logger.warning("Unrealistische Temperatur für " + location + ": " + temperature + "°F. API-Fehler?");
} } else if (effectiveUnits.equals("metric") && (temperature < -50 || temperature > 60)) {
logger.warning("Unrealistische Temperatur für " + location + ": " + temperature + "°C. API-Fehler?");
return new WeatherData(dateTime, weatherMain, temperature); }
}
// Temperatur immer in Celsius für WeatherTimeData speichern
public JSONObject fetchForecast() throws Exception { double tempCelsius = effectiveUnits.equals("imperial") ? (temperature - 32) * 5 / 9 : temperature;
String effectiveUnits = units.equals("metric") || units.equals("imperial") ? units : "metric";
// NEUE FELDER AUSLESEN
String urlString = String.format( int humidity = json.getJSONObject("main").getInt("humidity");
"https://api.openweathermap.org/data/2.5/forecast?q=%s&appid=%s&units=%s", double windSpeed = json.getJSONObject("wind").optDouble("speed", 0.0);
location, apiKey, effectiveUnits);
URL url = new URL(urlString); ZonedDateTime sunrise = Instant.ofEpochSecond(json.getJSONObject("sys").getLong("sunrise"))
HttpURLConnection connection = (HttpURLConnection) url.openConnection(); .atZone(ZoneId.of("UTC"))
connection.setRequestMethod("GET"); .plusSeconds(timezoneShift);
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000); ZonedDateTime sunset = Instant.ofEpochSecond(json.getJSONObject("sys").getLong("sunset"))
.atZone(ZoneId.of("UTC"))
int status = connection.getResponseCode(); .plusSeconds(timezoneShift);
if (status != 200) {
logger.warning("HTTP-Fehlercode: " + status + " für Ort: " + location); return new WeatherTimeData(dateTime, weatherMain, tempCelsius,
throw new RuntimeException("HTTP-Fehlercode: " + status + " für Ort: " + location); humidity, windSpeed, sunrise, sunset);
}
} catch (RuntimeException ru) {
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); throw ru;
StringBuilder content = new StringBuilder(); } catch (Exception ex) {
String inputLine; logger.warning("Fehler beim Abrufen von OpenWeatherMap: " + ex.getMessage());
while ((inputLine = in.readLine()) != null) { throw new RuntimeException("Verbindung oder API-Fehler: " + ex.getMessage(), ex);
content.append(inputLine); }
} }
in.close();
connection.disconnect(); /**
* Holt das Wetter-Vorhersage-JSON (5 Tage, 3-Stunden-Takt).
return new JSONObject(content.toString()); * Muss im Command asynchron ausgewertet werden!
} */
public JSONObject fetchForecast() throws Exception {
public static class WeatherData { if (apiKey.isEmpty()) throw new RuntimeException("API-Key fehlt.");
ZonedDateTime dateTime; String effectiveUnits = (units.equals("metric") || units.equals("imperial")) ? units : "metric";
String weatherMain; String urlString = String.format(
double temperature; "https://api.openweathermap.org/data/2.5/forecast?q=%s&appid=%s&units=%s",
location, apiKey, effectiveUnits);
public WeatherData(ZonedDateTime dateTime, String weatherMain, double temperature) {
this.dateTime = dateTime; try (BufferedReader in = new BufferedReader(new InputStreamReader(openConnectionStream(urlString)))) {
this.weatherMain = weatherMain; StringBuilder content = new StringBuilder();
this.temperature = temperature; String inputLine;
} while ((inputLine = in.readLine()) != null) {
} content.append(inputLine);
} }
JSONObject json = new JSONObject(content.toString());
if (json.has("cod") && (!"200".equals(json.get("cod").toString()))) {
String msg = json.has("message") ? json.getString("message") : "Unbekannter Fehler";
logger.warning("API Error (Forecast) für " + location + ": " + msg);
throw new RuntimeException(msg);
}
return json;
} catch (Exception e) {
logger.warning("Fehler beim Abrufen der Wettervorhersage: " + e.getMessage());
throw new RuntimeException("Fehler beim Abrufen der Wettervorhersage: " + e.getMessage(), e);
}
}
/** Öffnet eine HTTP-GET-Verbindung und liefert den InputStream der Response zurück (Timeouts gesetzt). */
private java.io.InputStream openConnectionStream(String urlString) throws Exception {
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(6000);
connection.setReadTimeout(6000);
int status = connection.getResponseCode();
if (status != 200) {
String err = "(keine Fehlerdetails)";
try (BufferedReader errIn = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) {
StringBuilder sb = new StringBuilder();
String l;
while ((l = errIn.readLine()) != null) sb.append(l);
err = sb.toString();
} catch (Exception suppress) {}
throw new RuntimeException("HTTP-Fehlercode: " + status + " " + err);
}
return connection.getInputStream();
}
}

View File

@@ -1,57 +1,87 @@
package dev.viper.weathertime; package dev.viper.weathertime;
import java.time.Instant; import java.time.ZonedDateTime;
import java.time.LocalTime;
import java.time.ZoneOffset; /**
* Zentrale Datenklasse für Wetter- und Zeitinformationen.
public class WeatherTimeData { * Erweiterung: enthält jetzt auch Luftfeuchtigkeit, Windgeschwindigkeit und Sonnenauf/untergang.
private final boolean rain; */
private final boolean thunder; public class WeatherTimeData {
private final long unixTime;
private final double tempCelsius; private final ZonedDateTime dateTime; // Lokale Zeit am Standort
private final String weatherMain; // Hauptwetterbeschreibung (z. B. "Clear", "Rain")
public WeatherTimeData(boolean rain, boolean thunder, long unixTime, double tempCelsius) { private final double tempCelsius; // Temperatur in °C
this.rain = rain;
this.thunder = thunder; private final int humidity; // Luftfeuchtigkeit in %
this.unixTime = unixTime; private final double windSpeed; // Windgeschwindigkeit (m/s oder mph)
this.tempCelsius = tempCelsius; private final ZonedDateTime sunrise; // Sonnenaufgang
} private final ZonedDateTime sunset; // Sonnenuntergang
public boolean isRain() { public WeatherTimeData(
return rain; ZonedDateTime dateTime,
} String weatherMain,
double tempCelsius,
public boolean isThunder() { int humidity,
return thunder; double windSpeed,
} ZonedDateTime sunrise,
ZonedDateTime sunset) {
public double getTemp(String unit) { this.dateTime = dateTime;
return unit.equalsIgnoreCase("F") ? (tempCelsius * 9 / 5) + 32 : tempCelsius; this.weatherMain = weatherMain;
} this.tempCelsius = tempCelsius;
this.humidity = humidity;
public String getFormattedTime(String format) { this.windSpeed = windSpeed;
LocalTime time = Instant.ofEpochSecond(unixTime) this.sunrise = sunrise;
.atOffset(ZoneOffset.UTC) this.sunset = sunset;
.toLocalTime(); }
if ("12h".equalsIgnoreCase(format)) { public ZonedDateTime getDateTime() {
int hour = time.getHour(); return dateTime;
String ampm = hour >= 12 ? "PM" : "AM"; }
hour = hour % 12;
if (hour == 0) hour = 12; public String getWeatherMain() {
return String.format("%02d:%02d %s", hour, time.getMinute(), ampm); return weatherMain;
} else { }
return String.format("%02d:%02d", time.getHour(), time.getMinute());
} public double getTemp(String unit) {
} return "F".equalsIgnoreCase(unit)
? (tempCelsius * 9 / 5) + 32
public long toMinecraftTime() { : tempCelsius;
LocalTime time = Instant.ofEpochSecond(unixTime) }
.atOffset(ZoneOffset.UTC)
.toLocalTime(); public int getHumidity() {
return humidity;
int hour = time.getHour(); }
int minute = time.getMinute();
return (hour * 1000L / 24) + (minute * 1000L / (24 * 60)); public double getWindSpeed() {
} return windSpeed;
} }
public ZonedDateTime getSunrise() {
return sunrise;
}
public ZonedDateTime getSunset() {
return sunset;
}
public String getFormattedTime(String format) {
int hour = dateTime.getHour();
int minute = dateTime.getMinute();
if ("12h".equalsIgnoreCase(format)) {
String ampm = hour >= 12 ? "PM" : "AM";
hour = hour % 12;
if (hour == 0) hour = 12;
return String.format("%02d:%02d %s", hour, minute, ampm);
}
return String.format("%02d:%02d", hour, minute);
}
public long toMinecraftTime() {
int hour = dateTime.getHour();
int minute = dateTime.getMinute();
int second = dateTime.getSecond();
return ((hour + 18) % 24) * 1000L
+ (minute * 1000L / 60)
+ (second * 1000L / 3600);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,30 +1,39 @@
api-key: "DEIN_API_KEY_HIER" # OpenWeatherMap API-Key hier eintragen
update-interval: 60 api-key: "DEIN_API_KEY_HIER"
defaults:
enabled: true # Update-Intervall in Sekunden (Standard: 60)
location: "Berlin,de" update-interval: 60
units: "metric"
time-format: "24h" defaults:
display-actionbar: true enabled: true
display-weather-icon: true location: "Berlin,de" # Stadt,Land
display-position: "top-right" units: "metric" # metric = °C, imperial = °F
padding-right: 100 time-format: "24h" # oder "12h"
worlds: display-actionbar: true
world: display-weather-icon: true
enabled: true display-position: "top-right"
location: "Berlin,de" padding-right: 100
units: "metric" sync-in-game-weather: true
time-format: "24h"
display-actionbar: true worlds:
display-weather-icon: true world:
display-position: "top-left" enabled: true
padding-right: 50 location: "Berlin,de"
world_nether: units: "metric"
enabled: false time-format: "24h"
location: "Berlin,de" display-actionbar: true
units: "metric" display-weather-icon: true
time-format: "24h" display-position: "top-left"
display-actionbar: true padding-right: 50
display-weather-icon: false sync-in-game-weather: true
display-position: "top-right"
padding-right: 150 world_nether:
enabled: false
location: "Berlin,de"
units: "metric"
time-format: "24h"
display-actionbar: true
display-weather-icon: false
display-position: "top-right"
padding-right: 150
sync-in-game-weather: false

View File

@@ -1,30 +1,32 @@
name: RealTimeWeather name: RealTimeWeather
version: 1.0 version: 1.0
main: dev.viper.weathertime.WeatherTimeSyncPlugin main: dev.viper.weathertime.WeatherTimeSyncPlugin
api-version: 1.21 api-version: 1.21
commands:
wetter: commands:
description: Manages real-time weather and time synchronization wetter:
usage: /<command> reload | setlocation <city,country> | query | info | gui | help description: Manages real-time weather and time synchronization
permission: realtimeweather.use usage: /<command> reload | setlocation <city,country> | query | info | gui | help
weatherforecast: permission: realtimeweather.use
description: Shows the weather forecast for the player's location weatherforecast:
usage: /<command> description: Shows the weather forecast for the player's location
permission: realtimeweather.forecast usage: /<command>
toggleweather: permission: realtimeweather.forecast
description: Toggles the weather display for the current world toggleweather:
usage: /<command> description: Toggles the weather display for the current world
permission: realtimeweather.toggle usage: /<command>
permissions: permission: realtimeweather.toggle
realtimeweather.use:
description: Allows usage of the /wetter command permissions:
default: true realtimeweather.use:
realtimeweather.forecast: description: Allows usage of the /wetter command
description: Allows usage of the /weatherforecast command default: true
default: true realtimeweather.forecast:
realtimeweather.toggle: description: Allows usage of the /weatherforecast command
description: Allows usage of the /toggleweather command default: true
default: true realtimeweather.toggle:
realtimeweather.reload: description: Allows usage of the /toggleweather command
description: Allows reloading the plugin configuration default: true
default: op realtimeweather.reload:
description: Allows reloading the plugin configuration
default: op