Update from Git Manager GUI
This commit is contained in:
32
src/main/java/dev/viper/weathertime/DisplayMode.java
Normal file
32
src/main/java/dev/viper/weathertime/DisplayMode.java
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package dev.viper.weathertime;
|
||||||
|
|
||||||
|
public enum DisplayMode {
|
||||||
|
COMPACT("Kompakt", 5),
|
||||||
|
STANDARD("Standard", 10),
|
||||||
|
DETAILED("Detailliert", 15);
|
||||||
|
|
||||||
|
private final String displayName;
|
||||||
|
private final int lineCount;
|
||||||
|
|
||||||
|
DisplayMode(String displayName, int lineCount) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.lineCount = lineCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLineCount() {
|
||||||
|
return lineCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DisplayMode fromString(String mode) {
|
||||||
|
for (DisplayMode dm : values()) {
|
||||||
|
if (dm.name().equalsIgnoreCase(mode)) {
|
||||||
|
return dm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return STANDARD;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@ public class MetricsManager {
|
|||||||
private final Metrics metrics;
|
private final Metrics metrics;
|
||||||
|
|
||||||
public MetricsManager(JavaPlugin plugin) {
|
public MetricsManager(JavaPlugin plugin) {
|
||||||
int pluginId = 26865; // Deine Plugin-ID von bStats eintragen
|
int pluginId = 26865; // Deine Plugin-ID von bStats
|
||||||
this.metrics = new Metrics(plugin, pluginId);
|
this.metrics = new Metrics(plugin, pluginId);
|
||||||
|
|
||||||
// Optional: Eigene Charts hinzufügen
|
// Optional: Eigene Charts hinzufügen
|
||||||
|
|||||||
69
src/main/java/dev/viper/weathertime/MoonPhase.java
Normal file
69
src/main/java/dev/viper/weathertime/MoonPhase.java
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package dev.viper.weathertime;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
public class MoonPhase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Berechnet die aktuelle Mondphase basierend auf der Minecraft-Zeit
|
||||||
|
*/
|
||||||
|
public static String getPhase(World world) {
|
||||||
|
long fullTime = world.getFullTime();
|
||||||
|
long daysPassed = fullTime / 24000L;
|
||||||
|
int phase = (int) (daysPassed % 8);
|
||||||
|
|
||||||
|
switch (phase) {
|
||||||
|
case 0: return "🌑 Neumond";
|
||||||
|
case 1: return "🌒 Zunehmende Sichel";
|
||||||
|
case 2: return "🌓 Erstes Viertel";
|
||||||
|
case 3: return "🌔 Zunehmender Mond";
|
||||||
|
case 4: return "🌕 Vollmond";
|
||||||
|
case 5: return "🌖 Abnehmender Mond";
|
||||||
|
case 6: return "🌗 Letztes Viertel";
|
||||||
|
case 7: return "🌘 Abnehmende Sichel";
|
||||||
|
default: return "🌑 Neumond";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt nur das Emoji der Mondphase zurück
|
||||||
|
*/
|
||||||
|
public static String getEmoji(World world) {
|
||||||
|
long fullTime = world.getFullTime();
|
||||||
|
long daysPassed = fullTime / 24000L;
|
||||||
|
int phase = (int) (daysPassed % 8);
|
||||||
|
|
||||||
|
switch (phase) {
|
||||||
|
case 0: return "🌑";
|
||||||
|
case 1: return "🌒";
|
||||||
|
case 2: return "🌓";
|
||||||
|
case 3: return "🌔";
|
||||||
|
case 4: return "🌕";
|
||||||
|
case 5: return "🌖";
|
||||||
|
case 6: return "🌗";
|
||||||
|
case 7: return "🌘";
|
||||||
|
default: return "🌑";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt den Namen der Mondphase zurück (ohne Emoji)
|
||||||
|
*/
|
||||||
|
public static String getName(World world) {
|
||||||
|
long fullTime = world.getFullTime();
|
||||||
|
long daysPassed = fullTime / 24000L;
|
||||||
|
int phase = (int) (daysPassed % 8);
|
||||||
|
|
||||||
|
switch (phase) {
|
||||||
|
case 0: return "Neumond";
|
||||||
|
case 1: return "Zunehmende Sichel";
|
||||||
|
case 2: return "Erstes Viertel";
|
||||||
|
case 3: return "Zunehmender Mond";
|
||||||
|
case 4: return "Vollmond";
|
||||||
|
case 5: return "Abnehmender Mond";
|
||||||
|
case 6: return "Letztes Viertel";
|
||||||
|
case 7: return "Abnehmende Sichel";
|
||||||
|
default: return "Neumond";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package dev.viper.weathertime;
|
|||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
@@ -9,8 +10,6 @@ import java.net.URL;
|
|||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
public class UpdateChecker {
|
public class UpdateChecker {
|
||||||
private final JavaPlugin plugin;
|
private final JavaPlugin plugin;
|
||||||
private final int resourceId;
|
private final int resourceId;
|
||||||
@@ -21,16 +20,18 @@ public class UpdateChecker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void getLatestVersion(Consumer<String> consumer) {
|
public void getLatestVersion(Consumer<String> consumer) {
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||||
try {
|
InputStream inputStream = null;
|
||||||
HttpURLConnection connection = (HttpURLConnection)
|
Scanner scanner = null;
|
||||||
new URL("https://api.spiget.org/v2/resources/" + resourceId + "/versions/latest").openConnection();
|
try {
|
||||||
|
HttpURLConnection connection = (HttpURLConnection)
|
||||||
|
new URL("https://api.spiget.org/v2/resources/" + resourceId + "/versions/latest").openConnection();
|
||||||
|
|
||||||
connection.setRequestMethod("GET");
|
connection.setRequestMethod("GET");
|
||||||
connection.addRequestProperty("User-Agent", "Mozilla/5.0");
|
connection.addRequestProperty("User-Agent", "Mozilla/5.0");
|
||||||
|
|
||||||
try (InputStream inputStream = connection.getInputStream();
|
inputStream = connection.getInputStream();
|
||||||
Scanner scanner = new Scanner(inputStream)) {
|
scanner = new Scanner(inputStream);
|
||||||
String response = scanner.useDelimiter("\\A").next();
|
String response = scanner.useDelimiter("\\A").next();
|
||||||
|
|
||||||
JSONObject json = new JSONObject(response);
|
JSONObject json = new JSONObject(response);
|
||||||
@@ -40,11 +41,24 @@ public class UpdateChecker {
|
|||||||
String cleanVersion = versionName.replaceAll("[^0-9.]", "").trim();
|
String cleanVersion = versionName.replaceAll("[^0-9.]", "").trim();
|
||||||
|
|
||||||
consumer.accept(cleanVersion.isEmpty() ? versionName : cleanVersion);
|
consumer.accept(cleanVersion.isEmpty() ? versionName : cleanVersion);
|
||||||
|
} catch (Exception e) {
|
||||||
|
plugin.getLogger().warning("Konnte keine Update-Info abrufen: " + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
if (scanner != null) {
|
||||||
|
try {
|
||||||
|
scanner.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (inputStream != null) {
|
||||||
|
try {
|
||||||
|
inputStream.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
});
|
||||||
plugin.getLogger().warning("Konnte keine Update-Info abrufen: " + e.getMessage());
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
97
src/main/java/dev/viper/weathertime/WeatherColors.java
Normal file
97
src/main/java/dev/viper/weathertime/WeatherColors.java
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
package dev.viper.weathertime;
|
||||||
|
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
|
||||||
|
public class WeatherColors {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die Farbe basierend auf der Temperatur zurück
|
||||||
|
*/
|
||||||
|
public static ChatColor getTemperatureColor(double tempCelsius) {
|
||||||
|
if (tempCelsius < 0) {
|
||||||
|
return ChatColor.AQUA; // Unter 0°C - Hellblau (eisig)
|
||||||
|
} else if (tempCelsius < 10) {
|
||||||
|
return ChatColor.BLUE; // 0-10°C - Blau (kalt)
|
||||||
|
} else if (tempCelsius < 20) {
|
||||||
|
return ChatColor.GREEN; // 10-20°C - Grün (mild)
|
||||||
|
} else if (tempCelsius < 30) {
|
||||||
|
return ChatColor.YELLOW; // 20-30°C - Gelb (warm)
|
||||||
|
} else {
|
||||||
|
return ChatColor.RED; // Über 30°C - Rot (heiß)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die Farbe basierend auf dem Wetter zurück
|
||||||
|
*/
|
||||||
|
public static ChatColor getWeatherColor(String weatherMain) {
|
||||||
|
switch (weatherMain.toLowerCase()) {
|
||||||
|
case "clear":
|
||||||
|
return ChatColor.GOLD; // Sonnig - Gold
|
||||||
|
case "clouds":
|
||||||
|
return ChatColor.GRAY; // Bewölkt - Grau
|
||||||
|
case "rain":
|
||||||
|
case "drizzle":
|
||||||
|
return ChatColor.BLUE; // Regen - Blau
|
||||||
|
case "thunderstorm":
|
||||||
|
return ChatColor.DARK_PURPLE; // Gewitter - Dunkelviolett
|
||||||
|
case "snow":
|
||||||
|
return ChatColor.WHITE; // Schnee - Weiß
|
||||||
|
case "mist":
|
||||||
|
case "fog":
|
||||||
|
case "haze":
|
||||||
|
return ChatColor.DARK_GRAY; // Nebel - Dunkelgrau
|
||||||
|
default:
|
||||||
|
return ChatColor.WHITE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die Farbe basierend auf der Luftfeuchtigkeit zurück
|
||||||
|
*/
|
||||||
|
public static ChatColor getHumidityColor(int humidity) {
|
||||||
|
if (humidity < 30) {
|
||||||
|
return ChatColor.RED; // Trocken
|
||||||
|
} else if (humidity < 60) {
|
||||||
|
return ChatColor.GREEN; // Angenehm
|
||||||
|
} else if (humidity < 80) {
|
||||||
|
return ChatColor.YELLOW; // Feucht
|
||||||
|
} else {
|
||||||
|
return ChatColor.AQUA; // Sehr feucht
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die Farbe basierend auf der Windgeschwindigkeit zurück (m/s)
|
||||||
|
*/
|
||||||
|
public static ChatColor getWindSpeedColor(double windSpeed) {
|
||||||
|
if (windSpeed < 5) {
|
||||||
|
return ChatColor.GREEN; // Leicht
|
||||||
|
} else if (windSpeed < 10) {
|
||||||
|
return ChatColor.YELLOW; // Mäßig
|
||||||
|
} else if (windSpeed < 15) {
|
||||||
|
return ChatColor.GOLD; // Frisch
|
||||||
|
} else if (windSpeed < 20) {
|
||||||
|
return ChatColor.RED; // Stark
|
||||||
|
} else {
|
||||||
|
return ChatColor.DARK_RED; // Sturm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die Farbe basierend auf dem UV-Index zurück
|
||||||
|
*/
|
||||||
|
public static ChatColor getUVIndexColor(int uvIndex) {
|
||||||
|
if (uvIndex <= 2) {
|
||||||
|
return ChatColor.GREEN; // Niedrig
|
||||||
|
} else if (uvIndex <= 5) {
|
||||||
|
return ChatColor.YELLOW; // Mäßig
|
||||||
|
} else if (uvIndex <= 7) {
|
||||||
|
return ChatColor.GOLD; // Hoch
|
||||||
|
} else if (uvIndex <= 10) {
|
||||||
|
return ChatColor.RED; // Sehr hoch
|
||||||
|
} else {
|
||||||
|
return ChatColor.DARK_RED; // Extrem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,16 +44,16 @@ public class WeatherFetcher {
|
|||||||
"https://api.openweathermap.org/data/2.5/weather?q=%s&appid=%s&units=%s",
|
"https://api.openweathermap.org/data/2.5/weather?q=%s&appid=%s&units=%s",
|
||||||
location, apiKey, effectiveUnits);
|
location, apiKey, effectiveUnits);
|
||||||
|
|
||||||
|
BufferedReader in = null;
|
||||||
try {
|
try {
|
||||||
JSONObject json;
|
JSONObject json;
|
||||||
try (BufferedReader in = new BufferedReader(new InputStreamReader(openConnectionStream(urlString)))) {
|
in = new BufferedReader(new InputStreamReader(openConnectionStream(urlString)));
|
||||||
StringBuilder content = new StringBuilder();
|
StringBuilder content = new StringBuilder();
|
||||||
String inputLine;
|
String inputLine;
|
||||||
while ((inputLine = in.readLine()) != null) {
|
while ((inputLine = in.readLine()) != null) {
|
||||||
content.append(inputLine);
|
content.append(inputLine);
|
||||||
}
|
|
||||||
json = new JSONObject(content.toString());
|
|
||||||
}
|
}
|
||||||
|
json = new JSONObject(content.toString());
|
||||||
|
|
||||||
// Fehlerfall: Antwort-Code ungleich 200
|
// Fehlerfall: Antwort-Code ungleich 200
|
||||||
if (json.has("cod") && json.getInt("cod") != 200) {
|
if (json.has("cod") && json.getInt("cod") != 200) {
|
||||||
@@ -79,11 +79,18 @@ public class WeatherFetcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Temperatur immer in Celsius für WeatherTimeData speichern
|
// Temperatur immer in Celsius für WeatherTimeData speichern
|
||||||
double tempCelsius = effectiveUnits.equals("imperial") ? (temperature - 32) * 5 / 9 : temperature;
|
double tempCelsius = effectiveUnits.equals("imperial") ? (temperature - 32) * 5.0 / 9.0 : temperature;
|
||||||
|
|
||||||
// NEUE FELDER AUSLESEN
|
// FELDER AUSLESEN
|
||||||
int humidity = json.getJSONObject("main").getInt("humidity");
|
int humidity = json.getJSONObject("main").getInt("humidity");
|
||||||
double windSpeed = json.getJSONObject("wind").optDouble("speed", 0.0);
|
double windSpeed = json.getJSONObject("wind").optDouble("speed", 0.0);
|
||||||
|
double windDeg = json.getJSONObject("wind").optDouble("deg", 0.0);
|
||||||
|
|
||||||
|
int pressure = json.getJSONObject("main").optInt("pressure", 1013);
|
||||||
|
int clouds = json.getJSONObject("clouds").optInt("all", 0);
|
||||||
|
double feelsLikeTemp = json.getJSONObject("main").optDouble("feels_like", temperature);
|
||||||
|
double feelsLikeCelsius = effectiveUnits.equals("imperial") ? (feelsLikeTemp - 32) * 5.0 / 9.0 : feelsLikeTemp;
|
||||||
|
int visibility = json.optInt("visibility", 10000); // Standard 10km
|
||||||
|
|
||||||
ZonedDateTime sunrise = Instant.ofEpochSecond(json.getJSONObject("sys").getLong("sunrise"))
|
ZonedDateTime sunrise = Instant.ofEpochSecond(json.getJSONObject("sys").getLong("sunrise"))
|
||||||
.atZone(ZoneId.of("UTC"))
|
.atZone(ZoneId.of("UTC"))
|
||||||
@@ -94,13 +101,22 @@ public class WeatherFetcher {
|
|||||||
.plusSeconds(timezoneShift);
|
.plusSeconds(timezoneShift);
|
||||||
|
|
||||||
return new WeatherTimeData(dateTime, weatherMain, tempCelsius,
|
return new WeatherTimeData(dateTime, weatherMain, tempCelsius,
|
||||||
humidity, windSpeed, sunrise, sunset);
|
humidity, windSpeed, windDeg, sunrise, sunset,
|
||||||
|
pressure, clouds, feelsLikeCelsius, visibility);
|
||||||
|
|
||||||
} catch (RuntimeException ru) {
|
} catch (RuntimeException ru) {
|
||||||
throw ru;
|
throw ru;
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logger.warning("Fehler beim Abrufen von OpenWeatherMap: " + ex.getMessage());
|
logger.warning("Fehler beim Abrufen von OpenWeatherMap: " + ex.getMessage());
|
||||||
throw new RuntimeException("Verbindung oder API-Fehler: " + ex.getMessage(), ex);
|
throw new RuntimeException("Verbindung oder API-Fehler: " + ex.getMessage(), ex);
|
||||||
|
} finally {
|
||||||
|
if (in != null) {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +131,9 @@ public class WeatherFetcher {
|
|||||||
"https://api.openweathermap.org/data/2.5/forecast?q=%s&appid=%s&units=%s",
|
"https://api.openweathermap.org/data/2.5/forecast?q=%s&appid=%s&units=%s",
|
||||||
location, apiKey, effectiveUnits);
|
location, apiKey, effectiveUnits);
|
||||||
|
|
||||||
try (BufferedReader in = new BufferedReader(new InputStreamReader(openConnectionStream(urlString)))) {
|
BufferedReader in = null;
|
||||||
|
try {
|
||||||
|
in = new BufferedReader(new InputStreamReader(openConnectionStream(urlString)));
|
||||||
StringBuilder content = new StringBuilder();
|
StringBuilder content = new StringBuilder();
|
||||||
String inputLine;
|
String inputLine;
|
||||||
while ((inputLine = in.readLine()) != null) {
|
while ((inputLine = in.readLine()) != null) {
|
||||||
@@ -131,6 +149,14 @@ public class WeatherFetcher {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.warning("Fehler beim Abrufen der Wettervorhersage: " + e.getMessage());
|
logger.warning("Fehler beim Abrufen der Wettervorhersage: " + e.getMessage());
|
||||||
throw new RuntimeException("Fehler beim Abrufen der Wettervorhersage: " + e.getMessage(), e);
|
throw new RuntimeException("Fehler beim Abrufen der Wettervorhersage: " + e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
if (in != null) {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,12 +171,24 @@ public class WeatherFetcher {
|
|||||||
int status = connection.getResponseCode();
|
int status = connection.getResponseCode();
|
||||||
if (status != 200) {
|
if (status != 200) {
|
||||||
String err = "(keine Fehlerdetails)";
|
String err = "(keine Fehlerdetails)";
|
||||||
try (BufferedReader errIn = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) {
|
BufferedReader errIn = null;
|
||||||
|
try {
|
||||||
|
errIn = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
String l;
|
String l;
|
||||||
while ((l = errIn.readLine()) != null) sb.append(l);
|
while ((l = errIn.readLine()) != null) sb.append(l);
|
||||||
err = sb.toString();
|
err = sb.toString();
|
||||||
} catch (Exception suppress) {}
|
} catch (Exception suppress) {
|
||||||
|
// Ignore
|
||||||
|
} finally {
|
||||||
|
if (errIn != null) {
|
||||||
|
try {
|
||||||
|
errIn.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
throw new RuntimeException("HTTP-Fehlercode: " + status + " – " + err);
|
throw new RuntimeException("HTTP-Fehlercode: " + status + " – " + err);
|
||||||
}
|
}
|
||||||
return connection.getInputStream();
|
return connection.getInputStream();
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import java.time.ZonedDateTime;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Zentrale Datenklasse für Wetter- und Zeitinformationen.
|
* Zentrale Datenklasse für Wetter- und Zeitinformationen.
|
||||||
* Erweiterung: enthält jetzt auch Luftfeuchtigkeit, Windgeschwindigkeit und Sonnenauf/untergang.
|
* Erweiterung: enthält jetzt auch Luftfeuchtigkeit, Windgeschwindigkeit, Windrichtung,
|
||||||
|
* Sonnenauf/untergang, Luftdruck, Wolkendichte und UV-Index.
|
||||||
*/
|
*/
|
||||||
public class WeatherTimeData {
|
public class WeatherTimeData {
|
||||||
|
|
||||||
@@ -14,24 +15,40 @@ public class WeatherTimeData {
|
|||||||
|
|
||||||
private final int humidity; // Luftfeuchtigkeit in %
|
private final int humidity; // Luftfeuchtigkeit in %
|
||||||
private final double windSpeed; // Windgeschwindigkeit (m/s oder mph)
|
private final double windSpeed; // Windgeschwindigkeit (m/s oder mph)
|
||||||
|
private final double windDeg; // Windrichtung in Grad (0-360)
|
||||||
private final ZonedDateTime sunrise; // Sonnenaufgang
|
private final ZonedDateTime sunrise; // Sonnenaufgang
|
||||||
private final ZonedDateTime sunset; // Sonnenuntergang
|
private final ZonedDateTime sunset; // Sonnenuntergang
|
||||||
|
|
||||||
|
private final int pressure; // Luftdruck in hPa
|
||||||
|
private final int clouds; // Wolkendichte in %
|
||||||
|
private final double feelsLike; // Gefühlte Temperatur in °C
|
||||||
|
private final int visibility; // Sichtweite in Metern
|
||||||
|
|
||||||
public WeatherTimeData(
|
public WeatherTimeData(
|
||||||
ZonedDateTime dateTime,
|
ZonedDateTime dateTime,
|
||||||
String weatherMain,
|
String weatherMain,
|
||||||
double tempCelsius,
|
double tempCelsius,
|
||||||
int humidity,
|
int humidity,
|
||||||
double windSpeed,
|
double windSpeed,
|
||||||
|
double windDeg,
|
||||||
ZonedDateTime sunrise,
|
ZonedDateTime sunrise,
|
||||||
ZonedDateTime sunset) {
|
ZonedDateTime sunset,
|
||||||
|
int pressure,
|
||||||
|
int clouds,
|
||||||
|
double feelsLike,
|
||||||
|
int visibility) {
|
||||||
this.dateTime = dateTime;
|
this.dateTime = dateTime;
|
||||||
this.weatherMain = weatherMain;
|
this.weatherMain = weatherMain;
|
||||||
this.tempCelsius = tempCelsius;
|
this.tempCelsius = tempCelsius;
|
||||||
this.humidity = humidity;
|
this.humidity = humidity;
|
||||||
this.windSpeed = windSpeed;
|
this.windSpeed = windSpeed;
|
||||||
|
this.windDeg = windDeg;
|
||||||
this.sunrise = sunrise;
|
this.sunrise = sunrise;
|
||||||
this.sunset = sunset;
|
this.sunset = sunset;
|
||||||
|
this.pressure = pressure;
|
||||||
|
this.clouds = clouds;
|
||||||
|
this.feelsLike = feelsLike;
|
||||||
|
this.visibility = visibility;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ZonedDateTime getDateTime() {
|
public ZonedDateTime getDateTime() {
|
||||||
@@ -44,7 +61,7 @@ public class WeatherTimeData {
|
|||||||
|
|
||||||
public double getTemp(String unit) {
|
public double getTemp(String unit) {
|
||||||
return "F".equalsIgnoreCase(unit)
|
return "F".equalsIgnoreCase(unit)
|
||||||
? (tempCelsius * 9 / 5) + 32
|
? (tempCelsius * 9.0 / 5.0) + 32.0
|
||||||
: tempCelsius;
|
: tempCelsius;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +73,10 @@ public class WeatherTimeData {
|
|||||||
return windSpeed;
|
return windSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public double getWindDeg() {
|
||||||
|
return windDeg;
|
||||||
|
}
|
||||||
|
|
||||||
public ZonedDateTime getSunrise() {
|
public ZonedDateTime getSunrise() {
|
||||||
return sunrise;
|
return sunrise;
|
||||||
}
|
}
|
||||||
@@ -64,6 +85,62 @@ public class WeatherTimeData {
|
|||||||
return sunset;
|
return sunset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getPressure() {
|
||||||
|
return pressure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getClouds() {
|
||||||
|
return clouds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getFeelsLike(String unit) {
|
||||||
|
return "F".equalsIgnoreCase(unit)
|
||||||
|
? (feelsLike * 9.0 / 5.0) + 32.0
|
||||||
|
: feelsLike;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVisibility() {
|
||||||
|
return visibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Berechnet einen einfachen UV-Index basierend auf Tageszeit, Wolken und Wetter
|
||||||
|
* (0-11+: 0-2=niedrig, 3-5=mäßig, 6-7=hoch, 8-10=sehr hoch, 11+=extrem)
|
||||||
|
*/
|
||||||
|
public int getUVIndex() {
|
||||||
|
int hour = dateTime.getHour();
|
||||||
|
|
||||||
|
// Nachts ist UV-Index 0
|
||||||
|
if (hour < 6 || hour > 20) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basis UV-Index je nach Tageszeit (Maximum mittags)
|
||||||
|
int baseUV;
|
||||||
|
if (hour >= 11 && hour <= 13) {
|
||||||
|
baseUV = 9; // Mittags am höchsten
|
||||||
|
} else if (hour >= 10 && hour <= 14) {
|
||||||
|
baseUV = 7;
|
||||||
|
} else if (hour >= 9 && hour <= 15) {
|
||||||
|
baseUV = 5;
|
||||||
|
} else {
|
||||||
|
baseUV = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reduzierung durch Wolken
|
||||||
|
baseUV = baseUV - (clouds / 20);
|
||||||
|
|
||||||
|
// Reduzierung bei Regen/Schnee/Gewitter
|
||||||
|
if (weatherMain.equalsIgnoreCase("rain") ||
|
||||||
|
weatherMain.equalsIgnoreCase("drizzle") ||
|
||||||
|
weatherMain.equalsIgnoreCase("thunderstorm") ||
|
||||||
|
weatherMain.equalsIgnoreCase("snow")) {
|
||||||
|
baseUV = Math.max(1, baseUV / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.max(0, Math.min(11, baseUV));
|
||||||
|
}
|
||||||
|
|
||||||
public String getFormattedTime(String format) {
|
public String getFormattedTime(String format) {
|
||||||
int hour = dateTime.getHour();
|
int hour = dateTime.getHour();
|
||||||
int minute = dateTime.getMinute();
|
int minute = dateTime.getMinute();
|
||||||
|
|||||||
@@ -4,31 +4,28 @@ import net.kyori.adventure.text.Component;
|
|||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.text.format.TextDecoration;
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.*;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.command.*;
|
import org.bukkit.command.*;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.entity.Snowman;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.inventory.meta.ItemMeta;
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
import org.bukkit.scoreboard.*;
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -38,9 +35,12 @@ import java.time.ZonedDateTime;
|
|||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
// <--- NEU: Einbinden der Hilfsklassen (keine Änderung am bestehenden Code)
|
|
||||||
import dev.viper.weathertime.MetricsManager;
|
import dev.viper.weathertime.MetricsManager;
|
||||||
import dev.viper.weathertime.UpdateChecker;
|
import dev.viper.weathertime.UpdateChecker;
|
||||||
|
import dev.viper.weathertime.DisplayMode;
|
||||||
|
import dev.viper.weathertime.WeatherColors;
|
||||||
|
import dev.viper.weathertime.WindDirection;
|
||||||
|
import dev.viper.weathertime.MoonPhase;
|
||||||
|
|
||||||
public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
||||||
|
|
||||||
@@ -51,17 +51,16 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
private final Map<UUID, Set<String>> playersWithDisplay = new HashMap<>();
|
private final Map<UUID, Set<String>> playersWithDisplay = new HashMap<>();
|
||||||
private final Map<UUID, String> playerLocations = new HashMap<>();
|
private final Map<UUID, String> playerLocations = new HashMap<>();
|
||||||
private final Map<UUID, Inventory> playerGUIs = new HashMap<>();
|
private final Map<UUID, Inventory> playerGUIs = new HashMap<>();
|
||||||
|
private final Map<UUID, Scoreboard> playerScoreboards = new HashMap<>();
|
||||||
|
private final Map<UUID, DisplayMode> playerDisplayModes = new HashMap<>();
|
||||||
private BukkitAudiences audiences;
|
private BukkitAudiences audiences;
|
||||||
private BukkitRunnable weatherUpdateTask;
|
private BukkitRunnable weatherUpdateTask;
|
||||||
private BukkitRunnable syncTask;
|
private BukkitRunnable syncTask;
|
||||||
private final Set<String> processedLocations = new HashSet<>();
|
private final Set<String> processedLocations = new HashSet<>();
|
||||||
private FileConfiguration langConfig;
|
private FileConfiguration langConfig;
|
||||||
|
|
||||||
// NEU: bStats & Updater-Felder
|
|
||||||
private MetricsManager metricsManager;
|
private MetricsManager metricsManager;
|
||||||
private UpdateChecker updateChecker;
|
private UpdateChecker updateChecker;
|
||||||
|
|
||||||
// Variable, um die aktuell bekannte neue Version zu speichern
|
|
||||||
private String latestVersion = null;
|
private String latestVersion = null;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -71,25 +70,19 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
loadConfig();
|
loadConfig();
|
||||||
audiences = BukkitAudiences.create(this);
|
audiences = BukkitAudiences.create(this);
|
||||||
|
|
||||||
// bStats initialisieren
|
|
||||||
metricsManager = new MetricsManager(this);
|
metricsManager = new MetricsManager(this);
|
||||||
|
|
||||||
// Spigot UpdateChecker initialisieren (Resource-ID)
|
|
||||||
updateChecker = new UpdateChecker(this, 127846);
|
updateChecker = new UpdateChecker(this, 127846);
|
||||||
updateChecker.getLatestVersion(version -> {
|
updateChecker.getLatestVersion(version -> {
|
||||||
// Version bereinigen: nur Zahlen und Punkte
|
|
||||||
String cleanVersion = version.replaceAll("[^0-9.]", "").trim();
|
String cleanVersion = version.replaceAll("[^0-9.]", "").trim();
|
||||||
String currentVersion = getDescription().getVersion();
|
String currentVersion = getDescription().getVersion();
|
||||||
|
|
||||||
// Nur dann melden, wenn cleanVersion wirklich neuer ist
|
|
||||||
if (isVersionNewer(currentVersion, cleanVersion)) {
|
if (isVersionNewer(currentVersion, cleanVersion)) {
|
||||||
latestVersion = cleanVersion; // Neue Version merken
|
latestVersion = cleanVersion;
|
||||||
|
|
||||||
// Konsolen-Info
|
|
||||||
getLogger().info("Neue Version verfügbar: " + cleanVersion + " (aktuell: " + currentVersion + ")");
|
getLogger().info("Neue Version verfügbar: " + cleanVersion + " (aktuell: " + currentVersion + ")");
|
||||||
getLogger().info("Download: https://www.spigotmc.org/resources/127846/");
|
getLogger().info("Download: https://www.spigotmc.org/resources/127846/");
|
||||||
|
|
||||||
// Ingame-Info an alle aktuell online Operatoren
|
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
if (player.isOp()) {
|
if (player.isOp()) {
|
||||||
player.sendMessage("§aEine neue Version von §eRealTimeWeather §aist verfügbar: §e"
|
player.sendMessage("§aEine neue Version von §eRealTimeWeather §aist verfügbar: §e"
|
||||||
@@ -111,9 +104,13 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
startWeatherUpdateTask();
|
startWeatherUpdateTask();
|
||||||
startSyncTask();
|
startSyncTask();
|
||||||
initializePlayerDisplays();
|
initializePlayerDisplays();
|
||||||
|
|
||||||
|
getLogger().info("==============================================");
|
||||||
|
getLogger().info("RealTimeWeather nutzt SCOREBOARD-Anzeige!");
|
||||||
|
getLogger().info("Die Wetteranzeige erscheint rechts am Bildschirm.");
|
||||||
|
getLogger().info("==============================================");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Methode zum Versionsvergleich, damit nur wirklich neuere Versionen gemeldet werden
|
|
||||||
private boolean isVersionNewer(String current, String latest) {
|
private boolean isVersionNewer(String current, String latest) {
|
||||||
String[] curParts = current.split("\\.");
|
String[] curParts = current.split("\\.");
|
||||||
String[] latParts = latest.split("\\.");
|
String[] latParts = latest.split("\\.");
|
||||||
@@ -124,16 +121,15 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
int latNum = i < latParts.length ? Integer.parseInt(latParts[i]) : 0;
|
int latNum = i < latParts.length ? Integer.parseInt(latParts[i]) : 0;
|
||||||
|
|
||||||
if (latNum > curNum) {
|
if (latNum > curNum) {
|
||||||
return true; // neuere Version gefunden
|
return true;
|
||||||
}
|
}
|
||||||
if (latNum < curNum) {
|
if (latNum < curNum) {
|
||||||
return false; // keine neuere Version
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false; // Versionen sind gleich
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event Listener für Join-Nachricht
|
|
||||||
public class UpdateNotifyListener implements Listener {
|
public class UpdateNotifyListener implements Listener {
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@@ -155,10 +151,12 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
if (audiences != null) audiences.close();
|
if (audiences != null) audiences.close();
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
if (playerGUIs.containsKey(player.getUniqueId())) player.closeInventory();
|
if (playerGUIs.containsKey(player.getUniqueId())) player.closeInventory();
|
||||||
|
if (playerScoreboards.containsKey(player.getUniqueId())) {
|
||||||
|
player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============== Config & Sprache ===============
|
|
||||||
private void loadConfig() {
|
private void loadConfig() {
|
||||||
FileConfiguration cfg = getConfig();
|
FileConfiguration cfg = getConfig();
|
||||||
apiKey = cfg.getString("api-key", "").trim();
|
apiKey = cfg.getString("api-key", "").trim();
|
||||||
@@ -219,7 +217,13 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
private void setDoDaylightCycleForWorlds() {
|
private void setDoDaylightCycleForWorlds() {
|
||||||
for (World world : Bukkit.getWorlds()) {
|
for (World world : Bukkit.getWorlds()) {
|
||||||
WorldConfig config = worldConfigs.getOrDefault(world.getName(), worldConfigs.get("defaults"));
|
WorldConfig config = worldConfigs.getOrDefault(world.getName(), worldConfigs.get("defaults"));
|
||||||
if (config.enabled) world.setGameRuleValue("doDaylightCycle", "false");
|
if (config.enabled) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
GameRule<Boolean> doDaylightCycle = (GameRule<Boolean>) GameRule.getByName("doDaylightCycle");
|
||||||
|
if (doDaylightCycle != null) {
|
||||||
|
world.setGameRule(doDaylightCycle, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,6 +236,7 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
if (config.enabled && config.displayActionbar) worlds.add(world.getName());
|
if (config.enabled && config.displayActionbar) worlds.add(world.getName());
|
||||||
}
|
}
|
||||||
playersWithDisplay.put(player.getUniqueId(), worlds);
|
playersWithDisplay.put(player.getUniqueId(), worlds);
|
||||||
|
createScoreboardForPlayer(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,7 +261,7 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
WeatherTimeData data = worldWeatherData.get(world.getName());
|
WeatherTimeData data = worldWeatherData.get(world.getName());
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
syncMinecraftTime(world, data.getDateTime());
|
syncMinecraftTime(world, data.getDateTime());
|
||||||
updateActionbarForWorld(world, data);
|
updateScoreboardForWorld(world, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,6 +272,7 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
private void updateWeatherDataForAllWorlds() {
|
private void updateWeatherDataForAllWorlds() {
|
||||||
for (World world : Bukkit.getWorlds()) {
|
for (World world : Bukkit.getWorlds()) {
|
||||||
WorldConfig config = worldConfigs.getOrDefault(world.getName(), worldConfigs.get("defaults"));
|
WorldConfig config = worldConfigs.getOrDefault(world.getName(), worldConfigs.get("defaults"));
|
||||||
|
|
||||||
if (!config.enabled) {
|
if (!config.enabled) {
|
||||||
worldWeatherData.remove(world.getName());
|
worldWeatherData.remove(world.getName());
|
||||||
continue;
|
continue;
|
||||||
@@ -308,13 +314,8 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
case "snow":
|
case "snow":
|
||||||
world.setStorm(true);
|
world.setStorm(true);
|
||||||
world.setThundering(false);
|
world.setThundering(false);
|
||||||
|
|
||||||
// ---- FAKE-SCHNEE ----
|
|
||||||
spawnTemporarySnowInWorld(world, WeatherTimeSyncPlugin.this);
|
spawnTemporarySnowInWorld(world, WeatherTimeSyncPlugin.this);
|
||||||
|
|
||||||
// ---- Schneemänner, temporär spawnen (z.B. 25 Stück) ----
|
|
||||||
spawnTemporarySnowmen(world, 25, WeatherTimeSyncPlugin.this);
|
spawnTemporarySnowmen(world, 25, WeatherTimeSyncPlugin.this);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
world.setStorm(false);
|
world.setStorm(false);
|
||||||
@@ -330,85 +331,77 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void spawnTemporarySnowInWorld(World world, JavaPlugin plugin) {
|
||||||
* Fake-Schnee auf allen aktuell geladenen Chunks platzieren
|
List<Block> snowBlocks = new ArrayList<>();
|
||||||
*/
|
|
||||||
private void spawnTemporarySnowInWorld(World world, JavaPlugin plugin) {
|
|
||||||
List<Block> snowBlocks = new ArrayList<>();
|
|
||||||
|
|
||||||
for (org.bukkit.Chunk chunk : world.getLoadedChunks()) {
|
for (org.bukkit.Chunk chunk : world.getLoadedChunks()) {
|
||||||
int chunkX = chunk.getX() << 4;
|
int chunkX = chunk.getX() << 4;
|
||||||
int chunkZ = chunk.getZ() << 4;
|
int chunkZ = chunk.getZ() << 4;
|
||||||
|
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
if (Math.random() > 0.7) continue;
|
if (Math.random() > 0.7) continue;
|
||||||
int worldX = chunkX + x;
|
int worldX = chunkX + x;
|
||||||
int worldZ = chunkZ + z;
|
int worldZ = chunkZ + z;
|
||||||
int worldY = world.getHighestBlockYAt(worldX, worldZ);
|
int worldY = world.getHighestBlockYAt(worldX, worldZ);
|
||||||
|
|
||||||
Block ground = world.getBlockAt(worldX, worldY - 1, worldZ);
|
Block ground = world.getBlockAt(worldX, worldY - 1, worldZ);
|
||||||
Block above = world.getBlockAt(worldX, worldY, worldZ);
|
Block above = world.getBlockAt(worldX, worldY, worldZ);
|
||||||
|
|
||||||
if (ground.getType().isSolid() && above.getType() == Material.AIR) {
|
if (ground.getType().isSolid() && above.getType() == Material.AIR) {
|
||||||
above.setType(Material.SNOW);
|
above.setType(Material.SNOW);
|
||||||
snowBlocks.add(above);
|
snowBlocks.add(above);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schnee entfernen
|
|
||||||
new BukkitRunnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
for (Block b : snowBlocks) {
|
|
||||||
if (b.getType() == Material.SNOW) {
|
|
||||||
b.setType(Material.AIR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.runTaskLater(plugin, 180 * 20L); // 3 Minuten bleibt der Schnee liegen
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
new BukkitRunnable() {
|
||||||
* Spawn temporärer Schneemänner in geladenen Chunks
|
@Override
|
||||||
*/
|
public void run() {
|
||||||
private void spawnTemporarySnowmen(World world, int count, JavaPlugin plugin) {
|
for (Block b : snowBlocks) {
|
||||||
List<org.bukkit.entity.Snowman> snowmen = new ArrayList<>();
|
if (b.getType() == Material.SNOW) {
|
||||||
Random random = new Random();
|
b.setType(Material.AIR);
|
||||||
|
}
|
||||||
List<org.bukkit.Chunk> loadedChunks = Arrays.asList(world.getLoadedChunks());
|
|
||||||
|
|
||||||
for (int i = 0; i < count; i++) {
|
|
||||||
if (loadedChunks.isEmpty()) break;
|
|
||||||
org.bukkit.Chunk chunk = loadedChunks.get(random.nextInt(loadedChunks.size()));
|
|
||||||
|
|
||||||
int chunkX = chunk.getX() << 4;
|
|
||||||
int chunkZ = chunk.getZ() << 4;
|
|
||||||
int x = chunkX + random.nextInt(16);
|
|
||||||
int z = chunkZ + random.nextInt(16);
|
|
||||||
int y = world.getHighestBlockYAt(x, z);
|
|
||||||
|
|
||||||
if (world.getBlockAt(x, y - 1, z).getType().isSolid()) {
|
|
||||||
org.bukkit.entity.Snowman snowman = (org.bukkit.entity.Snowman)
|
|
||||||
world.spawnEntity(new org.bukkit.Location(world, x + 0.5, y, z + 0.5),
|
|
||||||
org.bukkit.entity.EntityType.SNOW_GOLEM);
|
|
||||||
snowmen.add(snowman);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}.runTaskLater(plugin, 180 * 20L);
|
||||||
|
}
|
||||||
|
|
||||||
// Schneemänner nach 30 Sekunden wieder entfernen
|
private void spawnTemporarySnowmen(World world, int count, JavaPlugin plugin) {
|
||||||
new BukkitRunnable() {
|
List<Snowman> snowmen = new ArrayList<>();
|
||||||
@Override
|
Random random = new Random();
|
||||||
public void run() {
|
|
||||||
for (org.bukkit.entity.Snowman s : snowmen) {
|
List<org.bukkit.Chunk> loadedChunks = Arrays.asList(world.getLoadedChunks());
|
||||||
if (!s.isDead()) s.remove();
|
|
||||||
}
|
for (int i = 0; i < count; i++) {
|
||||||
}
|
if (loadedChunks.isEmpty()) break;
|
||||||
}.runTaskLater(plugin, 180 * 20L);
|
org.bukkit.Chunk chunk = loadedChunks.get(random.nextInt(loadedChunks.size()));
|
||||||
|
|
||||||
|
int chunkX = chunk.getX() << 4;
|
||||||
|
int chunkZ = chunk.getZ() << 4;
|
||||||
|
int x = chunkX + random.nextInt(16);
|
||||||
|
int z = chunkZ + random.nextInt(16);
|
||||||
|
int y = world.getHighestBlockYAt(x, z);
|
||||||
|
|
||||||
|
if (world.getBlockAt(x, y - 1, z).getType().isSolid()) {
|
||||||
|
Snowman snowman = (Snowman) world.spawnEntity(
|
||||||
|
new Location(world, x + 0.5, y, z + 0.5),
|
||||||
|
EntityType.SNOW_GOLEM
|
||||||
|
);
|
||||||
|
snowmen.add(snowman);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new BukkitRunnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (Snowman s : snowmen) {
|
||||||
|
if (!s.isDead()) s.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.runTaskLater(plugin, 180 * 20L);
|
||||||
|
}
|
||||||
|
|
||||||
private void syncMinecraftTime(World world, ZonedDateTime dateTime) {
|
private void syncMinecraftTime(World world, ZonedDateTime dateTime) {
|
||||||
int hour = dateTime.getHour();
|
int hour = dateTime.getHour();
|
||||||
@@ -416,17 +409,56 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
int second = dateTime.getSecond();
|
int second = dateTime.getSecond();
|
||||||
int minecraftTime = ((hour + 18) % 24) * 1000 + (minute * 1000 / 60) + (second * 1000 / 3600);
|
int minecraftTime = ((hour + 18) % 24) * 1000 + (minute * 1000 / 60) + (second * 1000 / 3600);
|
||||||
world.setTime(minecraftTime);
|
world.setTime(minecraftTime);
|
||||||
world.setGameRuleValue("doDaylightCycle", "false");
|
@SuppressWarnings("unchecked")
|
||||||
|
GameRule<Boolean> doDaylightCycle = (GameRule<Boolean>) GameRule.getByName("doDaylightCycle");
|
||||||
|
if (doDaylightCycle != null) {
|
||||||
|
world.setGameRule(doDaylightCycle, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// === Anzeige (Actionbar, jetzt mit Luftfeuchtigkeit, Wind, Sonne) ===
|
private void createScoreboardForPlayer(Player player) {
|
||||||
private void updateActionbarForWorld(World world, WeatherTimeData data) {
|
Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
|
||||||
|
Objective objective = scoreboard.registerNewObjective("weather", "dummy",
|
||||||
|
ChatColor.GOLD + "" + ChatColor.BOLD + "⛅ Wetter Info");
|
||||||
|
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
|
||||||
|
|
||||||
|
player.setScoreboard(scoreboard);
|
||||||
|
playerScoreboards.put(player.getUniqueId(), scoreboard);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateScoreboardForWorld(World world, WeatherTimeData data) {
|
||||||
WorldConfig config = worldConfigs.getOrDefault(world.getName(), worldConfigs.get("defaults"));
|
WorldConfig config = worldConfigs.getOrDefault(world.getName(), worldConfigs.get("defaults"));
|
||||||
if (!config.enabled || !config.displayActionbar) return;
|
|
||||||
|
if (!config.enabled || !config.displayActionbar) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (Player player : world.getPlayers()) {
|
for (Player player : world.getPlayers()) {
|
||||||
if (!playersWithDisplay.getOrDefault(player.getUniqueId(), new HashSet<>()).contains(world.getName()))
|
Set<String> displayWorlds = playersWithDisplay.getOrDefault(player.getUniqueId(), new HashSet<>());
|
||||||
|
|
||||||
|
if (!displayWorlds.contains(world.getName())) {
|
||||||
|
// Scoreboard entfernen wenn disabled
|
||||||
|
Scoreboard scoreboard = playerScoreboards.get(player.getUniqueId());
|
||||||
|
if (scoreboard != null) {
|
||||||
|
player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
|
||||||
|
playerScoreboards.remove(player.getUniqueId());
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scoreboard scoreboard = playerScoreboards.get(player.getUniqueId());
|
||||||
|
if (scoreboard == null) {
|
||||||
|
createScoreboardForPlayer(player);
|
||||||
|
scoreboard = playerScoreboards.get(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
Objective objective = scoreboard.getObjective("weather");
|
||||||
|
if (objective == null) continue;
|
||||||
|
|
||||||
|
// Alte Scores löschen
|
||||||
|
for (String entry : scoreboard.getEntries()) {
|
||||||
|
scoreboard.resetScores(entry);
|
||||||
|
}
|
||||||
|
|
||||||
WeatherTimeData playerData = data;
|
WeatherTimeData playerData = data;
|
||||||
String location = playerLocations.getOrDefault(player.getUniqueId(), "");
|
String location = playerLocations.getOrDefault(player.getUniqueId(), "");
|
||||||
@@ -435,43 +467,125 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
WeatherFetcher fetcher = new WeatherFetcher(apiKey, location, config.units, getLogger());
|
WeatherFetcher fetcher = new WeatherFetcher(apiKey, location, config.units, getLogger());
|
||||||
playerData = fetcher.fetchAsWeatherTimeData();
|
playerData = fetcher.fetchAsWeatherTimeData();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
String countryCode = getCountryCode(config.location);
|
|
||||||
audiences.player(player).sendMessage(Component.text(
|
|
||||||
getLocalizedMessage("forecast_error", countryCode,
|
|
||||||
"location", location,
|
|
||||||
"error", e.getMessage()),
|
|
||||||
NamedTextColor.RED));
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Display Mode des Spielers
|
||||||
|
DisplayMode mode = playerDisplayModes.getOrDefault(player.getUniqueId(), DisplayMode.STANDARD);
|
||||||
|
|
||||||
|
// Daten vorbereiten
|
||||||
String dateStr = playerData.getDateTime().format(DateTimeFormatter.ofPattern("dd.MM.yyyy"));
|
String dateStr = playerData.getDateTime().format(DateTimeFormatter.ofPattern("dd.MM.yyyy"));
|
||||||
String timeStr = playerData.getFormattedTime(config.timeFormat);
|
String timeStr = playerData.getFormattedTime(config.timeFormat);
|
||||||
String tempUnit = config.units.equalsIgnoreCase("metric") ? "°C" : "°F";
|
String tempUnit = config.units.equalsIgnoreCase("metric") ? "°C" : "°F";
|
||||||
String weatherIcon = config.displayWeatherIcon ? getWeatherSymbol(playerData.getWeatherMain()) + " " : "";
|
String weatherIcon = getWeatherSymbol(playerData.getWeatherMain());
|
||||||
String tempStr = String.format("%.1f%s", playerData.getTemp(config.units.equalsIgnoreCase("metric") ? "C" : "F"), tempUnit);
|
String weatherMain = getLocalizedWeatherMain(playerData.getWeatherMain(), getCountryCode(config.location));
|
||||||
|
double temp = playerData.getTemp(config.units.equalsIgnoreCase("metric") ? "C" : "F");
|
||||||
|
double tempCelsius = playerData.getTemp("C");
|
||||||
|
String cityName = config.location.split(",")[0];
|
||||||
|
|
||||||
String humidityStr = "💧 " + playerData.getHumidity() + "%";
|
// Farben basierend auf Werten
|
||||||
String windStr = "🌬️ " + String.format("%.1f", playerData.getWindSpeed()) + (config.units.equalsIgnoreCase("metric") ? " m/s" : " mph");
|
ChatColor tempColor = WeatherColors.getTemperatureColor(tempCelsius);
|
||||||
String sunriseStr = "🌅 " + playerData.getSunrise().format(DateTimeFormatter.ofPattern("HH:mm"));
|
ChatColor weatherColor = WeatherColors.getWeatherColor(playerData.getWeatherMain());
|
||||||
String sunsetStr = "🌇 " + playerData.getSunset().format(DateTimeFormatter.ofPattern("HH:mm"));
|
ChatColor humidityColor = WeatherColors.getHumidityColor(playerData.getHumidity());
|
||||||
|
ChatColor windColor = WeatherColors.getWindSpeedColor(playerData.getWindSpeed());
|
||||||
|
|
||||||
Component message = Component.text()
|
// Trennlinie
|
||||||
.append(Component.text(dateStr + " ", NamedTextColor.AQUA, TextDecoration.BOLD))
|
String separator = ChatColor.DARK_GRAY + "~" + ChatColor.GRAY + "~" + ChatColor.DARK_GRAY + "~" +
|
||||||
.append(Component.text("| " + timeStr + " ", NamedTextColor.YELLOW))
|
ChatColor.GRAY + "~" + ChatColor.DARK_GRAY + "~" + ChatColor.GRAY + "~" +
|
||||||
.append(Component.text("| " + weatherIcon, NamedTextColor.WHITE))
|
ChatColor.DARK_GRAY + "~" + ChatColor.GRAY + "~" + ChatColor.DARK_GRAY + "~";
|
||||||
.append(Component.text("| " + tempStr + " ", NamedTextColor.GREEN))
|
|
||||||
.append(Component.text("| " + humidityStr + " ", NamedTextColor.AQUA))
|
|
||||||
.append(Component.text("| " + windStr + " ", NamedTextColor.GRAY))
|
|
||||||
.append(Component.text("| " + sunriseStr + " ", NamedTextColor.GOLD))
|
|
||||||
.append(Component.text("| " + sunsetStr, NamedTextColor.DARK_RED))
|
|
||||||
.build();
|
|
||||||
|
|
||||||
audiences.player(player).sendActionBar(message);
|
int line = 20;
|
||||||
|
|
||||||
|
// === KOMPAKT MODE ===
|
||||||
|
if (mode == DisplayMode.COMPACT) {
|
||||||
|
objective.getScore(" ").setScore(line--);
|
||||||
|
objective.getScore(ChatColor.AQUA + "📅 " + dateStr + " " + ChatColor.YELLOW + timeStr).setScore(line--);
|
||||||
|
objective.getScore(separator + "1").setScore(line--);
|
||||||
|
objective.getScore(weatherColor + weatherIcon + " " + ChatColor.GRAY + weatherMain).setScore(line--);
|
||||||
|
objective.getScore(tempColor + "🌡 " + String.format("%.1f%s", temp, tempUnit)).setScore(line--);
|
||||||
|
objective.getScore(separator + "2").setScore(line--);
|
||||||
|
objective.getScore(ChatColor.DARK_AQUA + "📍 " + cityName).setScore(line--);
|
||||||
|
objective.getScore(" ").setScore(line--);
|
||||||
|
}
|
||||||
|
// === STANDARD MODE ===
|
||||||
|
else if (mode == DisplayMode.STANDARD) {
|
||||||
|
objective.getScore(" ").setScore(line--);
|
||||||
|
objective.getScore(ChatColor.AQUA + "📅 " + dateStr).setScore(line--);
|
||||||
|
objective.getScore(ChatColor.YELLOW + "🕐 " + timeStr).setScore(line--);
|
||||||
|
objective.getScore(separator + "1").setScore(line--);
|
||||||
|
objective.getScore(weatherColor + weatherIcon + " " + ChatColor.GRAY + weatherMain).setScore(line--);
|
||||||
|
objective.getScore(tempColor + "🌡 " + String.format("%.1f%s", temp, tempUnit)).setScore(line--);
|
||||||
|
objective.getScore(humidityColor + "💧 " + playerData.getHumidity() + "%").setScore(line--);
|
||||||
|
|
||||||
|
// Windrichtung mit Pfeil
|
||||||
|
String windDir = WindDirection.getDirection(playerData.getWindDeg());
|
||||||
|
String windArrow = WindDirection.getArrow(playerData.getWindDeg());
|
||||||
|
objective.getScore(windColor + "🌬 " + String.format("%.1f", playerData.getWindSpeed()) +
|
||||||
|
(config.units.equalsIgnoreCase("metric") ? " m/s " : " mph ") + windArrow + " " + windDir).setScore(line--);
|
||||||
|
|
||||||
|
objective.getScore(separator + "2").setScore(line--);
|
||||||
|
objective.getScore(ChatColor.GOLD + "🌅 " + playerData.getSunrise().format(DateTimeFormatter.ofPattern("HH:mm"))).setScore(line--);
|
||||||
|
objective.getScore(ChatColor.DARK_RED + "🌇 " + playerData.getSunset().format(DateTimeFormatter.ofPattern("HH:mm"))).setScore(line--);
|
||||||
|
|
||||||
|
// Mondphase
|
||||||
|
objective.getScore(ChatColor.LIGHT_PURPLE + MoonPhase.getEmoji(world) + " " + MoonPhase.getName(world)).setScore(line--);
|
||||||
|
|
||||||
|
objective.getScore(separator + "3").setScore(line--);
|
||||||
|
objective.getScore(ChatColor.DARK_AQUA + "📍 " + cityName).setScore(line--);
|
||||||
|
objective.getScore(" ").setScore(line--);
|
||||||
|
}
|
||||||
|
// === DETAILLIERT MODE ===
|
||||||
|
else if (mode == DisplayMode.DETAILED) {
|
||||||
|
objective.getScore(" ").setScore(line--);
|
||||||
|
objective.getScore(ChatColor.AQUA + "📅 " + dateStr).setScore(line--);
|
||||||
|
objective.getScore(ChatColor.YELLOW + "🕐 " + timeStr).setScore(line--);
|
||||||
|
objective.getScore(separator + "1").setScore(line--);
|
||||||
|
objective.getScore(weatherColor + weatherIcon + " " + ChatColor.GRAY + weatherMain).setScore(line--);
|
||||||
|
objective.getScore(tempColor + "🌡 " + String.format("%.1f%s", temp, tempUnit)).setScore(line--);
|
||||||
|
|
||||||
|
// Gefühlte Temperatur
|
||||||
|
double feelsLike = playerData.getFeelsLike(config.units.equalsIgnoreCase("metric") ? "C" : "F");
|
||||||
|
ChatColor feelsLikeColor = WeatherColors.getTemperatureColor(playerData.getFeelsLike("C"));
|
||||||
|
objective.getScore(feelsLikeColor + "🌡️ Gefühlt: " + String.format("%.1f%s", feelsLike, tempUnit)).setScore(line--);
|
||||||
|
|
||||||
|
objective.getScore(humidityColor + "💧 " + playerData.getHumidity() + "%").setScore(line--);
|
||||||
|
|
||||||
|
// Windrichtung mit Pfeil
|
||||||
|
String windDir = WindDirection.getDirection(playerData.getWindDeg());
|
||||||
|
String windArrow = WindDirection.getArrow(playerData.getWindDeg());
|
||||||
|
objective.getScore(windColor + "🌬 " + String.format("%.1f", playerData.getWindSpeed()) +
|
||||||
|
(config.units.equalsIgnoreCase("metric") ? " m/s " : " mph ") + windArrow + " " + windDir).setScore(line--);
|
||||||
|
|
||||||
|
// Luftdruck
|
||||||
|
objective.getScore(ChatColor.GRAY + "📊 " + playerData.getPressure() + " hPa").setScore(line--);
|
||||||
|
|
||||||
|
// Wolkendichte
|
||||||
|
objective.getScore(ChatColor.WHITE + "☁️ Wolken: " + playerData.getClouds() + "%").setScore(line--);
|
||||||
|
|
||||||
|
// Sichtweite
|
||||||
|
int visKm = playerData.getVisibility() / 1000;
|
||||||
|
objective.getScore(ChatColor.BLUE + "👁️ Sicht: " + visKm + " km").setScore(line--);
|
||||||
|
|
||||||
|
// UV-Index
|
||||||
|
int uvIndex = playerData.getUVIndex();
|
||||||
|
ChatColor uvColor = WeatherColors.getUVIndexColor(uvIndex);
|
||||||
|
objective.getScore(uvColor + "☀️ UV: " + uvIndex).setScore(line--);
|
||||||
|
|
||||||
|
objective.getScore(separator + "2").setScore(line--);
|
||||||
|
objective.getScore(ChatColor.GOLD + "🌅 " + playerData.getSunrise().format(DateTimeFormatter.ofPattern("HH:mm"))).setScore(line--);
|
||||||
|
objective.getScore(ChatColor.DARK_RED + "🌇 " + playerData.getSunset().format(DateTimeFormatter.ofPattern("HH:mm"))).setScore(line--);
|
||||||
|
|
||||||
|
// Mondphase
|
||||||
|
objective.getScore(ChatColor.LIGHT_PURPLE + MoonPhase.getPhase(world)).setScore(line--);
|
||||||
|
|
||||||
|
objective.getScore(separator + "3").setScore(line--);
|
||||||
|
objective.getScore(ChatColor.DARK_AQUA + "📍 " + cityName).setScore(line--);
|
||||||
|
objective.getScore(" ").setScore(line--);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// === Events (z.B. Weltwechsel) ===
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerChangedWorld(PlayerChangedWorldEvent event) {
|
public void onPlayerChangedWorld(PlayerChangedWorldEvent event) {
|
||||||
Player player = event.getPlayer();
|
Player player = event.getPlayer();
|
||||||
@@ -485,7 +599,21 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
String tempUnit = config.units.equalsIgnoreCase("metric") ? "°C" : "°F";
|
String tempUnit = config.units.equalsIgnoreCase("metric") ? "°C" : "°F";
|
||||||
String city = config.location.split(",")[0];
|
String city = config.location.split(",")[0];
|
||||||
String message = String.format("%s: %s, %.1f%s", city, localizedWeather, data.getTemp(config.units.equalsIgnoreCase("metric") ? "C" : "F"), tempUnit);
|
String message = String.format("%s: %s, %.1f%s", city, localizedWeather, data.getTemp(config.units.equalsIgnoreCase("metric") ? "C" : "F"), tempUnit);
|
||||||
audiences.player(player).sendActionBar(Component.text(message, NamedTextColor.GREEN));
|
player.sendMessage(ChatColor.GREEN + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onPlayerJoinForDisplay(PlayerJoinEvent event) {
|
||||||
|
Player player = event.getPlayer();
|
||||||
|
Set<String> worlds = new HashSet<>();
|
||||||
|
for (World world : Bukkit.getWorlds()) {
|
||||||
|
WorldConfig config = worldConfigs.getOrDefault(world.getName(), worldConfigs.get("defaults"));
|
||||||
|
if (config.enabled && config.displayActionbar) {
|
||||||
|
worlds.add(world.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
playersWithDisplay.put(player.getUniqueId(), worlds);
|
||||||
|
createScoreboardForPlayer(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
@@ -521,7 +649,7 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
new WeatherForecastCommand().onCommand(player, null, "weatherforecast", new String[]{});
|
new WeatherForecastCommand().onCommand(player, null, "weatherforecast", new String[]{});
|
||||||
} else if (clickedItem.getType() == Material.OAK_SIGN) {
|
} else if (clickedItem.getType() == Material.OAK_SIGN) {
|
||||||
player.closeInventory();
|
player.closeInventory();
|
||||||
String infoMessage = "RealTimeWeather Plugin\nVersion: 1.2\nAutor: M_Viper\nGetestete Minecraft-Version: 1.21.1 - 1.21.8";
|
String infoMessage = "RealTimeWeather Plugin\nVersion: 1.3\nAutor: M_Viper\nGetestete Minecraft-Version: 1.21.1 - 1.21.11";
|
||||||
audiences.player(player).sendMessage(Component.text(infoMessage, NamedTextColor.AQUA));
|
audiences.player(player).sendMessage(Component.text(infoMessage, NamedTextColor.AQUA));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -531,8 +659,6 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
playerGUIs.remove(event.getPlayer().getUniqueId());
|
playerGUIs.remove(event.getPlayer().getUniqueId());
|
||||||
}
|
}
|
||||||
|
|
||||||
// === Hilfsmethoden & Modellklassen ===
|
|
||||||
|
|
||||||
private String getLocalizedMessage(String key, String countryCode, String... placeholders) {
|
private String getLocalizedMessage(String key, String countryCode, String... placeholders) {
|
||||||
String path = "languages." + (countryCode.isEmpty() ? "en" : countryCode.toLowerCase()) + "." + key;
|
String path = "languages." + (countryCode.isEmpty() ? "en" : countryCode.toLowerCase()) + "." + key;
|
||||||
String message = langConfig.getString(path);
|
String message = langConfig.getString(path);
|
||||||
@@ -610,7 +736,6 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
return inv;
|
return inv;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==== PlayerConfig etc. wie gehabt ====
|
|
||||||
private class PlayerConfig {
|
private class PlayerConfig {
|
||||||
private final File configFile;
|
private final File configFile;
|
||||||
private final FileConfiguration config;
|
private final FileConfiguration config;
|
||||||
@@ -633,7 +758,6 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==== Commands ====
|
|
||||||
private class WetterCommand implements CommandExecutor {
|
private class WetterCommand implements CommandExecutor {
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||||
@@ -659,6 +783,9 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
.append(Component.text("/wetter query", NamedTextColor.YELLOW))
|
.append(Component.text("/wetter query", NamedTextColor.YELLOW))
|
||||||
.append(Component.text(" - " + getLocalizedMessage("help_query", countryCode), NamedTextColor.WHITE))
|
.append(Component.text(" - " + getLocalizedMessage("help_query", countryCode), NamedTextColor.WHITE))
|
||||||
.append(Component.newline())
|
.append(Component.newline())
|
||||||
|
.append(Component.text("/wetter mode <compact|standard|detailed>", NamedTextColor.YELLOW))
|
||||||
|
.append(Component.text(" - Anzeigemodus wechseln", NamedTextColor.WHITE))
|
||||||
|
.append(Component.newline())
|
||||||
.append(Component.text("/wetter info", NamedTextColor.YELLOW))
|
.append(Component.text("/wetter info", NamedTextColor.YELLOW))
|
||||||
.append(Component.text(" - " + getLocalizedMessage("help_info", countryCode), NamedTextColor.WHITE))
|
.append(Component.text(" - " + getLocalizedMessage("help_info", countryCode), NamedTextColor.WHITE))
|
||||||
.append(Component.newline())
|
.append(Component.newline())
|
||||||
@@ -756,7 +883,7 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case "info": {
|
case "info": {
|
||||||
String infoMessage = "RealTimeWeather Plugin\nVersion: 1.0\nAutor: M_Viper\nGetestete Minecraft-Version: 1.21.1 - 1.21.8";
|
String infoMessage = "RealTimeWeather Plugin\nVersion: 1.3\nAutor: M_Viper\nGetestete Minecraft-Version: 1.21.1 - 1.21.11\n\nDie Wetteranzeige erscheint als SCOREBOARD rechts am Bildschirm.";
|
||||||
audiences.sender(sender).sendMessage(Component.text(infoMessage, NamedTextColor.AQUA));
|
audiences.sender(sender).sendMessage(Component.text(infoMessage, NamedTextColor.AQUA));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -775,6 +902,31 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
guiPlayer.openInventory(createWeatherGUI(guiPlayer));
|
guiPlayer.openInventory(createWeatherGUI(guiPlayer));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case "mode": {
|
||||||
|
if (!(sender instanceof Player)) {
|
||||||
|
audiences.sender(sender).sendMessage(Component.text("Nur für Spieler", NamedTextColor.RED));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Player modePlayer = (Player) sender;
|
||||||
|
|
||||||
|
if (args.length != 2) {
|
||||||
|
DisplayMode currentMode = playerDisplayModes.getOrDefault(modePlayer.getUniqueId(), DisplayMode.STANDARD);
|
||||||
|
modePlayer.sendMessage(ChatColor.YELLOW + "Aktueller Anzeigemodus: " + ChatColor.GREEN + currentMode.getDisplayName());
|
||||||
|
modePlayer.sendMessage(ChatColor.GRAY + "Verwendung: /wetter mode <compact|standard|detailed>");
|
||||||
|
modePlayer.sendMessage(ChatColor.GRAY + "- " + ChatColor.AQUA + "compact" + ChatColor.GRAY + ": Minimale Anzeige");
|
||||||
|
modePlayer.sendMessage(ChatColor.GRAY + "- " + ChatColor.AQUA + "standard" + ChatColor.GRAY + ": Normale Anzeige (empfohlen)");
|
||||||
|
modePlayer.sendMessage(ChatColor.GRAY + "- " + ChatColor.AQUA + "detailed" + ChatColor.GRAY + ": Alle verfügbaren Daten");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayMode newMode = DisplayMode.fromString(args[1]);
|
||||||
|
playerDisplayModes.put(modePlayer.getUniqueId(), newMode);
|
||||||
|
|
||||||
|
modePlayer.sendMessage(ChatColor.GREEN + "Anzeigemodus geändert zu: " + ChatColor.GOLD + newMode.getDisplayName());
|
||||||
|
modePlayer.sendMessage(ChatColor.GRAY + "Das Scoreboard wird beim nächsten Update aktualisiert.");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
audiences.sender(sender).sendMessage(Component.text(getLocalizedMessage("usage", countryCode), NamedTextColor.RED));
|
audiences.sender(sender).sendMessage(Component.text(getLocalizedMessage("usage", countryCode), NamedTextColor.RED));
|
||||||
return true;
|
return true;
|
||||||
@@ -861,16 +1013,22 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
|
|||||||
Set<String> worlds = playersWithDisplay.computeIfAbsent(player.getUniqueId(), k -> new HashSet<>());
|
Set<String> worlds = playersWithDisplay.computeIfAbsent(player.getUniqueId(), k -> new HashSet<>());
|
||||||
if (worlds.contains(worldName)) {
|
if (worlds.contains(worldName)) {
|
||||||
worlds.remove(worldName);
|
worlds.remove(worldName);
|
||||||
audiences.player(player).sendMessage(Component.text(getLocalizedMessage("toggle_disabled", countryCode, "world", worldName), NamedTextColor.RED));
|
// Scoreboard entfernen
|
||||||
|
player.setScoreboard(Bukkit.getScoreboardManager().getMainScoreboard());
|
||||||
|
playerScoreboards.remove(player.getUniqueId());
|
||||||
|
audiences.player(player).sendMessage(Component.text(
|
||||||
|
getLocalizedMessage("toggle_disabled", countryCode, "world", worldName), NamedTextColor.RED));
|
||||||
} else {
|
} else {
|
||||||
worlds.add(worldName);
|
worlds.add(worldName);
|
||||||
audiences.player(player).sendMessage(Component.text(getLocalizedMessage("toggle_enabled", countryCode, "world", worldName), NamedTextColor.GREEN));
|
// Scoreboard erstellen
|
||||||
|
createScoreboardForPlayer(player);
|
||||||
|
audiences.player(player).sendMessage(Component.text(
|
||||||
|
getLocalizedMessage("toggle_enabled", countryCode, "world", worldName), NamedTextColor.GREEN));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Modellklasse WorldConfig (nur als Speicher für die Welten-Settings)
|
|
||||||
private static class WorldConfig {
|
private static class WorldConfig {
|
||||||
boolean enabled;
|
boolean enabled;
|
||||||
String location;
|
String location;
|
||||||
|
|||||||
83
src/main/java/dev/viper/weathertime/WindDirection.java
Normal file
83
src/main/java/dev/viper/weathertime/WindDirection.java
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
package dev.viper.weathertime;
|
||||||
|
|
||||||
|
public class WindDirection {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konvertiert Windrichtung in Grad (0-360) zu Himmelsrichtung
|
||||||
|
*/
|
||||||
|
public static String getDirection(double degrees) {
|
||||||
|
// Normalisiere auf 0-360
|
||||||
|
degrees = degrees % 360;
|
||||||
|
if (degrees < 0) degrees += 360;
|
||||||
|
|
||||||
|
if (degrees >= 337.5 || degrees < 22.5) {
|
||||||
|
return "N"; // Nord
|
||||||
|
} else if (degrees >= 22.5 && degrees < 67.5) {
|
||||||
|
return "NO"; // Nordost
|
||||||
|
} else if (degrees >= 67.5 && degrees < 112.5) {
|
||||||
|
return "O"; // Ost
|
||||||
|
} else if (degrees >= 112.5 && degrees < 157.5) {
|
||||||
|
return "SO"; // Südost
|
||||||
|
} else if (degrees >= 157.5 && degrees < 202.5) {
|
||||||
|
return "S"; // Süd
|
||||||
|
} else if (degrees >= 202.5 && degrees < 247.5) {
|
||||||
|
return "SW"; // Südwest
|
||||||
|
} else if (degrees >= 247.5 && degrees < 292.5) {
|
||||||
|
return "W"; // West
|
||||||
|
} else {
|
||||||
|
return "NW"; // Nordwest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt den Pfeil-Emoji basierend auf der Windrichtung zurück
|
||||||
|
*/
|
||||||
|
public static String getArrow(double degrees) {
|
||||||
|
degrees = degrees % 360;
|
||||||
|
if (degrees < 0) degrees += 360;
|
||||||
|
|
||||||
|
if (degrees >= 337.5 || degrees < 22.5) {
|
||||||
|
return "↓"; // Nord (Wind kommt von Norden, weht nach Süden)
|
||||||
|
} else if (degrees >= 22.5 && degrees < 67.5) {
|
||||||
|
return "↙"; // Nordost
|
||||||
|
} else if (degrees >= 67.5 && degrees < 112.5) {
|
||||||
|
return "←"; // Ost
|
||||||
|
} else if (degrees >= 112.5 && degrees < 157.5) {
|
||||||
|
return "↖"; // Südost
|
||||||
|
} else if (degrees >= 157.5 && degrees < 202.5) {
|
||||||
|
return "↑"; // Süd
|
||||||
|
} else if (degrees >= 202.5 && degrees < 247.5) {
|
||||||
|
return "↗"; // Südwest
|
||||||
|
} else if (degrees >= 247.5 && degrees < 292.5) {
|
||||||
|
return "→"; // West
|
||||||
|
} else {
|
||||||
|
return "↘"; // Nordwest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die volle Bezeichnung der Windrichtung zurück
|
||||||
|
*/
|
||||||
|
public static String getFullName(double degrees) {
|
||||||
|
degrees = degrees % 360;
|
||||||
|
if (degrees < 0) degrees += 360;
|
||||||
|
|
||||||
|
if (degrees >= 337.5 || degrees < 22.5) {
|
||||||
|
return "Nord";
|
||||||
|
} else if (degrees >= 22.5 && degrees < 67.5) {
|
||||||
|
return "Nordost";
|
||||||
|
} else if (degrees >= 67.5 && degrees < 112.5) {
|
||||||
|
return "Ost";
|
||||||
|
} else if (degrees >= 112.5 && degrees < 157.5) {
|
||||||
|
return "Südost";
|
||||||
|
} else if (degrees >= 157.5 && degrees < 202.5) {
|
||||||
|
return "Süd";
|
||||||
|
} else if (degrees >= 202.5 && degrees < 247.5) {
|
||||||
|
return "Südwest";
|
||||||
|
} else if (degrees >= 247.5 && degrees < 292.5) {
|
||||||
|
return "West";
|
||||||
|
} else {
|
||||||
|
return "Nordwest";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
name: RealTimeWeather
|
name: RealTimeWeather
|
||||||
version: 1.3
|
version: 1.4
|
||||||
main: dev.viper.weathertime.WeatherTimeSyncPlugin
|
main: dev.viper.weathertime.WeatherTimeSyncPlugin
|
||||||
api-version: 1.21
|
api-version: 1.21
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user