src/main/java/dev/viper/weathertime/WeatherTimeSyncPlugin.java aktualisiert

This commit is contained in:
2025-08-09 20:57:46 +00:00
parent 64c994bc8b
commit 98cad69efc

View File

@@ -7,9 +7,7 @@ import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.*;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
@@ -32,67 +30,56 @@ import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.UUID;
import java.util.*;
public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
private String apiKey;
private int updateInterval;
private final HashMap<String, WorldConfig> worldConfigs = new HashMap<>();
private final HashMap<String, WeatherData> worldWeatherData = new HashMap<>();
private final HashMap<UUID, HashSet<String>> playersWithDisplay = new HashMap<>();
private final HashMap<UUID, String> playerLocations = new HashMap<>();
private final HashMap<UUID, Inventory> playerGUIs = new HashMap<>();
private final Map<String, WorldConfig> worldConfigs = new HashMap<>();
private final Map<String, WeatherTimeData> worldWeatherData = new HashMap<>();
private final Map<UUID, Set<String>> playersWithDisplay = new HashMap<>();
private final Map<UUID, String> playerLocations = new HashMap<>();
private final Map<UUID, Inventory> playerGUIs = new HashMap<>();
private BukkitAudiences audiences;
private BukkitRunnable weatherUpdateTask;
private BukkitRunnable syncTask;
private final HashSet<String> processedLocations = new HashSet<>();
private final Set<String> processedLocations = new HashSet<>();
private FileConfiguration langConfig;
@Override
public void onEnable() {
saveDefaultConfig();
loadLanguageConfig(); // Zuerst laden, um sicherzustellen, dass Übersetzungen verfügbar sind
loadLanguageConfig();
loadConfig();
this.audiences = BukkitAudiences.create(this);
audiences = BukkitAudiences.create(this);
getCommand("wetter").setExecutor(new WetterCommand());
getCommand("weatherforecast").setExecutor(new WeatherForecastCommand());
getCommand("toggleweather").setExecutor(new ToggleWeatherCommand());
Objects.requireNonNull(getCommand("wetter")).setExecutor(new WetterCommand());
Objects.requireNonNull(getCommand("weatherforecast")).setExecutor(new WeatherForecastCommand());
Objects.requireNonNull(getCommand("toggleweather")).setExecutor(new ToggleWeatherCommand());
getServer().getPluginManager().registerEvents(this, this);
setDoDaylightCycleForWorlds();
startWeatherUpdateTask();
startSyncTask();
initializePlayerDisplays();
}
@Override
public void onDisable() {
if (weatherUpdateTask != null) {
weatherUpdateTask.cancel();
}
if (syncTask != null) {
syncTask.cancel();
}
if (audiences != null) {
audiences.close();
}
if (weatherUpdateTask != null) weatherUpdateTask.cancel();
if (syncTask != null) syncTask.cancel();
if (audiences != null) audiences.close();
for (Player player : Bukkit.getOnlinePlayers()) {
if (playerGUIs.containsKey(player.getUniqueId())) {
player.closeInventory();
}
if (playerGUIs.containsKey(player.getUniqueId())) player.closeInventory();
}
}
// =============== Config & Sprache ===============
private void loadConfig() {
FileConfiguration cfg = getConfig();
apiKey = cfg.getString("api-key");
apiKey = cfg.getString("api-key", "").trim();
updateInterval = cfg.getInt("update-interval", 60);
worldConfigs.clear();
@@ -125,8 +112,7 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
worldConfigs.put(worldName, worldConfig);
}
}
if (apiKey == null || apiKey.trim().isEmpty()) {
if (apiKey.isEmpty()) {
getLogger().severe("API-Key ist nicht gesetzt! Bitte in config.yml eintragen.");
}
}
@@ -137,48 +123,34 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
langConfig = YamlConfiguration.loadConfiguration(langFile);
if (!langFile.exists()) {
saveResource("lang.yml", false);
getLogger().info("lang.yml wurde aus den Ressourcen kopiert.");
langConfig = YamlConfiguration.loadConfiguration(langFile);
} else if (langConfig.getConfigurationSection("languages") == null) {
getLogger().warning("lang.yml enthält keinen 'languages'-Abschnitt. Standardwerte werden verwendet.");
saveResource("lang.yml", true); // Überschreibe mit Standardwerten
saveResource("lang.yml", true);
langConfig = YamlConfiguration.loadConfiguration(langFile);
}
// Debugging: Verfügbare Sprachen protokollieren
getLogger().info("Verfügbare Sprachen in lang.yml: " + langConfig.getConfigurationSection("languages").getKeys(false));
} catch (Exception e) {
getLogger().severe("Fehler beim Laden von lang.yml: " + e.getMessage());
saveResource("lang.yml", true); // Überschreibe bei Fehler mit Standardwerten
saveResource("lang.yml", true);
langConfig = YamlConfiguration.loadConfiguration(langFile);
getLogger().info("lang.yml wurde nach Fehler mit Standardwerten überschrieben.");
}
}
private void setDoDaylightCycleForWorlds() {
for (World world : Bukkit.getWorlds()) {
WorldConfig config = worldConfigs.getOrDefault(world.getName(), worldConfigs.get("defaults"));
if (config.enabled) {
world.setGameRuleValue("doDaylightCycle", "false");
}
if (config.enabled) world.setGameRuleValue("doDaylightCycle", "false");
}
}
private String getLocalizedMessage(String key, String countryCode, String... placeholders) {
String path = "languages." + (countryCode.isEmpty() ? "en" : countryCode.toLowerCase()) + "." + key;
String message = langConfig.getString(path);
if (message == null) {
path = "languages.en." + key;
message = langConfig.getString(path);
if (message == null) {
// Nur Warnung für fehlende Übersetzungen, keine Debugging-Info für jede Suche
getLogger().warning("Übersetzung für Schlüssel '" + key + "' in Sprache '" + countryCode + "' und Fallback 'en' nicht gefunden!");
return key;
private void initializePlayerDisplays() {
playersWithDisplay.clear();
for (Player player : Bukkit.getOnlinePlayers()) {
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);
}
for (int i = 0; i < placeholders.length - 1; i += 2) {
message = message.replace("{" + placeholders[i] + "}", placeholders[i + 1]);
}
return message;
}
private void startWeatherUpdateTask() {
@@ -199,9 +171,9 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
for (World world : Bukkit.getWorlds()) {
WorldConfig config = worldConfigs.getOrDefault(world.getName(), worldConfigs.get("defaults"));
if (!config.enabled) continue;
WeatherData data = worldWeatherData.get(world.getName());
WeatherTimeData data = worldWeatherData.get(world.getName());
if (data != null) {
syncMinecraftTime(world, data.dateTime);
syncMinecraftTime(world, data.getDateTime());
updateActionbarForWorld(world, data);
}
}
@@ -221,7 +193,7 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
for (String otherWorld : worldWeatherData.keySet()) {
WorldConfig otherConfig = worldConfigs.getOrDefault(otherWorld, worldConfigs.get("defaults"));
if (otherConfig.location.equals(config.location)) {
WeatherData existingData = worldWeatherData.get(otherWorld);
WeatherTimeData existingData = worldWeatherData.get(otherWorld);
if (existingData != null) {
worldWeatherData.put(world.getName(), existingData);
break;
@@ -232,73 +204,41 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
}
try {
WeatherFetcher fetcher = new WeatherFetcher(apiKey, config.location, config.units, getLogger());
WeatherFetcher.WeatherData weatherData = fetcher.fetch();
WeatherData newData = new WeatherData(
weatherData.dateTime,
weatherData.weatherMain,
weatherData.temperature
);
worldWeatherData.put(world.getName(), newData);
WeatherTimeData weatherData = fetcher.fetchAsWeatherTimeData();
worldWeatherData.put(world.getName(), weatherData);
processedLocations.add(config.location);
new BukkitRunnable() {
@Override
public void run() {
syncMinecraftTime(world, weatherData.dateTime);
syncMinecraftTime(world, weatherData.getDateTime());
if (config.syncInGameWeather) {
int durationTicks = 20 * 60 * 5; // 5 Minuten
switch (weatherData.weatherMain.toLowerCase()) {
switch (weatherData.getWeatherMain().toLowerCase()) {
case "rain":
case "drizzle":
world.setStorm(true);
world.setThundering(false);
world.setWeatherDuration(durationTicks);
break;
case "thunderstorm":
world.setStorm(true);
world.setThundering(true);
world.setWeatherDuration(durationTicks);
break;
case "snow":
world.setStorm(true);
world.setThundering(false);
world.setWeatherDuration(durationTicks);
break;
default:
world.setStorm(false);
world.setThundering(false);
world.setWeatherDuration(durationTicks);
break;
}
}
}
}.runTask(this);
} catch (Exception e) {
getLogger().warning("Fehler beim Abrufen von Wetter/Zeit für Welt " + world.getName() + ": " + e.getMessage());
String countryCode = getCountryCode(config.location);
String errorMsg = getLocalizedMessage("forecast_error", countryCode, "location", config.location, "error", e.getMessage());
for (Player player : Bukkit.getOnlinePlayers()) {
if (player.hasPermission("realtimeweather.admin")) {
audiences.player(player).sendMessage(Component.text(errorMsg, NamedTextColor.RED));
}
}
}
}
}
private void initializePlayerDisplays() {
playersWithDisplay.clear();
for (Player player : Bukkit.getOnlinePlayers()) {
HashSet<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);
}
}
private void syncMinecraftTime(World world, ZonedDateTime dateTime) {
int hour = dateTime.getHour();
@@ -309,172 +249,80 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
world.setGameRuleValue("doDaylightCycle", "false");
}
private void updateActionbarForWorld(World world, WeatherData data) {
// === Anzeige (Actionbar, jetzt mit Luftfeuchtigkeit, Wind, Sonne) ===
private void updateActionbarForWorld(World world, WeatherTimeData data) {
WorldConfig config = worldConfigs.getOrDefault(world.getName(), worldConfigs.get("defaults"));
if (!config.enabled || !config.displayActionbar) return;
for (Player player : world.getPlayers()) {
if (!playersWithDisplay.getOrDefault(player.getUniqueId(), new HashSet<>()).contains(world.getName())) {
if (!playersWithDisplay.getOrDefault(player.getUniqueId(), new HashSet<>()).contains(world.getName()))
continue;
}
WeatherData playerData = data;
WeatherTimeData playerData = data;
String location = playerLocations.getOrDefault(player.getUniqueId(), "");
if (!location.isEmpty()) {
try {
WeatherFetcher fetcher = new WeatherFetcher(apiKey, location, config.units, getLogger());
WeatherFetcher.WeatherData fetched = fetcher.fetch();
playerData = new WeatherData(fetched.dateTime, fetched.weatherMain, fetched.temperature);
playerData = fetcher.fetchAsWeatherTimeData();
} catch (Exception e) {
String countryCode = getCountryCode(config.location);
audiences.player(player).sendMessage(Component.text(
getLocalizedMessage("forecast_error", countryCode, "location", location, "error", e.getMessage()),
getLocalizedMessage("forecast_error", countryCode,
"location", location,
"error", e.getMessage()),
NamedTextColor.RED));
continue;
}
}
String dateStr = playerData.dateTime.format(DateTimeFormatter.ofPattern("dd.MM.yyyy"));
String timeStr = formatTime(playerData.dateTime, config.timeFormat);
String dateStr = playerData.getDateTime().format(DateTimeFormatter.ofPattern("dd.MM.yyyy"));
String timeStr = playerData.getFormattedTime(config.timeFormat);
String tempUnit = config.units.equalsIgnoreCase("metric") ? "°C" : "°F";
String weatherIcon = config.displayWeatherIcon ? getWeatherSymbol(playerData.weatherMain) + " " : "";
String tempStr = String.format("%.1f%s", playerData.temperature, tempUnit);
String weatherIcon = config.displayWeatherIcon ? getWeatherSymbol(playerData.getWeatherMain()) + " " : "";
String tempStr = String.format("%.1f%s", playerData.getTemp(config.units.equalsIgnoreCase("metric") ? "C" : "F"), tempUnit);
String humidityStr = "💧 " + playerData.getHumidity() + "%";
String windStr = "🌬️ " + String.format("%.1f", playerData.getWindSpeed()) + (config.units.equalsIgnoreCase("metric") ? " m/s" : " mph");
String sunriseStr = "🌅 " + playerData.getSunrise().format(DateTimeFormatter.ofPattern("HH:mm"));
String sunsetStr = "🌇 " + playerData.getSunset().format(DateTimeFormatter.ofPattern("HH:mm"));
Component message = Component.text()
.append(Component.text(dateStr + " ", NamedTextColor.AQUA, TextDecoration.BOLD))
.append(Component.text(timeStr + " ", NamedTextColor.YELLOW))
.append(Component.text(weatherIcon, NamedTextColor.WHITE))
.append(Component.text(tempStr, NamedTextColor.GREEN))
.append(Component.text("| " + timeStr + " ", NamedTextColor.YELLOW))
.append(Component.text("| " + weatherIcon, NamedTextColor.WHITE))
.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();
Component paddedMessage;
if ("top-right".equalsIgnoreCase(config.displayPosition)) {
paddedMessage = Component.text()
.append(Component.text(" ".repeat(config.paddingRight)))
.append(message)
.build();
} else {
paddedMessage = Component.text()
.append(message)
.append(Component.text(" ".repeat(20)))
.build();
}
audiences.player(player).sendActionBar(paddedMessage);
audiences.player(player).sendActionBar(message);
}
}
private String formatTime(ZonedDateTime dateTime, String timeFormat) {
int hour = dateTime.getHour();
int minute = dateTime.getMinute();
int second = dateTime.getSecond();
if ("12h".equalsIgnoreCase(timeFormat)) {
String ampm = hour >= 12 ? "PM" : "AM";
int hour12 = hour % 12;
if (hour12 == 0) hour12 = 12;
return String.format("%d:%02d:%02d %s", hour12, minute, second, ampm);
} else {
return String.format("%02d:%02d:%02d", hour, minute, second);
}
}
private String getWeatherSymbol(String weatherMain) {
String w = weatherMain.toLowerCase();
switch (w) {
case "clear": return "☀️";
case "clouds": return "☁️";
case "rain": return "🌧️";
case "thunderstorm": return "⛈️";
case "snow": return "❄️";
case "mist":
case "fog":
case "haze": return "🌫️";
default: return weatherMain;
}
}
private String getLocalizedWeatherMain(String weatherMain, String countryCode) {
String key = "weather." + weatherMain.toLowerCase();
return getLocalizedMessage(key, countryCode);
}
private String getCountryCode(String location) {
if (location == null || !location.contains(",")) {
getLogger().warning("Ungültiges Location-Format: " + location + ". Fallback auf 'en'.");
return "en";
}
String[] parts = location.split(",");
String countryCode = parts.length > 1 ? parts[1].trim().toLowerCase() : "en";
// Überprüfe, ob der Sprachcode in lang.yml existiert
if (!langConfig.contains("languages." + countryCode)) {
getLogger().warning("Sprache '" + countryCode + "' nicht in lang.yml gefunden. Fallback auf 'en'.");
return "en";
}
return countryCode;
}
private Inventory createWeatherGUI(Player player) {
String countryCode = getCountryCode(worldConfigs.getOrDefault(player.getWorld().getName(), worldConfigs.get("defaults")).location);
Inventory inv = Bukkit.createInventory(null, 9, getLocalizedMessage("gui_title", countryCode));
ItemStack setLocation = new ItemStack(Material.BOOK);
ItemStack toggleWeather = new ItemStack(Material.REDSTONE_TORCH);
ItemStack forecast = new ItemStack(Material.PAPER);
ItemStack info = new ItemStack(Material.OAK_SIGN);
ItemMeta setLocationMeta = setLocation.getItemMeta();
setLocationMeta.setDisplayName(getLocalizedMessage("gui_setlocation", countryCode));
setLocationMeta.setLore(Arrays.asList(getLocalizedMessage("gui_setlocation_lore", countryCode)));
setLocation.setItemMeta(setLocationMeta);
ItemMeta toggleWeatherMeta = toggleWeather.getItemMeta();
toggleWeatherMeta.setDisplayName(getLocalizedMessage("gui_toggleweather", countryCode));
toggleWeatherMeta.setLore(Arrays.asList(getLocalizedMessage("gui_toggleweather_lore", countryCode)));
toggleWeather.setItemMeta(toggleWeatherMeta);
ItemMeta forecastMeta = forecast.getItemMeta();
forecastMeta.setDisplayName(getLocalizedMessage("gui_forecast", countryCode));
forecastMeta.setLore(Arrays.asList(getLocalizedMessage("gui_forecast_lore", countryCode)));
forecast.setItemMeta(forecastMeta);
ItemMeta infoMeta = info.getItemMeta();
infoMeta.setDisplayName(getLocalizedMessage("gui_info", countryCode));
infoMeta.setLore(Arrays.asList(getLocalizedMessage("gui_info_lore", countryCode)));
info.setItemMeta(infoMeta);
inv.setItem(2, setLocation);
inv.setItem(3, toggleWeather);
inv.setItem(4, forecast);
inv.setItem(5, info);
playerGUIs.put(player.getUniqueId(), inv);
return inv;
}
// === Events (z.B. Weltwechsel) ===
@EventHandler
public void onPlayerChangedWorld(PlayerChangedWorldEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
WorldConfig config = worldConfigs.getOrDefault(world.getName(), worldConfigs.get("defaults"));
if (!config.enabled) return;
WeatherData data = worldWeatherData.get(world.getName());
WeatherTimeData data = worldWeatherData.get(world.getName());
if (data == null) return;
String countryCode = getCountryCode(config.location);
String localizedWeather = getLocalizedWeatherMain(data.weatherMain, countryCode);
String localizedWeather = getLocalizedWeatherMain(data.getWeatherMain(), countryCode);
String tempUnit = config.units.equalsIgnoreCase("metric") ? "°C" : "°F";
String city = config.location.split(",")[0];
String message = String.format("%s: %s, %.1f%s", city, localizedWeather, data.temperature, 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));
}
@EventHandler
public void onInventoryClick(InventoryClickEvent event) {
Player player = (Player) event.getWhoClicked();
if (!playerGUIs.containsKey(player.getUniqueId()) || event.getInventory() != playerGUIs.get(player.getUniqueId())) {
return;
}
Inventory expectedGUI = playerGUIs.get(player.getUniqueId());
if (expectedGUI == null || event.getInventory() != expectedGUI) return;
event.setCancelled(true);
ItemStack clickedItem = event.getCurrentItem();
if (clickedItem == null || clickedItem.getType() == Material.AIR) return;
@@ -488,7 +336,7 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
getLocalizedMessage("gui_setlocation_prompt", countryCode), NamedTextColor.YELLOW));
} else if (clickedItem.getType() == Material.REDSTONE_TORCH) {
String worldName = player.getWorld().getName();
HashSet<String> worlds = playersWithDisplay.computeIfAbsent(player.getUniqueId(), k -> new HashSet<>());
Set<String> worlds = playersWithDisplay.computeIfAbsent(player.getUniqueId(), k -> new HashSet<>());
if (worlds.contains(worldName)) {
worlds.remove(worldName);
audiences.player(player).sendMessage(Component.text(
@@ -510,62 +358,101 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
@EventHandler
public void onInventoryClose(InventoryCloseEvent event) {
Player player = (Player) event.getPlayer();
playerGUIs.remove(player.getUniqueId());
playerGUIs.remove(event.getPlayer().getUniqueId());
}
private static class WeatherData {
ZonedDateTime dateTime;
String weatherMain;
double temperature;
// === Hilfsmethoden & Modellklassen ===
public WeatherData(ZonedDateTime dateTime, String weatherMain, double temperature) {
this.dateTime = dateTime;
this.weatherMain = weatherMain;
this.temperature = temperature;
private String getLocalizedMessage(String key, String countryCode, String... placeholders) {
String path = "languages." + (countryCode.isEmpty() ? "en" : countryCode.toLowerCase()) + "." + key;
String message = langConfig.getString(path);
if (message == null) {
path = "languages.en." + key;
message = langConfig.getString(path, key);
}
for (int i = 0; i < placeholders.length - 1; i += 2) {
message = message.replace("{" + placeholders[i] + "}", placeholders[i + 1]);
}
return message;
}
private String getWeatherSymbol(String weatherMain) {
switch (weatherMain.toLowerCase()) {
case "clear": return "☀️";
case "clouds": return "☁️";
case "rain": return "🌧️";
case "thunderstorm": return "⛈️";
case "snow": return "❄️";
case "mist":
case "fog":
case "haze": return "🌫️";
default: return weatherMain;
}
}
private static class WorldConfig {
boolean enabled;
String location;
String units;
String timeFormat;
boolean displayActionbar;
boolean displayWeatherIcon;
String displayPosition;
int paddingRight;
boolean syncInGameWeather;
public WorldConfig(boolean enabled, String location, String units, String timeFormat, boolean displayActionbar,
boolean displayWeatherIcon, String displayPosition, int paddingRight, boolean syncInGameWeather) {
this.enabled = enabled;
this.location = location;
this.units = units;
this.timeFormat = timeFormat;
this.displayActionbar = displayActionbar;
this.displayWeatherIcon = displayWeatherIcon;
this.displayPosition = displayPosition;
this.paddingRight = paddingRight;
this.syncInGameWeather = syncInGameWeather;
}
private String getLocalizedWeatherMain(String weatherMain, String countryCode) {
String key = "weather." + weatherMain.toLowerCase();
return getLocalizedMessage(key, countryCode);
}
private String getCountryCode(String location) {
if (location == null || !location.contains(",")) return "en";
String[] parts = location.split(",");
String countryCode = parts.length > 1 ? parts[1].trim().toLowerCase() : "en";
if (!langConfig.contains("languages." + countryCode)) return "en";
return countryCode;
}
private Inventory createWeatherGUI(Player player) {
String countryCode = getCountryCode(worldConfigs.getOrDefault(player.getWorld().getName(), worldConfigs.get("defaults")).location);
Inventory inv = Bukkit.createInventory(null, 9, getLocalizedMessage("gui_title", countryCode));
ItemStack setLocation = new ItemStack(Material.BOOK);
ItemStack toggleWeather = new ItemStack(Material.REDSTONE_TORCH);
ItemStack forecast = new ItemStack(Material.PAPER);
ItemStack info = new ItemStack(Material.OAK_SIGN);
ItemMeta setLocationMeta = setLocation.getItemMeta();
setLocationMeta.setDisplayName(getLocalizedMessage("gui_setlocation", countryCode));
setLocationMeta.setLore(Collections.singletonList(getLocalizedMessage("gui_setlocation_lore", countryCode)));
setLocation.setItemMeta(setLocationMeta);
ItemMeta toggleWeatherMeta = toggleWeather.getItemMeta();
toggleWeatherMeta.setDisplayName(getLocalizedMessage("gui_toggleweather", countryCode));
toggleWeatherMeta.setLore(Collections.singletonList(getLocalizedMessage("gui_toggleweather_lore", countryCode)));
toggleWeather.setItemMeta(toggleWeatherMeta);
ItemMeta forecastMeta = forecast.getItemMeta();
forecastMeta.setDisplayName(getLocalizedMessage("gui_forecast", countryCode));
forecastMeta.setLore(Collections.singletonList(getLocalizedMessage("gui_forecast_lore", countryCode)));
forecast.setItemMeta(forecastMeta);
ItemMeta infoMeta = info.getItemMeta();
infoMeta.setDisplayName(getLocalizedMessage("gui_info", countryCode));
infoMeta.setLore(Collections.singletonList(getLocalizedMessage("gui_info_lore", countryCode)));
info.setItemMeta(infoMeta);
inv.setItem(2, setLocation);
inv.setItem(3, toggleWeather);
inv.setItem(4, forecast);
inv.setItem(5, info);
playerGUIs.put(player.getUniqueId(), inv);
return inv;
}
// ==== PlayerConfig etc. wie gehabt ====
private class PlayerConfig {
private final File configFile;
private final FileConfiguration config;
public PlayerConfig(UUID playerId) {
File playerDir = new File(getDataFolder(), "players");
playerDir.mkdirs();
configFile = new File(playerDir, playerId.toString() + ".yml");
config = YamlConfiguration.loadConfiguration(configFile);
}
public String getLocation() {
return config.getString("location", "");
}
public void setLocation(String location) {
config.set("location", location);
try {
@@ -576,18 +463,17 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
}
}
// ==== Commands ====
private class WetterCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length == 0) {
String countryCode = getCountryCode(worldConfigs.get("defaults").location);
audiences.sender(sender).sendMessage(Component.text(
getLocalizedMessage("usage", countryCode), NamedTextColor.RED));
if (args.length == 0) {
audiences.sender(sender).sendMessage(Component.text(getLocalizedMessage("usage", countryCode), NamedTextColor.RED));
return true;
}
if (args[0].equalsIgnoreCase("help")) {
String countryCode = getCountryCode(worldConfigs.get("defaults").location);
switch (args[0].toLowerCase(Locale.ROOT)) {
case "help": {
Component helpMessage = Component.text()
.append(Component.text(getLocalizedMessage("help_header", countryCode), NamedTextColor.AQUA, TextDecoration.BOLD))
.append(Component.newline())
@@ -618,52 +504,34 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
audiences.sender(sender).sendMessage(helpMessage);
return true;
}
if (args[0].equalsIgnoreCase("reload")) {
case "reload": {
if (!sender.hasPermission("realtimeweather.reload")) {
String countryCode = getCountryCode(worldConfigs.get("defaults").location);
audiences.sender(sender).sendMessage(Component.text(
getLocalizedMessage("no_permission", countryCode), NamedTextColor.RED));
audiences.sender(sender).sendMessage(Component.text(getLocalizedMessage("no_permission", countryCode), NamedTextColor.RED));
return true;
}
if (weatherUpdateTask != null) {
weatherUpdateTask.cancel();
}
if (syncTask != null) {
syncTask.cancel();
}
if (weatherUpdateTask != null) weatherUpdateTask.cancel();
if (syncTask != null) syncTask.cancel();
reloadConfig();
loadConfig();
loadLanguageConfig();
worldWeatherData.clear();
processedLocations.clear();
initializePlayerDisplays();
setDoDaylightCycleForWorlds();
startWeatherUpdateTask();
startSyncTask();
processedLocations.clear();
updateWeatherDataForAllWorlds();
String countryCode = getCountryCode(worldConfigs.get("defaults").location);
audiences.sender(sender).sendMessage(Component.text(
getLocalizedMessage("reload_success", countryCode), NamedTextColor.GREEN));
audiences.sender(sender).sendMessage(Component.text(getLocalizedMessage("reload_success", countryCode), NamedTextColor.GREEN));
return true;
}
if (args[0].equalsIgnoreCase("setlocation")) {
case "setlocation": {
if (!(sender instanceof Player)) {
String countryCode = getCountryCode(worldConfigs.get("defaults").location);
audiences.sender(sender).sendMessage(Component.text(
getLocalizedMessage("only_players", countryCode), NamedTextColor.RED));
audiences.sender(sender).sendMessage(Component.text(getLocalizedMessage("only_players", countryCode), NamedTextColor.RED));
return true;
}
if (args.length != 2) {
String countryCode = getCountryCode(worldConfigs.get("defaults").location);
audiences.sender(sender).sendMessage(Component.text(
getLocalizedMessage("usage_setlocation", countryCode), NamedTextColor.RED));
audiences.sender(sender).sendMessage(Component.text(getLocalizedMessage("usage_setlocation", countryCode), NamedTextColor.RED));
return true;
}
Player player = (Player) sender;
@@ -673,114 +541,90 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
public void run() {
try {
WeatherFetcher fetcher = new WeatherFetcher(apiKey, location, "metric", getLogger());
fetcher.fetch(); // Teste, ob der Ort gültig ist
fetcher.fetchAsWeatherTimeData();
PlayerConfig playerConfig = new PlayerConfig(player.getUniqueId());
playerConfig.setLocation(location);
playerLocations.put(player.getUniqueId(), location);
String countryCode = getCountryCode(location);
audiences.player(player).sendMessage(Component.text(
getLocalizedMessage("location_set", countryCode, "location", location),
NamedTextColor.GREEN));
String cc = getCountryCode(location);
audiences.player(player).sendMessage(Component.text(getLocalizedMessage("location_set", cc, "location", location), NamedTextColor.GREEN));
} catch (Exception e) {
String countryCode = getCountryCode(worldConfigs.get("defaults").location);
audiences.player(player).sendMessage(Component.text(
getLocalizedMessage("invalid_location", countryCode, "location", location),
NamedTextColor.RED));
audiences.player(player).sendMessage(Component.text(getLocalizedMessage("invalid_location", countryCode, "location", location), NamedTextColor.RED));
}
}
}.runTaskAsynchronously(WeatherTimeSyncPlugin.this);
return true;
}
if (args[0].equalsIgnoreCase("query")) {
case "query": {
if (!(sender instanceof Player)) {
String countryCode = getCountryCode(worldConfigs.get("defaults").location);
audiences.sender(sender).sendMessage(Component.text(
getLocalizedMessage("only_players", countryCode), NamedTextColor.RED));
audiences.sender(sender).sendMessage(Component.text(getLocalizedMessage("only_players", countryCode), NamedTextColor.RED));
return true;
}
Player player = (Player) sender;
WorldConfig config = worldConfigs.getOrDefault(player.getWorld().getName(), worldConfigs.get("defaults"));
Player queryPlayer = (Player) sender;
WorldConfig config = worldConfigs.getOrDefault(queryPlayer.getWorld().getName(), worldConfigs.get("defaults"));
if (!config.enabled) {
String countryCode = getCountryCode(config.location);
audiences.player(player).sendMessage(Component.text(
getLocalizedMessage("plugin_disabled", countryCode, "world", player.getWorld().getName()),
NamedTextColor.RED));
audiences.player(queryPlayer).sendMessage(Component.text(getLocalizedMessage("plugin_disabled", countryCode, "world", queryPlayer.getWorld().getName()), NamedTextColor.RED));
return true;
}
String location = playerLocations.getOrDefault(player.getUniqueId(), config.location);
String queryLocation = playerLocations.getOrDefault(queryPlayer.getUniqueId(), config.location);
new BukkitRunnable() {
@Override
public void run() {
try {
WeatherFetcher fetcher = new WeatherFetcher(apiKey, location, config.units, getLogger());
WeatherFetcher.WeatherData data = fetcher.fetch();
String countryCode = getCountryCode(location);
String localizedWeather = getLocalizedWeatherMain(data.weatherMain, countryCode);
WeatherFetcher fetcher = new WeatherFetcher(apiKey, queryLocation, config.units, getLogger());
WeatherTimeData data = fetcher.fetchAsWeatherTimeData();
String cc = getCountryCode(queryLocation);
String localizedWeather = getLocalizedWeatherMain(data.getWeatherMain(), cc);
String tempUnit = config.units.equalsIgnoreCase("metric") ? "°C" : "°F";
String city = location.split(",")[0];
String message = String.format("%s: %s, %.1f%s", city, localizedWeather, data.temperature, tempUnit);
audiences.player(player).sendMessage(Component.text(message, NamedTextColor.GREEN));
String city = queryLocation.split(",")[0];
String message = String.format("%s: %s, %.1f%s", city, localizedWeather, data.getTemp(config.units.equalsIgnoreCase("metric") ? "C" : "F"), tempUnit);
audiences.player(queryPlayer).sendMessage(Component.text(message, NamedTextColor.GREEN));
} 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));
audiences.player(queryPlayer).sendMessage(Component.text(getLocalizedMessage("forecast_error", countryCode, "location", queryLocation, "error", e.getMessage()), NamedTextColor.RED));
}
}
}.runTaskAsynchronously(WeatherTimeSyncPlugin.this);
return true;
}
if (args[0].equalsIgnoreCase("info")) {
case "info": {
String infoMessage = "RealTimeWeather Plugin\nVersion: 1.0\nAutor: M_Viper\nGetestete Minecraft-Version: 1.21.1 - 1.21.8";
audiences.sender(sender).sendMessage(Component.text(infoMessage, NamedTextColor.AQUA));
return true;
}
if (args[0].equalsIgnoreCase("gui")) {
case "gui": {
if (!(sender instanceof Player)) {
String countryCode = getCountryCode(worldConfigs.get("defaults").location);
audiences.sender(sender).sendMessage(Component.text(
getLocalizedMessage("only_players", countryCode), NamedTextColor.RED));
audiences.sender(sender).sendMessage(Component.text(getLocalizedMessage("only_players", countryCode), NamedTextColor.RED));
return true;
}
Player player = (Player) sender;
WorldConfig config = worldConfigs.getOrDefault(player.getWorld().getName(), worldConfigs.get("defaults"));
if (!config.enabled) {
String countryCode = getCountryCode(config.location);
audiences.player(player).sendMessage(Component.text(
getLocalizedMessage("plugin_disabled", countryCode, "world", player.getWorld().getName()),
NamedTextColor.RED));
Player guiPlayer = (Player) sender;
WorldConfig guiConfig = worldConfigs.getOrDefault(guiPlayer.getWorld().getName(), worldConfigs.get("defaults"));
if (!guiConfig.enabled) {
String cc = getCountryCode(guiConfig.location);
audiences.player(guiPlayer).sendMessage(Component.text(getLocalizedMessage("plugin_disabled", cc, "world", guiPlayer.getWorld().getName()), NamedTextColor.RED));
return true;
}
player.openInventory(createWeatherGUI(player));
guiPlayer.openInventory(createWeatherGUI(guiPlayer));
return true;
}
String countryCode = getCountryCode(worldConfigs.get("defaults").location);
audiences.sender(sender).sendMessage(Component.text(
getLocalizedMessage("usage", countryCode), NamedTextColor.RED));
default:
audiences.sender(sender).sendMessage(Component.text(getLocalizedMessage("usage", countryCode), NamedTextColor.RED));
return true;
}
}
}
private class WeatherForecastCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
String countryCode = getCountryCode(worldConfigs.get("defaults").location);
audiences.sender(sender).sendMessage(Component.text(
getLocalizedMessage("only_players", countryCode), NamedTextColor.RED));
audiences.sender(sender).sendMessage(Component.text(getLocalizedMessage("only_players", countryCode), NamedTextColor.RED));
return true;
}
Player player = (Player) sender;
WorldConfig config = worldConfigs.getOrDefault(player.getWorld().getName(), worldConfigs.get("defaults"));
if (!config.enabled) {
String countryCode = getCountryCode(config.location);
audiences.player(player).sendMessage(Component.text(
getLocalizedMessage("plugin_disabled", countryCode, "world", player.getWorld().getName()),
NamedTextColor.RED));
audiences.player(player).sendMessage(Component.text(getLocalizedMessage("plugin_disabled", countryCode, "world", player.getWorld().getName()), NamedTextColor.RED));
return true;
}
String location = playerLocations.getOrDefault(player.getUniqueId(), config.location);
@@ -832,8 +676,7 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)) {
String countryCode = getCountryCode(worldConfigs.get("defaults").location);
audiences.sender(sender).sendMessage(Component.text(
getLocalizedMessage("only_players", countryCode), NamedTextColor.RED));
audiences.sender(sender).sendMessage(Component.text(getLocalizedMessage("only_players", countryCode), NamedTextColor.RED));
return true;
}
Player player = (Player) sender;
@@ -841,23 +684,46 @@ public class WeatherTimeSyncPlugin extends JavaPlugin implements Listener {
WorldConfig config = worldConfigs.getOrDefault(worldName, worldConfigs.get("defaults"));
if (!config.enabled) {
String countryCode = getCountryCode(config.location);
audiences.player(player).sendMessage(Component.text(
getLocalizedMessage("plugin_disabled", countryCode, "world", worldName),
NamedTextColor.RED));
audiences.player(player).sendMessage(Component.text(getLocalizedMessage("plugin_disabled", countryCode, "world", worldName), NamedTextColor.RED));
return true;
}
String countryCode = getCountryCode(config.location);
HashSet<String> worlds = playersWithDisplay.computeIfAbsent(player.getUniqueId(), k -> new HashSet<>());
Set<String> worlds = playersWithDisplay.computeIfAbsent(player.getUniqueId(), k -> new HashSet<>());
if (worlds.contains(worldName)) {
worlds.remove(worldName);
audiences.player(player).sendMessage(Component.text(
getLocalizedMessage("toggle_disabled", countryCode, "world", worldName), NamedTextColor.RED));
audiences.player(player).sendMessage(Component.text(getLocalizedMessage("toggle_disabled", countryCode, "world", worldName), NamedTextColor.RED));
} else {
worlds.add(worldName);
audiences.player(player).sendMessage(Component.text(
getLocalizedMessage("toggle_enabled", countryCode, "world", worldName), NamedTextColor.GREEN));
audiences.player(player).sendMessage(Component.text(getLocalizedMessage("toggle_enabled", countryCode, "world", worldName), NamedTextColor.GREEN));
}
return true;
}
}
// Modellklasse WorldConfig (nur als Speicher für die Welten-Settings)
private static class WorldConfig {
boolean enabled;
String location;
String units;
String timeFormat;
boolean displayActionbar;
boolean displayWeatherIcon;
String displayPosition;
int paddingRight;
boolean syncInGameWeather;
public WorldConfig(boolean enabled, String location, String units, String timeFormat,
boolean displayActionbar, boolean displayWeatherIcon,
String displayPosition, int paddingRight, boolean syncInGameWeather) {
this.enabled = enabled;
this.location = location;
this.units = units;
this.timeFormat = timeFormat;
this.displayActionbar = displayActionbar;
this.displayWeatherIcon = displayWeatherIcon;
this.displayPosition = displayPosition;
this.paddingRight = paddingRight;
this.syncInGameWeather = syncInGameWeather;
}
}
}