Compare commits
17 Commits
Author | SHA1 | Date | |
---|---|---|---|
137ba95a24 | |||
a1e415d6f0 | |||
b6b44d25c5 | |||
dc173691a4 | |||
f42e91f253 | |||
50f4827ac1 | |||
221151dfd2 | |||
b1de85aa22 | |||
85e78307b5 | |||
3dedf24f92 | |||
f05c63307a | |||
edb366acd6 | |||
8e753d1479 | |||
a7af54e61c | |||
33759bb44b | |||
b8715ced69 | |||
302b188f50 |
85
dependency-reduced-pom.xml
Normal file
85
dependency-reduced-pom.xml
Normal file
@@ -0,0 +1,85 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>viper</groupId>
|
||||
<artifactId>ButtonControl</artifactId>
|
||||
<version>1.3</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/groups/public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.21-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- bStats Monitoring -->
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.10.1</version>
|
||||
<configuration>
|
||||
<source>${java.version}</source>
|
||||
<target>${java.version}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.4.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>de.viper.bstats</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
53
pom.xml
53
pom.xml
@@ -1,14 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>viper</groupId>
|
||||
<artifactId>ButtonControl</artifactId>
|
||||
<version>1.1</version>
|
||||
<version>1.3</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>ButtonControl</name>
|
||||
|
||||
<repositories>
|
||||
<!-- Spigot-Repository -->
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
@@ -16,16 +21,32 @@
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- Spigot API (bereitgestellt vom Server) -->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.21.1-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- bStats Bukkit -->
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>3.0.2</version>
|
||||
</dependency>
|
||||
|
||||
<!-- org.json für UpdateChecker JSON-Parsing -->
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>20240303</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- Compiler Plugin -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
@@ -33,8 +54,34 @@
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
<encoding>UTF-8</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Shade Plugin zum Relocaten von bStats -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>org.bstats</pattern>
|
||||
<shadedPattern>viper.shaded.bstats</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
</project>
|
||||
|
@@ -17,32 +17,93 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.Note;
|
||||
import org.bukkit.Note.Tone;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ButtonControl extends JavaPlugin {
|
||||
private ConfigManager configManager;
|
||||
private DataManager dataManager;
|
||||
private Map<String, Long> lastMotionDetections = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
configManager = new ConfigManager(this);
|
||||
dataManager = new DataManager(this);
|
||||
|
||||
// Initialize config with defaults if not present
|
||||
// Spigot Update Checker starten
|
||||
new UpdateChecker(this, 127702).getVersion(version -> {
|
||||
String currentVersion = this.getDescription().getVersion();
|
||||
String normalizedLatest = version.replaceFirst("(?i)^(version\\s*|v\\.?\\s*)", "").trim();
|
||||
String normalizedCurrent = currentVersion.replaceFirst("(?i)^(version\\s*|v\\.?\\s*)", "").trim();
|
||||
|
||||
if (isNewerVersion(normalizedLatest, normalizedCurrent)) {
|
||||
getLogger().info("Neue Version verfügbar: " + version);
|
||||
getLogger().info("Download: https://www.spigotmc.org/resources/buttoncontrol.127702/");
|
||||
Bukkit.getScheduler().runTask(this, () -> {
|
||||
Bukkit.getOnlinePlayers().stream()
|
||||
.filter(p -> p.hasPermission("buttoncontrol.update"))
|
||||
.forEach(p -> {
|
||||
p.sendMessage("§6[ButtonControl] §eEine neue Version ist verfügbar: §f" + version);
|
||||
p.sendMessage("§6[ButtonControl] §eDownload: §fhttps://www.spigotmc.org/resources/buttoncontrol.127702/");
|
||||
});
|
||||
});
|
||||
} else {
|
||||
getLogger().info("Keine neue Version verfügbar.");
|
||||
}
|
||||
});
|
||||
|
||||
// Listener für Spieler-Joins
|
||||
getServer().getPluginManager().registerEvents(new Listener() {
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
if (!player.hasPermission("buttoncontrol.update")) return;
|
||||
new UpdateChecker(ButtonControl.this, 127702).getVersion(version -> {
|
||||
String currentVersion = getDescription().getVersion();
|
||||
String normalizedLatest = version.replaceFirst("(?i)^(version\\s*|v\\.?\\s*)", "").trim();
|
||||
String normalizedCurrent = currentVersion.replaceFirst("(?i)^(version\\s*|v\\.?\\s*)", "").trim();
|
||||
|
||||
if (isNewerVersion(normalizedLatest, normalizedCurrent)) {
|
||||
player.sendMessage("§6[ButtonControl] §eEine neue Version ist verfügbar: §f" + version);
|
||||
player.sendMessage("§6[ButtonControl] §eDownload: §fhttps://www.spigotmc.org/resources/buttoncontrol.127702/");
|
||||
}
|
||||
});
|
||||
}
|
||||
}, this);
|
||||
|
||||
updateConfigWithDefaults();
|
||||
|
||||
getServer().getPluginManager().registerEvents(new ButtonListener(this, configManager, dataManager), this);
|
||||
|
||||
registerRecipes();
|
||||
|
||||
// Scheduler zum Prüfen der Tageslichtsensoren alle 10 Sekunden (20 Ticks = 1 Sekunde)
|
||||
getServer().getScheduler().runTaskTimer(this, this::checkDaylightSensors, 0L, 20L * 10);
|
||||
getServer().getScheduler().runTaskTimer(this, this::checkMotionSensors, 0L, 10L);
|
||||
MetricsHandler.startMetrics(this);
|
||||
}
|
||||
|
||||
private boolean isNewerVersion(String latest, String current) {
|
||||
try {
|
||||
String[] latestParts = latest.split("\\.");
|
||||
String[] currentParts = current.split("\\.");
|
||||
int length = Math.max(latestParts.length, currentParts.length);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
int latestPart = (i < latestParts.length) ? Integer.parseInt(latestParts[i]) : 0;
|
||||
int currentPart = (i < currentParts.length) ? Integer.parseInt(currentParts[i]) : 0;
|
||||
if (latestPart > currentPart) return true;
|
||||
if (latestPart < currentPart) return false;
|
||||
}
|
||||
return false;
|
||||
} catch (NumberFormatException e) {
|
||||
return !latest.equalsIgnoreCase(current);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateConfigWithDefaults() {
|
||||
// Add default note block sound and double note settings if not present
|
||||
if (!configManager.getConfig().contains("default-note")) {
|
||||
configManager.getConfig().set("default-note", "PIANO");
|
||||
}
|
||||
@@ -52,6 +113,12 @@ public class ButtonControl extends JavaPlugin {
|
||||
if (!configManager.getConfig().contains("double-note-delay-ms")) {
|
||||
configManager.getConfig().set("double-note-delay-ms", 1000);
|
||||
}
|
||||
if (!configManager.getConfig().contains("motion-detection-radius")) {
|
||||
configManager.getConfig().set("motion-detection-radius", 5.0);
|
||||
}
|
||||
if (!configManager.getConfig().contains("motion-close-delay-ms")) {
|
||||
configManager.getConfig().set("motion-close-delay-ms", 5000);
|
||||
}
|
||||
configManager.saveConfig();
|
||||
}
|
||||
|
||||
@@ -82,7 +149,6 @@ public class ButtonControl extends JavaPlugin {
|
||||
daylightRecipe.setIngredient('8', Material.DAYLIGHT_DETECTOR);
|
||||
Bukkit.addRecipe(daylightRecipe);
|
||||
|
||||
// Recipe for Control Note Block
|
||||
ItemStack controlNoteBlock = new ItemStack(Material.NOTE_BLOCK);
|
||||
ItemMeta noteBlockMeta = controlNoteBlock.getItemMeta();
|
||||
noteBlockMeta.setDisplayName("§6Steuer-Notenblock");
|
||||
@@ -95,6 +161,19 @@ public class ButtonControl extends JavaPlugin {
|
||||
noteBlockRecipe.setIngredient('5', Material.NOTE_BLOCK);
|
||||
noteBlockRecipe.setIngredient('8', Material.NOTE_BLOCK);
|
||||
Bukkit.addRecipe(noteBlockRecipe);
|
||||
|
||||
ItemStack controlMotion = new ItemStack(Material.TRIPWIRE_HOOK);
|
||||
ItemMeta motionMeta = controlMotion.getItemMeta();
|
||||
motionMeta.setDisplayName("§6Steuer-Bewegungsmelder");
|
||||
controlMotion.setItemMeta(motionMeta);
|
||||
|
||||
NamespacedKey motionKey = new NamespacedKey(this, "control_motion");
|
||||
ShapedRecipe motionRecipe = new ShapedRecipe(motionKey, controlMotion);
|
||||
motionRecipe.shape("123", "456", "789");
|
||||
motionRecipe.setIngredient('2', Material.TRIPWIRE_HOOK);
|
||||
motionRecipe.setIngredient('5', Material.TRIPWIRE_HOOK);
|
||||
motionRecipe.setIngredient('8', Material.TRIPWIRE_HOOK);
|
||||
Bukkit.addRecipe(motionRecipe);
|
||||
}
|
||||
|
||||
public void checkDaylightSensors() {
|
||||
@@ -146,25 +225,89 @@ public class ButtonControl extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
// Play note block sound for doorbell
|
||||
public void checkMotionSensors() {
|
||||
long now = System.currentTimeMillis();
|
||||
List<String> allControllers = dataManager.getAllPlacedControllers();
|
||||
for (String controllerLoc : allControllers) {
|
||||
String[] parts = controllerLoc.split(",");
|
||||
if (parts.length != 4) continue;
|
||||
|
||||
World world = getServer().getWorld(parts[0]);
|
||||
if (world == null) continue;
|
||||
|
||||
Location loc = new Location(world,
|
||||
Integer.parseInt(parts[1]),
|
||||
Integer.parseInt(parts[2]),
|
||||
Integer.parseInt(parts[3]));
|
||||
|
||||
Block block = loc.getBlock();
|
||||
if (block.getType() != Material.TRIPWIRE_HOOK) continue;
|
||||
|
||||
String buttonId = dataManager.getButtonIdForPlacedController(controllerLoc);
|
||||
if (buttonId == null) continue;
|
||||
|
||||
// Individuelle Einstellungen für diesen Bewegungsmelder
|
||||
double radius = dataManager.getMotionSensorRadius(controllerLoc);
|
||||
if (radius == -1) radius = configManager.getConfig().getDouble("motion-detection-radius", 5.0);
|
||||
long delay = dataManager.getMotionSensorDelay(controllerLoc);
|
||||
if (delay == -1) delay = configManager.getConfig().getLong("motion-close-delay-ms", 5000L);
|
||||
|
||||
boolean detected = !world.getNearbyEntities(loc, radius, radius, radius, e -> e instanceof Player).isEmpty();
|
||||
|
||||
List<String> connectedBlocks = dataManager.getConnectedBlocks(buttonId);
|
||||
if (connectedBlocks == null || connectedBlocks.isEmpty()) continue;
|
||||
|
||||
if (detected) {
|
||||
setOpenables(connectedBlocks, true);
|
||||
lastMotionDetections.put(controllerLoc, now);
|
||||
} else {
|
||||
Long last = lastMotionDetections.get(controllerLoc);
|
||||
if (last != null && now - last >= delay) {
|
||||
setOpenables(connectedBlocks, false);
|
||||
lastMotionDetections.remove(controllerLoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setOpenables(List<String> connectedBlocks, boolean open) {
|
||||
for (String targetLocStr : connectedBlocks) {
|
||||
String[] targetParts = targetLocStr.split(",");
|
||||
if (targetParts.length != 4) continue;
|
||||
|
||||
World targetWorld = getServer().getWorld(targetParts[0]);
|
||||
if (targetWorld == null) continue;
|
||||
|
||||
Location targetLoc = new Location(targetWorld,
|
||||
Integer.parseInt(targetParts[1]),
|
||||
Integer.parseInt(targetParts[2]),
|
||||
Integer.parseInt(targetParts[3]));
|
||||
|
||||
Block targetBlock = targetLoc.getBlock();
|
||||
|
||||
if (targetBlock.getBlockData() instanceof org.bukkit.block.data.Openable) {
|
||||
org.bukkit.block.data.Openable openable = (org.bukkit.block.data.Openable) targetBlock.getBlockData();
|
||||
openable.setOpen(open);
|
||||
targetBlock.setBlockData(openable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void playDoorbellSound(Location loc, String instrument) {
|
||||
Block block = loc.getBlock();
|
||||
if (block.getType() != Material.NOTE_BLOCK) return;
|
||||
|
||||
NoteBlock noteBlock = (NoteBlock) block.getBlockData();
|
||||
try {
|
||||
// Set instrument based on config or player preference
|
||||
org.bukkit.Instrument bukkitInstrument = org.bukkit.Instrument.valueOf(instrument.toUpperCase());
|
||||
noteBlock.setInstrument(bukkitInstrument);
|
||||
noteBlock.setNote(new Note(0, Tone.C, false)); // Default to C note
|
||||
noteBlock.setNote(new Note(0, Tone.C, false));
|
||||
block.setBlockData(noteBlock);
|
||||
loc.getWorld().playSound(loc, bukkitInstrument.getSound(), 1.0f, 1.0f);
|
||||
|
||||
// Check if double note is enabled
|
||||
if (configManager.getConfig().getBoolean("double-note-enabled", true)) {
|
||||
// Schedule the second note after the configured delay in milliseconds
|
||||
int delayMs = configManager.getConfig().getInt("double-note-delay-ms", 1000);
|
||||
long delayTicks = (long) (delayMs / 50.0); // Convert milliseconds to ticks (1000 ms = 20 ticks)
|
||||
long delayTicks = (long) (delayMs / 50.0);
|
||||
getServer().getScheduler().runTaskLater(this, () -> {
|
||||
if (block.getType() == Material.NOTE_BLOCK) {
|
||||
loc.getWorld().playSound(loc, bukkitInstrument.getSound(), 1.0f, 1.0f);
|
||||
@@ -200,7 +343,7 @@ public class ButtonControl extends JavaPlugin {
|
||||
return true;
|
||||
}
|
||||
configManager.reloadConfig();
|
||||
updateConfigWithDefaults(); // Ensure new defaults are added without overwriting
|
||||
updateConfigWithDefaults();
|
||||
dataManager.reloadData();
|
||||
sender.sendMessage(configManager.getMessage("konfiguration-reloaded"));
|
||||
return true;
|
||||
|
@@ -3,7 +3,7 @@ package viper;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.data.type.Door;
|
||||
import org.bukkit.block.data.Openable;
|
||||
import org.bukkit.block.data.Lightable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@@ -35,82 +35,98 @@ public class ButtonListener implements Listener {
|
||||
ItemStack item = event.getItem();
|
||||
Block block = event.getClickedBlock();
|
||||
|
||||
if (event.getAction() == Action.RIGHT_CLICK_BLOCK && block != null &&
|
||||
(block.getType() == Material.STONE_BUTTON || block.getType() == Material.DAYLIGHT_DETECTOR)) {
|
||||
|
||||
// Block wird gesteuert (Button, Tageslichtsensor oder Bewegungsmelder)
|
||||
if (event.getAction() == Action.RIGHT_CLICK_BLOCK && block != null) {
|
||||
String blockLocation = block.getWorld().getName() + "," + block.getX() + "," + block.getY() + "," + block.getZ();
|
||||
String buttonId = dataManager.getButtonIdForPlacedController(playerUUID, blockLocation);
|
||||
|
||||
if (buttonId != null) {
|
||||
event.setCancelled(true);
|
||||
List<String> connectedBlocks = dataManager.getConnectedBlocks(playerUUID, buttonId);
|
||||
if (connectedBlocks != null && !connectedBlocks.isEmpty()) {
|
||||
boolean anyDoorOpened = false;
|
||||
boolean anyDoorClosed = false;
|
||||
boolean anyLampOn = false;
|
||||
boolean anyLampOff = false;
|
||||
boolean anyNoteBlockPlayed = false;
|
||||
|
||||
for (String loc : connectedBlocks) {
|
||||
String[] parts = loc.split(",");
|
||||
Location location = new Location(plugin.getServer().getWorld(parts[0]),
|
||||
Integer.parseInt(parts[1]),
|
||||
Integer.parseInt(parts[2]),
|
||||
Integer.parseInt(parts[3]));
|
||||
Block targetBlock = location.getBlock();
|
||||
if (isDoor(targetBlock.getType())) {
|
||||
Door door = (Door) targetBlock.getBlockData();
|
||||
boolean wasOpen = door.isOpen();
|
||||
door.setOpen(!wasOpen);
|
||||
targetBlock.setBlockData(door);
|
||||
if (!wasOpen) {
|
||||
anyDoorOpened = true;
|
||||
} else {
|
||||
anyDoorClosed = true;
|
||||
}
|
||||
} else if (targetBlock.getType() == Material.REDSTONE_LAMP) {
|
||||
Lightable lamp = (Lightable) targetBlock.getBlockData();
|
||||
boolean wasLit = lamp.isLit();
|
||||
lamp.setLit(!wasLit);
|
||||
targetBlock.setBlockData(lamp);
|
||||
if (!wasLit) {
|
||||
anyLampOn = true;
|
||||
} else {
|
||||
anyLampOff = true;
|
||||
}
|
||||
} else if (targetBlock.getType() == Material.NOTE_BLOCK) {
|
||||
String instrument = dataManager.getPlayerInstrument(event.getPlayer().getUniqueId());
|
||||
if (instrument == null) {
|
||||
instrument = configManager.getConfig().getString("default-note", "PIANO");
|
||||
}
|
||||
plugin.playDoorbellSound(location, instrument);
|
||||
anyNoteBlockPlayed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyDoorOpened) {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("tueren-geoeffnet"));
|
||||
}
|
||||
if (anyDoorClosed) {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("tueren-geschlossen"));
|
||||
}
|
||||
if (anyLampOn) {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("lampen-eingeschaltet"));
|
||||
}
|
||||
if (anyLampOff) {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("lampen-ausgeschaltet"));
|
||||
}
|
||||
if (anyNoteBlockPlayed) {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("notenblock-ausgeloest"));
|
||||
}
|
||||
} else {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("keine-bloecke-verbunden"));
|
||||
// Bewegungsmelder: GUI öffnen
|
||||
if (block.getType() == Material.TRIPWIRE_HOOK) {
|
||||
new MotionSensorGUI(plugin, event.getPlayer(), blockLocation, buttonId).open();
|
||||
return;
|
||||
}
|
||||
// Button oder Tageslichtsensor: Normale Steuerung
|
||||
if (block.getType() == Material.STONE_BUTTON || block.getType() == Material.DAYLIGHT_DETECTOR) {
|
||||
List<String> connectedBlocks = dataManager.getConnectedBlocks(playerUUID, buttonId);
|
||||
if (connectedBlocks != null && !connectedBlocks.isEmpty()) {
|
||||
boolean anyDoorOpened = false;
|
||||
boolean anyDoorClosed = false;
|
||||
boolean anyGateOpened = false;
|
||||
boolean anyGateClosed = false;
|
||||
boolean anyTrapOpened = false;
|
||||
boolean anyTrapClosed = false;
|
||||
boolean anyLampOn = false;
|
||||
boolean anyLampOff = false;
|
||||
boolean anyNoteBlockPlayed = false;
|
||||
boolean anyBellPlayed = false;
|
||||
|
||||
for (String loc : connectedBlocks) {
|
||||
String[] parts = loc.split(",");
|
||||
Location location = new Location(plugin.getServer().getWorld(parts[0]),
|
||||
Integer.parseInt(parts[1]),
|
||||
Integer.parseInt(parts[2]),
|
||||
Integer.parseInt(parts[3]));
|
||||
Block targetBlock = location.getBlock();
|
||||
|
||||
if (isDoor(targetBlock.getType()) || isGate(targetBlock.getType()) || isTrapdoor(targetBlock.getType())) {
|
||||
if (targetBlock.getBlockData() instanceof Openable) {
|
||||
Openable openable = (Openable) targetBlock.getBlockData();
|
||||
boolean wasOpen = openable.isOpen();
|
||||
openable.setOpen(!wasOpen);
|
||||
targetBlock.setBlockData(openable);
|
||||
|
||||
if (isDoor(targetBlock.getType())) {
|
||||
if (!wasOpen) anyDoorOpened = true; else anyDoorClosed = true;
|
||||
} else if (isGate(targetBlock.getType())) {
|
||||
if (!wasOpen) anyGateOpened = true; else anyGateClosed = true;
|
||||
} else if (isTrapdoor(targetBlock.getType())) {
|
||||
if (!wasOpen) anyTrapOpened = true; else anyTrapClosed = true;
|
||||
}
|
||||
}
|
||||
} else if (targetBlock.getType() == Material.REDSTONE_LAMP) {
|
||||
Lightable lamp = (Lightable) targetBlock.getBlockData();
|
||||
boolean wasLit = lamp.isLit();
|
||||
lamp.setLit(!wasLit);
|
||||
targetBlock.setBlockData(lamp);
|
||||
if (!wasLit) anyLampOn = true; else anyLampOff = true;
|
||||
} else if (targetBlock.getType() == Material.NOTE_BLOCK) {
|
||||
String instrument = dataManager.getPlayerInstrument(event.getPlayer().getUniqueId());
|
||||
if (instrument == null) {
|
||||
instrument = configManager.getConfig().getString("default-note", "PIANO");
|
||||
}
|
||||
plugin.playDoorbellSound(location, instrument);
|
||||
anyNoteBlockPlayed = true;
|
||||
} else if (targetBlock.getType() == Material.BELL) {
|
||||
targetBlock.getWorld().playSound(location, org.bukkit.Sound.BLOCK_BELL_USE, 3.0f, 1.0f);
|
||||
anyBellPlayed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (anyDoorOpened) event.getPlayer().sendMessage(configManager.getMessage("tueren-geoeffnet"));
|
||||
if (anyDoorClosed) event.getPlayer().sendMessage(configManager.getMessage("tueren-geschlossen"));
|
||||
if (anyGateOpened) event.getPlayer().sendMessage(configManager.getMessage("gates-geoeffnet"));
|
||||
if (anyGateClosed) event.getPlayer().sendMessage(configManager.getMessage("gates-geschlossen"));
|
||||
if (anyTrapOpened) event.getPlayer().sendMessage(configManager.getMessage("fallturen-geoeffnet"));
|
||||
if (anyTrapClosed) event.getPlayer().sendMessage(configManager.getMessage("fallturen-geschlossen"));
|
||||
if (anyLampOn) event.getPlayer().sendMessage(configManager.getMessage("lampen-eingeschaltet"));
|
||||
if (anyLampOff) event.getPlayer().sendMessage(configManager.getMessage("lampen-ausgeschaltet"));
|
||||
if (anyNoteBlockPlayed) event.getPlayer().sendMessage(configManager.getMessage("notenblock-ausgeloest"));
|
||||
if (anyBellPlayed) event.getPlayer().sendMessage(configManager.getMessage("glocke-gelaeutet"));
|
||||
} else {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("keine-bloecke-verbunden"));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (item == null || (!item.getType().equals(Material.STONE_BUTTON) && !item.getType().equals(Material.DAYLIGHT_DETECTOR) && !item.getType().equals(Material.NOTE_BLOCK))) {
|
||||
// Verbindung herstellen
|
||||
if (item == null || (!item.getType().equals(Material.STONE_BUTTON) &&
|
||||
!item.getType().equals(Material.DAYLIGHT_DETECTOR) &&
|
||||
!item.getType().equals(Material.NOTE_BLOCK) &&
|
||||
!item.getType().equals(Material.TRIPWIRE_HOOK))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -122,7 +138,11 @@ public class ButtonListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isDoor(block.getType()) || block.getType() == Material.REDSTONE_LAMP || block.getType() == Material.NOTE_BLOCK) {
|
||||
if (isDoor(block.getType()) || isGate(block.getType()) || isTrapdoor(block.getType()) ||
|
||||
block.getType() == Material.REDSTONE_LAMP ||
|
||||
block.getType() == Material.NOTE_BLOCK ||
|
||||
block.getType() == Material.BELL) {
|
||||
|
||||
event.setCancelled(true);
|
||||
|
||||
String buttonId = item.getItemMeta().hasLore() ? item.getItemMeta().getLore().get(0) : UUID.randomUUID().toString();
|
||||
@@ -132,16 +152,31 @@ public class ButtonListener implements Listener {
|
||||
}
|
||||
|
||||
int maxDoors = configManager.getMaxDoors();
|
||||
int maxGates = configManager.getMaxDoors();
|
||||
int maxTraps = configManager.getMaxDoors();
|
||||
int maxLamps = configManager.getMaxLamps();
|
||||
int maxNoteBlocks = configManager.getMaxNoteBlocks();
|
||||
int maxBells = configManager.getMaxBells();
|
||||
|
||||
int doorCount = (int) connectedBlocks.stream().filter(loc -> isDoor(getMaterialFromLocation(loc))).count();
|
||||
int gateCount = (int) connectedBlocks.stream().filter(loc -> isGate(getMaterialFromLocation(loc))).count();
|
||||
int trapCount = (int) connectedBlocks.stream().filter(loc -> isTrapdoor(getMaterialFromLocation(loc))).count();
|
||||
int lampCount = (int) connectedBlocks.stream().filter(loc -> getMaterialFromLocation(loc) == Material.REDSTONE_LAMP).count();
|
||||
int noteBlockCount = (int) connectedBlocks.stream().filter(loc -> getMaterialFromLocation(loc) == Material.NOTE_BLOCK).count();
|
||||
int bellCount = (int) connectedBlocks.stream().filter(loc -> getMaterialFromLocation(loc) == Material.BELL).count();
|
||||
|
||||
if (isDoor(block.getType()) && doorCount >= maxDoors) {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("max-tueren-erreicht"));
|
||||
return;
|
||||
}
|
||||
if (isGate(block.getType()) && gateCount >= maxGates) {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("max-gates-erreicht"));
|
||||
return;
|
||||
}
|
||||
if (isTrapdoor(block.getType()) && trapCount >= maxTraps) {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("max-fallturen-erreicht"));
|
||||
return;
|
||||
}
|
||||
if (block.getType() == Material.REDSTONE_LAMP && lampCount >= maxLamps) {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("max-lampen-erreicht"));
|
||||
return;
|
||||
@@ -150,6 +185,10 @@ public class ButtonListener implements Listener {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("max-notenbloecke-erreicht"));
|
||||
return;
|
||||
}
|
||||
if (block.getType() == Material.BELL && bellCount >= maxBells) {
|
||||
event.getPlayer().sendMessage(configManager.getMessage("max-glocken-erreicht"));
|
||||
return;
|
||||
}
|
||||
|
||||
String blockLocation = block.getWorld().getName() + "," + block.getX() + "," + block.getY() + "," + block.getZ();
|
||||
if (!connectedBlocks.contains(blockLocation)) {
|
||||
@@ -169,7 +208,10 @@ public class ButtonListener implements Listener {
|
||||
ItemStack item = event.getItemInHand();
|
||||
Block block = event.getBlockPlaced();
|
||||
|
||||
if (item == null || (!item.getType().equals(Material.STONE_BUTTON) && !item.getType().equals(Material.DAYLIGHT_DETECTOR) && !item.getType().equals(Material.NOTE_BLOCK))) {
|
||||
if (item == null || (!item.getType().equals(Material.STONE_BUTTON) &&
|
||||
!item.getType().equals(Material.DAYLIGHT_DETECTOR) &&
|
||||
!item.getType().equals(Material.NOTE_BLOCK) &&
|
||||
!item.getType().equals(Material.TRIPWIRE_HOOK))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -193,6 +235,7 @@ public class ButtonListener implements Listener {
|
||||
if (buttonId != null) {
|
||||
dataManager.removePlacedController(playerUUID, blockLocation);
|
||||
dataManager.setConnectedBlocks(playerUUID, buttonId, null);
|
||||
dataManager.removeMotionSensorSettings(blockLocation); // Entferne Bewegungsmelder-Einstellungen
|
||||
event.getPlayer().sendMessage(configManager.getMessage("controller-entfernt"));
|
||||
}
|
||||
}
|
||||
@@ -201,6 +244,14 @@ public class ButtonListener implements Listener {
|
||||
return material.toString().endsWith("_DOOR");
|
||||
}
|
||||
|
||||
private boolean isGate(Material material) {
|
||||
return material.toString().endsWith("_FENCE_GATE");
|
||||
}
|
||||
|
||||
private boolean isTrapdoor(Material material) {
|
||||
return material.toString().endsWith("_TRAPDOOR");
|
||||
}
|
||||
|
||||
private Material getMaterialFromLocation(String locString) {
|
||||
String[] parts = locString.split(",");
|
||||
if (parts.length != 4) return null;
|
||||
|
@@ -3,8 +3,8 @@ package viper;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class ConfigManager {
|
||||
private final ButtonControl plugin;
|
||||
@@ -25,7 +25,8 @@ public class ConfigManager {
|
||||
plugin.saveResource("config.yml", false);
|
||||
}
|
||||
config = YamlConfiguration.loadConfiguration(configFile);
|
||||
// Setze Standardwerte, falls sie fehlen
|
||||
|
||||
mergeDefaults(config, "config.yml", configFile);
|
||||
setConfigDefaults();
|
||||
}
|
||||
|
||||
@@ -35,116 +36,113 @@ public class ConfigManager {
|
||||
plugin.saveResource("lang.yml", false);
|
||||
}
|
||||
lang = YamlConfiguration.loadConfiguration(langFile);
|
||||
// Setze Standardnachrichten, falls sie fehlen
|
||||
|
||||
mergeDefaults(lang, "lang.yml", langFile);
|
||||
setLangDefaults();
|
||||
}
|
||||
|
||||
private void mergeDefaults(FileConfiguration file, String resourceName, File targetFile) {
|
||||
try (InputStream is = plugin.getResource(resourceName);
|
||||
InputStreamReader reader = new InputStreamReader(is, StandardCharsets.UTF_8)) {
|
||||
if (is == null) {
|
||||
plugin.getLogger().warning(resourceName + " nicht im Plugin-Jar gefunden, Merge übersprungen.");
|
||||
return;
|
||||
}
|
||||
FileConfiguration defaults = YamlConfiguration.loadConfiguration(reader);
|
||||
boolean changed = false;
|
||||
for (String key : defaults.getKeys(true)) {
|
||||
if (!file.contains(key)) {
|
||||
file.set(key, defaults.get(key));
|
||||
changed = true;
|
||||
plugin.getLogger().info("[ConfigManager] Neuer Key in " + resourceName + " hinzugefügt: " + key);
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
file.save(targetFile);
|
||||
plugin.getLogger().info(resourceName + " wurde mit neuen Standardwerten ergänzt.");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
plugin.getLogger().severe("Fehler beim Mergen von " + resourceName + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void setConfigDefaults() {
|
||||
if (!config.contains("max-doors")) {
|
||||
config.set("max-doors", 20);
|
||||
}
|
||||
if (!config.contains("max-lamps")) {
|
||||
config.set("max-lamps", 50);
|
||||
}
|
||||
if (!config.contains("max-noteblocks")) {
|
||||
config.set("max-noteblocks", 10);
|
||||
}
|
||||
if (!config.contains("default-note")) {
|
||||
config.set("default-note", "PIANO");
|
||||
}
|
||||
if (!config.contains("double-note-enabled")) {
|
||||
config.set("double-note-enabled", true);
|
||||
}
|
||||
if (!config.contains("double-note-delay-ms")) {
|
||||
config.set("double-note-delay-ms", 1000);
|
||||
}
|
||||
if (!config.contains("max-doors")) config.set("max-doors", 20);
|
||||
if (!config.contains("max-lamps")) config.set("max-lamps", 50);
|
||||
if (!config.contains("max-noteblocks")) config.set("max-noteblocks", 10);
|
||||
if (!config.contains("max-gates")) config.set("max-gates", 20);
|
||||
if (!config.contains("max-trapdoors")) config.set("max-trapdoors", 20);
|
||||
if (!config.contains("max-bells")) config.set("max-bells", 5);
|
||||
if (!config.contains("default-note")) config.set("default-note", "PIANO");
|
||||
if (!config.contains("double-note-enabled")) config.set("double-note-enabled", true);
|
||||
if (!config.contains("double-note-delay-ms")) config.set("double-note-delay-ms", 1000);
|
||||
if (!config.contains("motion-detection-radius")) config.set("motion-detection-radius", 5.0);
|
||||
if (!config.contains("motion-close-delay-ms")) config.set("motion-close-delay-ms", 5000);
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
private void setLangDefaults() {
|
||||
// Standardnachrichten hinzufügen, ohne bestehende zu überschreiben
|
||||
if (!lang.contains("tueren-geoeffnet")) {
|
||||
lang.set("tueren-geoeffnet", "§aTüren wurden geöffnet.");
|
||||
}
|
||||
if (!lang.contains("tueren-geschlossen")) {
|
||||
lang.set("tueren-geschlossen", "§cTüren wurden geschlossen.");
|
||||
}
|
||||
if (!lang.contains("lampen-eingeschaltet")) {
|
||||
lang.set("lampen-eingeschaltet", "§aLampen wurden eingeschaltet.");
|
||||
}
|
||||
if (!lang.contains("lampen-ausgeschaltet")) {
|
||||
lang.set("lampen-ausgeschaltet", "§cLampen wurden ausgeschaltet.");
|
||||
}
|
||||
if (!lang.contains("bloecke-umgeschaltet")) {
|
||||
lang.set("bloecke-umgeschaltet", "§eBlöcke wurden umgeschaltet.");
|
||||
}
|
||||
if (!lang.contains("keine-bloecke-verbunden")) {
|
||||
lang.set("keine-bloecke-verbunden", "§cKeine Blöcke sind verbunden.");
|
||||
}
|
||||
if (!lang.contains("max-tueren-erreicht")) {
|
||||
lang.set("max-tueren-erreicht", "§cMaximale Anzahl an Türen erreicht.");
|
||||
}
|
||||
if (!lang.contains("max-lampen-erreicht")) {
|
||||
lang.set("max-lampen-erreicht", "§cMaximale Anzahl an Lampen erreicht.");
|
||||
}
|
||||
if (!lang.contains("max-notenbloecke-erreicht")) {
|
||||
lang.set("max-notenbloecke-erreicht", "§cMaximale Anzahl an Notenblöcken erreicht.");
|
||||
}
|
||||
if (!lang.contains("block-verbunden")) {
|
||||
lang.set("block-verbunden", "§aBlock verbunden.");
|
||||
}
|
||||
if (!lang.contains("block-bereits-verbunden")) {
|
||||
lang.set("block-bereits-verbunden", "§cBlock ist bereits verbunden.");
|
||||
}
|
||||
if (!lang.contains("controller-platziert")) {
|
||||
lang.set("controller-platziert", "§aController platziert.");
|
||||
}
|
||||
if (!lang.contains("controller-entfernt")) {
|
||||
lang.set("controller-entfernt", "§cController entfernt.");
|
||||
}
|
||||
if (!lang.contains("notenblock-ausgeloest")) {
|
||||
lang.set("notenblock-ausgeloest", "§aNotenblock-Klingel wurde ausgelöst.");
|
||||
}
|
||||
if (!lang.contains("instrument-gesetzt")) {
|
||||
lang.set("instrument-gesetzt", "§aDein Notenblock-Instrument wurde auf %s gesetzt.");
|
||||
}
|
||||
if (!lang.contains("ungueltiges-instrument")) {
|
||||
lang.set("ungueltiges-instrument", "§cUngültiges Instrument! Verwende: /bc note <Instrument>");
|
||||
}
|
||||
if (!lang.contains("konfiguration-reloaded")) {
|
||||
lang.set("konfiguration-reloaded", "§aKonfiguration und Daten erfolgreich neu geladen!");
|
||||
}
|
||||
if (!lang.contains("keine-berechtigung")) {
|
||||
lang.set("keine-berechtigung", "§cDu hast keine Berechtigung für diesen Befehl!");
|
||||
}
|
||||
if (!lang.contains("tueren-geoeffnet")) lang.set("tueren-geoeffnet", "§aTüren wurden geöffnet.");
|
||||
if (!lang.contains("tueren-geschlossen")) lang.set("tueren-geschlossen", "§cTüren wurden geschlossen.");
|
||||
if (!lang.contains("max-tueren-erreicht")) lang.set("max-tueren-erreicht", "§cMaximale Anzahl an Türen erreicht.");
|
||||
|
||||
if (!lang.contains("lampen-eingeschaltet")) lang.set("lampen-eingeschaltet", "§aLampen wurden eingeschaltet.");
|
||||
if (!lang.contains("lampen-ausgeschaltet")) lang.set("lampen-ausgeschaltet", "§cLampen wurden ausgeschaltet.");
|
||||
if (!lang.contains("max-lampen-erreicht")) lang.set("max-lampen-erreicht", "§cMaximale Anzahl an Lampen erreicht.");
|
||||
|
||||
if (!lang.contains("notenblock-ausgeloest")) lang.set("notenblock-ausgeloest", "§aNotenblock-Klingel wurde ausgelöst.");
|
||||
if (!lang.contains("max-notenbloecke-erreicht")) lang.set("max-notenbloecke-erreicht", "§cMaximale Anzahl an Notenblöcken erreicht.");
|
||||
|
||||
if (!lang.contains("gates-geoeffnet")) lang.set("gates-geoeffnet", "§aZauntore wurden geöffnet.");
|
||||
if (!lang.contains("gates-geschlossen")) lang.set("gates-geschlossen", "§cZauntore wurden geschlossen.");
|
||||
if (!lang.contains("max-gates-erreicht")) lang.set("max-gates-erreicht", "§cMaximale Anzahl an Zauntoren erreicht.");
|
||||
|
||||
if (!lang.contains("fallturen-geoeffnet")) lang.set("fallturen-geoeffnet", "§aFalltüren wurden geöffnet.");
|
||||
if (!lang.contains("fallturen-geschlossen")) lang.set("fallturen-geschlossen", "§cFalltüren wurden geschlossen.");
|
||||
if (!lang.contains("max-fallturen-erreicht")) lang.set("max-fallturen-erreicht", "§cMaximale Anzahl an Falltüren erreicht.");
|
||||
|
||||
if (!lang.contains("glocke-gelaeutet")) lang.set("glocke-gelaeutet", "§eGlocke wurde geläutet.");
|
||||
if (!lang.contains("max-glocken-erreicht")) lang.set("max-glocken-erreicht", "§cMaximale Anzahl an Glocken erreicht.");
|
||||
|
||||
if (!lang.contains("bloecke-umgeschaltet")) lang.set("bloecke-umgeschaltet", "§eBlöcke wurden umgeschaltet.");
|
||||
if (!lang.contains("keine-bloecke-verbunden")) lang.set("keine-bloecke-verbunden", "§cKeine Blöcke sind verbunden.");
|
||||
if (!lang.contains("block-verbunden")) lang.set("block-verbunden", "§aBlock verbunden.");
|
||||
if (!lang.contains("block-bereits-verbunden")) lang.set("block-bereits-verbunden", "§cBlock ist bereits verbunden.");
|
||||
if (!lang.contains("controller-platziert")) lang.set("controller-platziert", "§aController platziert.");
|
||||
if (!lang.contains("controller-entfernt")) lang.set("controller-entfernt", "§cController entfernt.");
|
||||
if (!lang.contains("instrument-gesetzt")) lang.set("instrument-gesetzt", "§aDein Notenblock-Instrument wurde auf %s gesetzt.");
|
||||
if (!lang.contains("ungueltiges-instrument")) lang.set("ungueltiges-instrument", "§cUngültiges Instrument! Verwende: /bc note <Instrument>");
|
||||
if (!lang.contains("konfiguration-reloaded")) lang.set("konfiguration-reloaded", "§aKonfiguration und Daten erfolgreich neu geladen!");
|
||||
if (!lang.contains("keine-berechtigung")) lang.set("keine-berechtigung", "§cDu hast keine Berechtigung für diesen Befehl!");
|
||||
if (!lang.contains("kolben-ausgefahren")) lang.set("kolben-ausgefahren", "§6[ButtonControl] §7Kolben wurden ausgefahren.");
|
||||
if (!lang.contains("kolben-eingefahren")) lang.set("kolben-eingefahren", "§6[ButtonControl] §7Kolben wurden eingezogen.");
|
||||
if (!lang.contains("max-kolben-erreicht")) lang.set("max-kolben-erreicht", "§6[ButtonControl] §7Maximale Anzahl an Kolben erreicht.");
|
||||
|
||||
saveLang();
|
||||
}
|
||||
|
||||
public void reloadConfig() {
|
||||
config = YamlConfiguration.loadConfiguration(configFile);
|
||||
lang = YamlConfiguration.loadConfiguration(langFile);
|
||||
setConfigDefaults(); // Stelle sicher, dass neue Standardwerte hinzugefügt werden
|
||||
setLangDefaults(); // Stelle sicher, dass neue Nachrichten hinzugefügt werden
|
||||
mergeDefaults(config, "config.yml", configFile);
|
||||
mergeDefaults(lang, "lang.yml", langFile);
|
||||
setConfigDefaults();
|
||||
setLangDefaults();
|
||||
}
|
||||
|
||||
public FileConfiguration getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public int getMaxDoors() {
|
||||
return config.getInt("max-doors", 20);
|
||||
}
|
||||
|
||||
public int getMaxLamps() {
|
||||
return config.getInt("max-lamps", 50);
|
||||
}
|
||||
|
||||
public int getMaxNoteBlocks() {
|
||||
return config.getInt("max-noteblocks", 10);
|
||||
}
|
||||
public int getMaxDoors() { return config.getInt("max-doors", 20); }
|
||||
public int getMaxLamps() { return config.getInt("max-lamps", 50); }
|
||||
public int getMaxNoteBlocks() { return config.getInt("max-noteblocks", 10); }
|
||||
public int getMaxGates() { return config.getInt("max-gates", getMaxDoors()); }
|
||||
public int getMaxTrapdoors() { return config.getInt("max-trapdoors", getMaxDoors()); }
|
||||
public int getMaxBells() { return config.getInt("max-bells", 5); }
|
||||
|
||||
public String getMessage(String key) {
|
||||
return lang.getString(key, "Nachricht nicht gefunden: " + key);
|
||||
return lang.getString(key, "§cNachricht nicht gefunden: " + key);
|
||||
}
|
||||
|
||||
public void saveConfig() {
|
||||
|
@@ -32,8 +32,6 @@ public class DataManager {
|
||||
data = YamlConfiguration.loadConfiguration(dataFile);
|
||||
}
|
||||
|
||||
// --- Spielerbasierte Methoden ---
|
||||
|
||||
public List<String> getConnectedBlocks(String playerUUID, String buttonId) {
|
||||
return data.getStringList("players." + playerUUID + ".buttons." + buttonId);
|
||||
}
|
||||
@@ -65,8 +63,6 @@ public class DataManager {
|
||||
return new ArrayList<>(keys);
|
||||
}
|
||||
|
||||
// --- Neue globale Methoden für Tageslichtsensoren etc. ---
|
||||
|
||||
public List<String> getAllPlacedControllers() {
|
||||
List<String> allControllers = new ArrayList<>();
|
||||
if (data.getConfigurationSection("players") == null) {
|
||||
@@ -101,8 +97,6 @@ public class DataManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
// --- Notenblock-Instrument Methoden ---
|
||||
|
||||
public void setPlayerInstrument(UUID playerUUID, String instrument) {
|
||||
data.set("players." + playerUUID.toString() + ".instrument", instrument);
|
||||
saveData();
|
||||
@@ -112,6 +106,30 @@ public class DataManager {
|
||||
return data.getString("players." + playerUUID.toString() + ".instrument");
|
||||
}
|
||||
|
||||
// Bewegungsmelder-Einstellungen
|
||||
public void setMotionSensorRadius(String location, double radius) {
|
||||
data.set("motion-sensors." + location + ".radius", radius);
|
||||
saveData();
|
||||
}
|
||||
|
||||
public double getMotionSensorRadius(String location) {
|
||||
return data.getDouble("motion-sensors." + location + ".radius", -1);
|
||||
}
|
||||
|
||||
public void setMotionSensorDelay(String location, long delay) {
|
||||
data.set("motion-sensors." + location + ".delay", delay);
|
||||
saveData();
|
||||
}
|
||||
|
||||
public long getMotionSensorDelay(String location) {
|
||||
return data.getLong("motion-sensors." + location + ".delay", -1);
|
||||
}
|
||||
|
||||
public void removeMotionSensorSettings(String location) {
|
||||
data.set("motion-sensors." + location, null);
|
||||
saveData();
|
||||
}
|
||||
|
||||
public void saveData() {
|
||||
try {
|
||||
data.save(dataFile);
|
||||
|
14
src/main/java/viper/MetricsHandler.java
Normal file
14
src/main/java/viper/MetricsHandler.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package viper;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
// Import aus dem korrekten verschobenen Package:
|
||||
import org.bstats.bukkit.Metrics;
|
||||
|
||||
public class MetricsHandler {
|
||||
|
||||
private static final int BSTATS_PLUGIN_ID = 26862;
|
||||
|
||||
public static void startMetrics(JavaPlugin plugin) {
|
||||
new Metrics(plugin, BSTATS_PLUGIN_ID);
|
||||
}
|
||||
}
|
153
src/main/java/viper/MotionSensorGUI.java
Normal file
153
src/main/java/viper/MotionSensorGUI.java
Normal file
@@ -0,0 +1,153 @@
|
||||
package viper;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
import org.bukkit.event.inventory.InventoryCloseEvent;
|
||||
import org.bukkit.event.inventory.InventoryDragEvent;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class MotionSensorGUI implements Listener {
|
||||
private final ButtonControl plugin;
|
||||
private final DataManager dataManager;
|
||||
private final ConfigManager configManager;
|
||||
private final String blockLocation;
|
||||
private final String buttonId;
|
||||
private final Player player;
|
||||
private final Inventory inv;
|
||||
|
||||
public MotionSensorGUI(ButtonControl plugin, Player player, String blockLocation, String buttonId) {
|
||||
this.plugin = plugin;
|
||||
this.dataManager = plugin.getDataManager();
|
||||
this.configManager = plugin.getConfigManager();
|
||||
this.blockLocation = blockLocation;
|
||||
this.buttonId = buttonId;
|
||||
this.player = player;
|
||||
this.inv = Bukkit.createInventory(player, 27, "Bewegungsmelder Einstellungen");
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
public void open() {
|
||||
// Aktuelle Werte aus DataManager holen oder Standardwerte aus Config
|
||||
double radius = dataManager.getMotionSensorRadius(blockLocation);
|
||||
if (radius == -1) radius = configManager.getConfig().getDouble("motion-detection-radius", 5.0);
|
||||
long delay = dataManager.getMotionSensorDelay(blockLocation);
|
||||
if (delay == -1) delay = configManager.getConfig().getLong("motion-close-delay-ms", 5000L);
|
||||
|
||||
// Füllitems für leere Slots (graue Glasscheiben)
|
||||
ItemStack filler = new ItemStack(Material.GRAY_STAINED_GLASS_PANE);
|
||||
ItemMeta fillerMeta = filler.getItemMeta();
|
||||
fillerMeta.setDisplayName(ChatColor.RESET + "");
|
||||
filler.setItemMeta(fillerMeta);
|
||||
for (int i = 0; i < 27; i++) {
|
||||
inv.setItem(i, filler);
|
||||
}
|
||||
|
||||
// Items für die GUI
|
||||
ItemStack radiusItem = new ItemStack(Material.COMPASS);
|
||||
ItemMeta radiusMeta = radiusItem.getItemMeta();
|
||||
radiusMeta.setDisplayName(ChatColor.GREEN + "Erkennungsradius: " + radius + " Blöcke");
|
||||
radiusMeta.setLore(Arrays.asList(
|
||||
ChatColor.GRAY + "Linksklick: +0.5 Blöcke",
|
||||
ChatColor.GRAY + "Rechtsklick: -0.5 Blöcke"
|
||||
));
|
||||
radiusItem.setItemMeta(radiusMeta);
|
||||
|
||||
ItemStack delayItem = new ItemStack(Material.CLOCK);
|
||||
ItemMeta delayMeta = delayItem.getItemMeta();
|
||||
delayMeta.setDisplayName(ChatColor.GREEN + "Schließverzögerung: " + (delay / 1000.0) + " Sekunden");
|
||||
delayMeta.setLore(Arrays.asList(
|
||||
ChatColor.GRAY + "Linksklick: +1 Sekunde",
|
||||
ChatColor.GRAY + "Rechtsklick: -1 Sekunde"
|
||||
));
|
||||
delayItem.setItemMeta(delayMeta);
|
||||
|
||||
ItemStack saveItem = new ItemStack(Material.EMERALD);
|
||||
ItemMeta saveMeta = saveItem.getItemMeta();
|
||||
saveMeta.setDisplayName(ChatColor.GREEN + "Speichern und Schließen");
|
||||
saveItem.setItemMeta(saveMeta);
|
||||
|
||||
// Items in die GUI setzen
|
||||
inv.setItem(11, radiusItem);
|
||||
inv.setItem(15, delayItem);
|
||||
inv.setItem(22, saveItem);
|
||||
|
||||
player.openInventory(inv);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClick(InventoryClickEvent event) {
|
||||
if (!event.getInventory().equals(inv) || !event.getWhoClicked().equals(player)) return;
|
||||
if (event.getCurrentItem() == null) return;
|
||||
|
||||
event.setCancelled(true); // Alle Klicks standardmäßig abbrechen
|
||||
|
||||
int slot = event.getRawSlot();
|
||||
ItemStack clicked = event.getCurrentItem();
|
||||
|
||||
// Nur Klicks auf Slots 11, 15 und 22 verarbeiten
|
||||
if (slot != 11 && slot != 15 && slot != 22) return;
|
||||
|
||||
double radius = dataManager.getMotionSensorRadius(blockLocation);
|
||||
if (radius == -1) radius = configManager.getConfig().getDouble("motion-detection-radius", 5.0);
|
||||
long delay = dataManager.getMotionSensorDelay(blockLocation);
|
||||
if (delay == -1) delay = configManager.getConfig().getLong("motion-close-delay-ms", 5000L);
|
||||
|
||||
if (clicked.getType() == Material.COMPASS && slot == 11) {
|
||||
if (event.isLeftClick()) {
|
||||
radius = Math.min(radius + 0.5, 20.0); // Max. Radius: 20 Blöcke
|
||||
} else if (event.isRightClick()) {
|
||||
radius = Math.max(radius - 0.5, 0.5); // Min. Radius: 0.5 Blöcke
|
||||
}
|
||||
dataManager.setMotionSensorRadius(blockLocation, radius);
|
||||
ItemMeta meta = clicked.getItemMeta();
|
||||
meta.setDisplayName(ChatColor.GREEN + "Erkennungsradius: " + radius + " Blöcke");
|
||||
meta.setLore(Arrays.asList(
|
||||
ChatColor.GRAY + "Linksklick: +0.5 Blöcke",
|
||||
ChatColor.GRAY + "Rechtsklick: -0.5 Blöcke"
|
||||
));
|
||||
clicked.setItemMeta(meta);
|
||||
inv.setItem(11, clicked);
|
||||
} else if (clicked.getType() == Material.CLOCK && slot == 15) {
|
||||
if (event.isLeftClick()) {
|
||||
delay = Math.min(delay + 1000, 30000); // Max. Verzögerung: 30 Sekunden
|
||||
} else if (event.isRightClick()) {
|
||||
delay = Math.max(delay - 1000, 1000); // Min. Verzögerung: 1 Sekunde
|
||||
}
|
||||
dataManager.setMotionSensorDelay(blockLocation, delay);
|
||||
ItemMeta meta = clicked.getItemMeta();
|
||||
meta.setDisplayName(ChatColor.GREEN + "Schließverzögerung: " + (delay / 1000.0) + " Sekunden");
|
||||
meta.setLore(Arrays.asList(
|
||||
ChatColor.GRAY + "Linksklick: +1 Sekunde",
|
||||
ChatColor.GRAY + "Rechtsklick: -1 Sekunde"
|
||||
));
|
||||
clicked.setItemMeta(meta);
|
||||
inv.setItem(15, clicked);
|
||||
} else if (clicked.getType() == Material.EMERALD && slot == 22) {
|
||||
player.closeInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryDrag(InventoryDragEvent event) {
|
||||
if (!event.getInventory().equals(inv) || !event.getWhoClicked().equals(player)) return;
|
||||
event.setCancelled(true); // Verhindert Drag-and-Drop
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryClose(InventoryCloseEvent event) {
|
||||
if (event.getPlayer().equals(player) && event.getInventory().equals(inv)) {
|
||||
InventoryClickEvent.getHandlerList().unregister(this);
|
||||
InventoryDragEvent.getHandlerList().unregister(this);
|
||||
InventoryCloseEvent.getHandlerList().unregister(this);
|
||||
}
|
||||
}
|
||||
}
|
42
src/main/java/viper/UpdateChecker.java
Normal file
42
src/main/java/viper/UpdateChecker.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package viper;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.Scanner;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.json.JSONObject; // -> Dependency in pom.xml nötig
|
||||
|
||||
public class UpdateChecker {
|
||||
|
||||
private final JavaPlugin plugin;
|
||||
private final int resourceId;
|
||||
|
||||
public UpdateChecker(JavaPlugin plugin, int resourceId) {
|
||||
this.plugin = plugin;
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
public void getVersion(final Consumer<String> consumer) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> {
|
||||
try {
|
||||
HttpURLConnection connection = (HttpURLConnection)
|
||||
new URL("https://api.spiget.org/v2/resources/" + resourceId + "/versions/latest").openConnection();
|
||||
connection.setRequestMethod("GET");
|
||||
connection.addRequestProperty("User-Agent", "Mozilla/5.0");
|
||||
try (Scanner scanner = new Scanner(connection.getInputStream())) {
|
||||
String response = scanner.useDelimiter("\\A").next();
|
||||
JSONObject json = new JSONObject(response);
|
||||
String version = json.optString("name", "").trim();
|
||||
consumer.accept(version);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
plugin.getLogger().warning("Konnte nicht nach Updates suchen: " + e.getMessage());
|
||||
consumer.accept("");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@@ -1,6 +1,18 @@
|
||||
# Maximale Anzahl an steuerbaren Blöcken pro Controller
|
||||
max-doors: 20
|
||||
max-lamps: 50
|
||||
max-noteblocks: 10
|
||||
default-note: PIANO
|
||||
max-gates: 20
|
||||
max-trapdoors: 20
|
||||
max-bells: 5
|
||||
|
||||
# Standard-Instrument für Notenblöcke
|
||||
default-note: "PIANO"
|
||||
|
||||
# Doppelter Notenblock-Ton
|
||||
double-note-enabled: true
|
||||
double-note-delay-ms: 1000
|
||||
double-note-delay-ms: 1000
|
||||
|
||||
# Bewegungsmelder-Einstellungen
|
||||
motion-detection-radius: 5.0
|
||||
motion-close-delay-ms: 5000
|
@@ -1,18 +1,39 @@
|
||||
tueren-geoeffnet: "§aTüren wurden geöffnet."
|
||||
tueren-geschlossen: "§cTüren wurden geschlossen."
|
||||
|
||||
gates-geoeffnet: "§aZauntore wurden geöffnet."
|
||||
gates-geschlossen: "§cZauntore wurden geschlossen."
|
||||
max-gates-erreicht: "§cMaximale Anzahl an Zauntoren erreicht."
|
||||
|
||||
fallturen-geoeffnet: "§aFalltüren wurden geöffnet."
|
||||
fallturen-geschlossen: "§cFalltüren wurden geschlossen."
|
||||
max-fallturen-erreicht: "§cMaximale Anzahl an Falltüren erreicht."
|
||||
|
||||
lampen-eingeschaltet: "§aLampen wurden eingeschaltet."
|
||||
lampen-ausgeschaltet: "§cLampen wurden ausgeschaltet."
|
||||
|
||||
bloecke-umgeschaltet: "§eBlöcke wurden umgeschaltet."
|
||||
keine-bloecke-verbunden: "§cKeine Blöcke sind verbunden."
|
||||
|
||||
max-tueren-erreicht: "§cMaximale Anzahl an Türen erreicht."
|
||||
max-lampen-erreicht: "§cMaximale Anzahl an Lampen erreicht."
|
||||
max-notenbloecke-erreicht: "§cMaximale Anzahl an Notenblöcken erreicht."
|
||||
|
||||
max-glocken-erreicht: "§cMaximale Anzahl an Glocken erreicht."
|
||||
glocke-gelaeutet: "§aGlocke wurde geläutet."
|
||||
|
||||
block-verbunden: "§aBlock verbunden."
|
||||
block-bereits-verbunden: "§cBlock ist bereits verbunden."
|
||||
controller-platziert: "§aController platziert."
|
||||
controller-entfernt: "§cController entfernt."
|
||||
|
||||
notenblock-ausgeloest: "§aNotenblock-Klingel wurde ausgelöst."
|
||||
instrument-gesetzt: "§aDein Notenblock-Instrument wurde auf %s gesetzt."
|
||||
ungueltiges-instrument: "§cUngültiges Instrument! Verwende: /bc note <Instrument>"
|
||||
|
||||
konfiguration-neugeladen: "§aKonfiguration und Daten erfolgreich neu geladen!"
|
||||
keine-berechtigung: "§cDu hast keine Berechtigung für diesen Befehl!"
|
||||
keine-berechtigung: "§cDu hast keine Berechtigung für diesen Befehl!"
|
||||
|
||||
kolben-ausgefahren: "§6[ButtonControl] §7Kolben wurden ausgefahren."
|
||||
kolben-eingefahren: "§6[ButtonControl] §7Kolben wurden eingefahren."
|
||||
max-kolben-erreicht: "§6[ButtonControl] §7Maximale Anzahl an Kolben erreicht."
|
||||
|
@@ -1,7 +1,7 @@
|
||||
name: ButtonControl
|
||||
version: 1.1
|
||||
version: 1.4
|
||||
main: viper.ButtonControl
|
||||
api-version: 1.21
|
||||
api-version: 1.18
|
||||
author: viper
|
||||
description: Ein Plugin, um Türen, Redstone-Lampen und Notenblöcke mit einem Button oder Tageslichtsensor zu steuern.
|
||||
|
||||
|
Reference in New Issue
Block a user