diff --git a/pom.xml b/pom.xml
index 76b27d7..e2c69ac 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
com.rsscripting
RS-ServerAdmin
RS-ServerAdmin
- 1.4.0
+ 1.4.1
21
diff --git a/src/main/java/com/rsscripting/serveradmin/RSServerAdmin.java b/src/main/java/com/rsscripting/serveradmin/RSServerAdmin.java
index e50ab43..6cb431f 100644
--- a/src/main/java/com/rsscripting/serveradmin/RSServerAdmin.java
+++ b/src/main/java/com/rsscripting/serveradmin/RSServerAdmin.java
@@ -102,10 +102,16 @@ public class RSServerAdmin extends JavaPlugin {
SettingKey.CREEPER_ENTITY_DAMAGE
);
+ boolean disableFuseDefault =
+ settingsDAO.getDefault(
+ SettingKey.CREEPER_DISABLE_FUSE
+ );
+
creeperSettingsDAO.ensureWorldExists(
world.getName(),
blockDamageDefault,
- entityDamageDefault
+ entityDamageDefault,
+ disableFuseDefault
);
equipmentDropSettingsDAO.ensureWorldExists(
@@ -148,6 +154,16 @@ public class RSServerAdmin extends JavaPlugin {
this
);
+ getServer().getPluginManager().registerEvents(
+ new CreeperDisableFuseListener(),
+ this
+ );
+
+ getServer().getPluginManager().registerEvents(
+ new CreeperMenuListener(),
+ this
+ );
+
getServer().getPluginManager().registerEvents(
new WorldLoadListener(),
this
@@ -158,11 +174,6 @@ public class RSServerAdmin extends JavaPlugin {
this
);
- getServer().getPluginManager().registerEvents(
- new CreeperMenuListener(),
- this
- );
-
getServer().getPluginManager().registerEvents(
new MobEquipmentMenuListener(),
this
diff --git a/src/main/java/com/rsscripting/serveradmin/dao/CreeperSettingsDAO.java b/src/main/java/com/rsscripting/serveradmin/dao/CreeperSettingsDAO.java
index 4776e15..9c253ed 100644
--- a/src/main/java/com/rsscripting/serveradmin/dao/CreeperSettingsDAO.java
+++ b/src/main/java/com/rsscripting/serveradmin/dao/CreeperSettingsDAO.java
@@ -26,6 +26,22 @@ public class CreeperSettingsDAO {
boolean entityDamage
) throws SQLException {
+ ensureWorldExists(
+ worldName,
+ blockDamage,
+ entityDamage,
+ false
+ );
+
+ }
+
+ public void ensureWorldExists(
+ String worldName,
+ boolean blockDamage,
+ boolean entityDamage,
+ boolean disableFuse
+ ) throws SQLException {
+
Connection connection =
databaseManager.getConnection();
@@ -37,9 +53,10 @@ public class CreeperSettingsDAO {
(
world_name,
block_damage,
- entity_damage
+ entity_damage,
+ disable_fuse
)
- VALUES (?, ?, ?)
+ VALUES (?, ?, ?, ?)
"""
)) {
@@ -58,6 +75,11 @@ public class CreeperSettingsDAO {
entityDamage ? 1 : 0
);
+ statement.setInt(
+ 4,
+ disableFuse ? 1 : 0
+ );
+
statement.executeUpdate();
}
@@ -210,4 +232,77 @@ public class CreeperSettingsDAO {
}
+ public boolean getDisableFuse(
+ String worldName
+ ) throws SQLException {
+
+ Connection connection =
+ databaseManager.getConnection();
+
+ try (PreparedStatement statement =
+ connection.prepareStatement(
+ """
+ SELECT disable_fuse
+ FROM creeper_settings
+ WHERE world_name = ?
+ """
+ )) {
+
+ statement.setString(
+ 1,
+ worldName
+ );
+
+ try (ResultSet rs =
+ statement.executeQuery()) {
+
+ if (rs.next()) {
+
+ return rs.getInt(
+ "disable_fuse"
+ ) == 1;
+
+ }
+
+ }
+
+ }
+
+ return false;
+
+ }
+
+ public void setDisableFuse(
+ String worldName,
+ boolean value
+ ) throws SQLException {
+
+ Connection connection =
+ databaseManager.getConnection();
+
+ try (PreparedStatement statement =
+ connection.prepareStatement(
+ """
+ UPDATE creeper_settings
+ SET disable_fuse = ?
+ WHERE world_name = ?
+ """
+ )) {
+
+ statement.setInt(
+ 1,
+ value ? 1 : 0
+ );
+
+ statement.setString(
+ 2,
+ worldName
+ );
+
+ statement.executeUpdate();
+
+ }
+
+ }
+
}
\ No newline at end of file
diff --git a/src/main/java/com/rsscripting/serveradmin/dao/SettingsDAO.java b/src/main/java/com/rsscripting/serveradmin/dao/SettingsDAO.java
index 1f72910..ee222a9 100644
--- a/src/main/java/com/rsscripting/serveradmin/dao/SettingsDAO.java
+++ b/src/main/java/com/rsscripting/serveradmin/dao/SettingsDAO.java
@@ -22,40 +22,68 @@ public class SettingsDAO {
if (!defaultExists(key)) {
- boolean value = getDefaultValue(key);
+ boolean value =
+ getDefaultValue(key);
+
+ setDefault(
+ key,
+ value
+ );
- setDefault(key, value);
}
+
}
+
}
- private boolean defaultExists(SettingKey key) throws SQLException {
+ private boolean defaultExists(
+ SettingKey key
+ ) throws SQLException {
- Connection connection = databaseManager.getConnection();
+ Connection connection =
+ databaseManager.getConnection();
- try (PreparedStatement statement = connection.prepareStatement(
- "SELECT setting_key FROM defaults WHERE setting_key = ?")) {
+ try (PreparedStatement statement =
+ connection.prepareStatement(
+ """
+ SELECT setting_key
+ FROM defaults
+ WHERE setting_key = ?
+ """
+ )) {
- statement.setString(1, key.name());
+ statement.setString(
+ 1,
+ key.name()
+ );
+
+ try (ResultSet rs =
+ statement.executeQuery()) {
- try (ResultSet rs = statement.executeQuery()) {
return rs.next();
+
}
+
}
+
}
- private boolean getDefaultValue(SettingKey key) {
+ private boolean getDefaultValue(
+ SettingKey key
+ ) {
return switch (key) {
- case KEEP_INVENTORY -> true;
-
case CREEPER_BLOCK_DAMAGE,
CREEPER_ENTITY_DAMAGE,
+ CREEPER_DISABLE_FUSE,
KEEP_INVENTORY_NEW_WORLD,
PEACEFUL_MOBS_NEW_WORLD -> false;
+ case KEEP_INVENTORY -> true;
+
};
+
}
public void setDefault(
@@ -63,20 +91,30 @@ public class SettingsDAO {
boolean value
) throws SQLException {
- Connection connection = databaseManager.getConnection();
+ Connection connection =
+ databaseManager.getConnection();
- try (PreparedStatement statement = connection.prepareStatement(
- """
- INSERT OR REPLACE INTO defaults
- (setting_key, value)
- VALUES (?, ?)
- """
- )) {
+ try (PreparedStatement statement =
+ connection.prepareStatement(
+ """
+ INSERT OR REPLACE INTO defaults
+ (setting_key, value)
+ VALUES (?, ?)
+ """
+ )) {
- statement.setString(1, key.name());
- statement.setInt(2, value ? 1 : 0);
+ statement.setString(
+ 1,
+ key.name()
+ );
+
+ statement.setInt(
+ 2,
+ value ? 1 : 0
+ );
statement.executeUpdate();
+
}
}
@@ -107,7 +145,9 @@ public class SettingsDAO {
if (rs.next()) {
- return rs.getInt("value") == 1;
+ return rs.getInt(
+ "value"
+ ) == 1;
}
diff --git a/src/main/java/com/rsscripting/serveradmin/database/DatabaseManager.java b/src/main/java/com/rsscripting/serveradmin/database/DatabaseManager.java
index c62cc60..fe385d7 100644
--- a/src/main/java/com/rsscripting/serveradmin/database/DatabaseManager.java
+++ b/src/main/java/com/rsscripting/serveradmin/database/DatabaseManager.java
@@ -5,6 +5,7 @@ import com.rsscripting.serveradmin.RSServerAdmin;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
+import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
@@ -50,7 +51,8 @@ public class DatabaseManager {
private void createTables() throws SQLException {
- try (Statement statement = connection.createStatement()) {
+ try (Statement statement =
+ connection.createStatement()) {
statement.execute("""
CREATE TABLE IF NOT EXISTS settings (
@@ -62,10 +64,10 @@ public class DatabaseManager {
""");
statement.execute("""
- CREATE TABLE IF NOT EXISTS worlds (
- world_name TEXT PRIMARY KEY
- )
- """);
+ CREATE TABLE IF NOT EXISTS worlds (
+ world_name TEXT PRIMARY KEY
+ )
+ """);
statement.execute("""
CREATE TABLE IF NOT EXISTS defaults (
@@ -74,28 +76,25 @@ public class DatabaseManager {
)
""");
- statement.execute(
- """
- CREATE TABLE IF NOT EXISTS keep_inventory
- (
+ statement.execute("""
+ CREATE TABLE IF NOT EXISTS keep_inventory (
world_name TEXT PRIMARY KEY,
enabled INTEGER NOT NULL
)
- """
- );
+ """);
- statement.execute(
- """
+ statement.execute("""
CREATE TABLE IF NOT EXISTS creeper_settings (
world_name TEXT PRIMARY KEY,
block_damage INTEGER NOT NULL,
- entity_damage INTEGER NOT NULL
+ entity_damage INTEGER NOT NULL,
+ disable_fuse INTEGER NOT NULL DEFAULT 0
)
- """
- );
+ """);
- statement.execute(
- """
+ addDisableFuseColumnIfNeeded();
+
+ statement.execute("""
CREATE TABLE IF NOT EXISTS equipment_drop_settings (
world_name TEXT PRIMARY KEY,
helmet INTEGER NOT NULL,
@@ -105,18 +104,60 @@ public class DatabaseManager {
main_hand INTEGER NOT NULL,
off_hand INTEGER NOT NULL
)
- """
- );
+ """);
- statement.execute(
- """
+ statement.execute("""
CREATE TABLE IF NOT EXISTS peaceful_mobs (
world_name TEXT PRIMARY KEY,
enabled INTEGER NOT NULL
)
- """
- );
+ """);
+ }
+ }
+ private void addDisableFuseColumnIfNeeded()
+ throws SQLException {
+
+ boolean columnExists = false;
+
+ try (Statement statement =
+ connection.createStatement();
+ ResultSet resultSet =
+ statement.executeQuery(
+ "PRAGMA table_info(creeper_settings)"
+ )) {
+
+ while (resultSet.next()) {
+
+ String columnName =
+ resultSet.getString("name");
+
+ if ("disable_fuse".equalsIgnoreCase(
+ columnName
+ )) {
+
+ columnExists = true;
+ break;
+
+ }
+
+ }
+ }
+
+ if (!columnExists) {
+
+ try (Statement statement =
+ connection.createStatement()) {
+
+ statement.execute(
+ """
+ ALTER TABLE creeper_settings
+ ADD COLUMN disable_fuse
+ INTEGER NOT NULL DEFAULT 0
+ """
+ );
+
+ }
}
}
diff --git a/src/main/java/com/rsscripting/serveradmin/gui/CreeperDisableFuseMenu.java b/src/main/java/com/rsscripting/serveradmin/gui/CreeperDisableFuseMenu.java
new file mode 100644
index 0000000..bf10cf1
--- /dev/null
+++ b/src/main/java/com/rsscripting/serveradmin/gui/CreeperDisableFuseMenu.java
@@ -0,0 +1,275 @@
+package com.rsscripting.serveradmin.gui;
+
+import com.rsscripting.serveradmin.RSServerAdmin;
+import com.rsscripting.serveradmin.dao.CreeperSettingsDAO;
+import com.rsscripting.serveradmin.menuholder.RSMenuHolder;
+import com.rsscripting.serveradmin.settings.SettingKey;
+import com.rsscripting.serveradmin.utils.GUIUtils;
+import com.rsscripting.serveradmin.utils.MenuLayoutUtils;
+import org.bukkit.Bukkit;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.persistence.PersistentDataType;
+
+import java.sql.SQLException;
+import java.util.List;
+
+public class CreeperDisableFuseMenu {
+
+ private static final int WORLDS_PER_PAGE = 45;
+
+ public static Inventory create(
+ int page
+ ) throws SQLException {
+
+ RSMenuHolder holder =
+ new RSMenuHolder(
+ "CREEPER_DISABLE_FUSE"
+ );
+
+ holder.setPage(
+ page
+ );
+
+ Inventory inventory =
+ Bukkit.createInventory(
+ holder,
+ 54,
+ "Disable Fuse"
+ );
+
+ GUIUtils.fillEmptySlots(
+ inventory
+ );
+
+ createBackButton(
+ inventory
+ );
+
+ createDefaultButton(
+ inventory
+ );
+
+ populateWorlds(
+ inventory,
+ page
+ );
+
+ return inventory;
+
+ }
+
+ private static void createBackButton(
+ Inventory inventory
+ ) {
+
+ ItemStack item =
+ new ItemStack(
+ Material.ARROW
+ );
+
+ ItemMeta meta =
+ item.getItemMeta();
+
+ if (meta != null) {
+
+ meta.setDisplayName(
+ "§cBack"
+ );
+
+ item.setItemMeta(
+ meta
+ );
+
+ }
+
+ inventory.setItem(
+ 3,
+ item
+ );
+
+ }
+
+ private static void createDefaultButton(
+ Inventory inventory
+ ) throws SQLException {
+
+ boolean enabled =
+ RSServerAdmin.getInstance()
+ .getSettingsDAO()
+ .getDefault(
+ SettingKey.CREEPER_DISABLE_FUSE
+ );
+
+ ItemStack item =
+ new ItemStack(
+ enabled
+ ? Material.ENDER_CHEST
+ : Material.CHEST
+ );
+
+ ItemMeta meta =
+ item.getItemMeta();
+
+ if (meta != null) {
+
+ meta.setDisplayName(
+ "§eDefault For New Worlds"
+ );
+
+ meta.setLore(
+ List.of(
+ "§7Controls newly detected worlds",
+ "",
+ enabled
+ ? "§aCurrent: New worlds prevent creepers from arming"
+ : "§cCurrent: New worlds allow creepers to arm"
+ )
+ );
+
+ item.setItemMeta(
+ meta
+ );
+
+ }
+
+ inventory.setItem(
+ 5,
+ item
+ );
+
+ }
+
+ private static void populateWorlds(
+ Inventory inventory,
+ int page
+ ) throws SQLException {
+
+ CreeperSettingsDAO dao =
+ RSServerAdmin.getInstance()
+ .getCreeperSettingsDAO();
+
+ List worlds =
+ RSServerAdmin.getInstance()
+ .getWorldsDAO()
+ .getAllWorlds();
+
+ int start =
+ (page - 1) * WORLDS_PER_PAGE;
+
+ int end =
+ Math.min(
+ start + WORLDS_PER_PAGE,
+ worlds.size()
+ );
+
+ int worldCount =
+ end - start;
+
+ for (int i = start;
+ i < end;
+ i++) {
+
+ String worldName =
+ worlds.get(i);
+
+ boolean enabled =
+ dao.getDisableFuse(
+ worldName
+ );
+
+ ItemStack item =
+ new ItemStack(
+ enabled
+ ? Material.LIME_SHULKER_BOX
+ : Material.RED_SHULKER_BOX
+ );
+
+ ItemMeta meta =
+ item.getItemMeta();
+
+ if (meta != null) {
+
+ meta.setDisplayName(
+ "§e" + worldName
+ );
+
+ meta.getPersistentDataContainer()
+ .set(
+ new NamespacedKey(
+ RSServerAdmin.getInstance(),
+ "world_name"
+ ),
+ PersistentDataType.STRING,
+ worldName
+ );
+
+ meta.setLore(
+ List.of(
+ "§7Creeper Disable Fuse",
+ "",
+ enabled
+ ? "§aCurrent: Creepers cannot arm"
+ : "§cCurrent: Creepers can arm"
+ )
+ );
+
+ item.setItemMeta(
+ meta
+ );
+
+ }
+
+ int relativeIndex =
+ i - start;
+
+ int row =
+ relativeIndex / 9;
+
+ int indexInRow =
+ relativeIndex % 9;
+
+ int itemsRemaining =
+ worldCount - (row * 9);
+
+ boolean lastPartialRow =
+ itemsRemaining < 9;
+
+ int slot;
+
+ if (lastPartialRow) {
+
+ List rowSlots =
+ MenuLayoutUtils.getCenteredSlots(
+ itemsRemaining
+ );
+
+ slot =
+ 9
+ + (row * 9)
+ + rowSlots.get(
+ indexInRow
+ );
+
+ } else {
+
+ slot =
+ 9
+ + (row * 9)
+ + indexInRow;
+
+ }
+
+ inventory.setItem(
+ slot,
+ item
+ );
+
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/rsscripting/serveradmin/gui/CreeperMenu.java b/src/main/java/com/rsscripting/serveradmin/gui/CreeperMenu.java
index afd4ad7..2bafc3e 100644
--- a/src/main/java/com/rsscripting/serveradmin/gui/CreeperMenu.java
+++ b/src/main/java/com/rsscripting/serveradmin/gui/CreeperMenu.java
@@ -3,14 +3,16 @@ package com.rsscripting.serveradmin.gui;
import com.rsscripting.serveradmin.RSServerAdmin;
import com.rsscripting.serveradmin.menuholder.RSMenuHolder;
import com.rsscripting.serveradmin.settings.SettingKey;
-
import com.rsscripting.serveradmin.utils.GUIUtils;
+
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
+import java.util.List;
+
public class CreeperMenu {
public static Inventory create() {
@@ -27,102 +29,146 @@ public class CreeperMenu {
try {
- try {
+ /*
+ * Block Damage
+ */
- boolean disableBlockDamage =
- RSServerAdmin.getInstance()
- .getSettingsDAO()
- .getDefault(
- SettingKey.CREEPER_BLOCK_DAMAGE
- );
+ boolean disableBlockDamage =
+ RSServerAdmin.getInstance()
+ .getSettingsDAO()
+ .getDefault(
+ SettingKey.CREEPER_BLOCK_DAMAGE
+ );
- ItemStack blockDamage =
- new ItemStack(Material.TNT);
-
- ItemMeta blockMeta =
- blockDamage.getItemMeta();
-
- if (blockMeta != null) {
-
- blockMeta.setDisplayName(
- "§aBlock Damage"
+ ItemStack blockDamage =
+ new ItemStack(
+ Material.TNT
);
- blockMeta.setLore(
- java.util.List.of(
- "§7Disable Creeper damage to blocks",
- "",
- disableBlockDamage
- ? "§aCurrent: Explosion will not damage blocks"
- : "§cCurrent: Explosion will damage blocks"
- )
- );
+ ItemMeta blockMeta =
+ blockDamage.getItemMeta();
- blockDamage.setItemMeta(
- blockMeta
- );
+ if (blockMeta != null) {
- }
-
- inventory.setItem(
- 11,
- blockDamage
+ blockMeta.setDisplayName(
+ "§aBlock Damage"
);
- boolean disableEntityDamage =
- RSServerAdmin.getInstance()
- .getSettingsDAO()
- .getDefault(
- SettingKey.CREEPER_ENTITY_DAMAGE
- );
-
- ItemStack entityDamage =
- new ItemStack(
- Material.TOTEM_OF_UNDYING
- );
-
- ItemMeta entityMeta =
- entityDamage.getItemMeta();
-
- if (entityMeta != null) {
-
- entityMeta.setDisplayName(
- "§aEntity Damage"
- );
-
- entityMeta.setLore(
- java.util.List.of(
- "§7Disable Creeper damage to players and mobs",
- "",
- disableEntityDamage
- ? "§aCurrent: Explosion will not damage entities"
- : "§cCurrent: Explosion will damage entities"
- )
- );
-
- entityDamage.setItemMeta(
- entityMeta
- );
-
- }
-
- inventory.setItem(
- 15,
- entityDamage
+ blockMeta.setLore(
+ List.of(
+ "§7Disable Creeper damage to blocks",
+ "",
+ disableBlockDamage
+ ? "§aCurrent: Explosion will not damage blocks"
+ : "§cCurrent: Explosion will damage blocks"
+ )
);
- } catch (Exception ex) {
-
- RSServerAdmin.getInstance()
- .getLogger()
- .warning(
- "Failed to build Creeper menu: "
- + ex.getMessage()
- );
+ blockDamage.setItemMeta(
+ blockMeta
+ );
}
+ inventory.setItem(
+ 11,
+ blockDamage
+ );
+
+ /*
+ * Disable Fuse
+ */
+
+ boolean disableFuse =
+ RSServerAdmin.getInstance()
+ .getSettingsDAO()
+ .getDefault(
+ SettingKey.CREEPER_DISABLE_FUSE
+ );
+
+ ItemStack disableFuseItem =
+ new ItemStack(
+ Material.FLINT_AND_STEEL
+ );
+
+ ItemMeta fuseMeta =
+ disableFuseItem.getItemMeta();
+
+ if (fuseMeta != null) {
+
+ fuseMeta.setDisplayName(
+ "§aDisable Fuse"
+ );
+
+ fuseMeta.setLore(
+ List.of(
+ "§7Prevent Creepers from arming",
+ "",
+ disableFuse
+ ? "§aCurrent: Creepers cannot arm"
+ : "§cCurrent: Creepers can arm"
+ )
+ );
+
+ disableFuseItem.setItemMeta(
+ fuseMeta
+ );
+
+ }
+
+ inventory.setItem(
+ 21,
+ disableFuseItem
+ );
+
+ /*
+ * Entity Damage
+ */
+
+ boolean disableEntityDamage =
+ RSServerAdmin.getInstance()
+ .getSettingsDAO()
+ .getDefault(
+ SettingKey.CREEPER_ENTITY_DAMAGE
+ );
+
+ ItemStack entityDamage =
+ new ItemStack(
+ Material.TOTEM_OF_UNDYING
+ );
+
+ ItemMeta entityMeta =
+ entityDamage.getItemMeta();
+
+ if (entityMeta != null) {
+
+ entityMeta.setDisplayName(
+ "§aEntity Damage"
+ );
+
+ entityMeta.setLore(
+ List.of(
+ "§7Disable Creeper damage to players and mobs",
+ "",
+ disableEntityDamage
+ ? "§aCurrent: Explosion will not damage entities"
+ : "§cCurrent: Explosion will damage entities"
+ )
+ );
+
+ entityDamage.setItemMeta(
+ entityMeta
+ );
+
+ }
+
+ inventory.setItem(
+ 15,
+ entityDamage
+ );
+
} catch (Exception ex) {
+
RSServerAdmin.getInstance()
.getLogger()
.warning(
@@ -133,7 +179,9 @@ public class CreeperMenu {
}
ItemStack back =
- new ItemStack(Material.ARROW);
+ new ItemStack(
+ Material.ARROW
+ );
ItemMeta backMeta =
back.getItemMeta();
diff --git a/src/main/java/com/rsscripting/serveradmin/listeners/CreeperDisableFuseListener.java b/src/main/java/com/rsscripting/serveradmin/listeners/CreeperDisableFuseListener.java
new file mode 100644
index 0000000..5c3fce9
--- /dev/null
+++ b/src/main/java/com/rsscripting/serveradmin/listeners/CreeperDisableFuseListener.java
@@ -0,0 +1,243 @@
+package com.rsscripting.serveradmin.listeners;
+
+import com.rsscripting.serveradmin.RSServerAdmin;
+import org.bukkit.Bukkit;
+import org.bukkit.entity.Creeper;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.entity.EntityTargetEvent;
+import org.bukkit.event.entity.EntityExplodeEvent;
+import org.bukkit.scheduler.BukkitTask;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+public class CreeperDisableFuseListener implements Listener {
+
+ private final Map activeTasks =
+ new HashMap<>();
+
+ @EventHandler
+ public void onEntityTarget(
+ EntityTargetEvent event
+ ) {
+
+ if (!(event.getEntity() instanceof Creeper creeper)) {
+ return;
+ }
+
+ if (!(event.getTarget() instanceof Player)) {
+ stopTask(
+ creeper.getUniqueId()
+ );
+ return;
+ }
+
+ try {
+
+ String worldName =
+ creeper.getWorld()
+ .getName();
+
+ boolean disableFuse =
+ RSServerAdmin.getInstance()
+ .getCreeperSettingsDAO()
+ .getDisableFuse(
+ worldName
+ );
+
+ if (!disableFuse) {
+ return;
+ }
+
+ startFusePrevention(
+ creeper
+ );
+
+ } catch (Exception ex) {
+
+ RSServerAdmin.getInstance()
+ .getLogger()
+ .warning(
+ "Failed to process Creeper Disable Fuse: "
+ + ex.getMessage()
+ );
+
+ }
+
+ }
+
+ @EventHandler
+ public void onEntityExplode(
+ EntityExplodeEvent event
+ ) {
+
+ if (!(event.getEntity() instanceof Creeper creeper)) {
+ return;
+ }
+
+ try {
+
+ String worldName =
+ creeper.getWorld()
+ .getName();
+
+ boolean disableFuse =
+ RSServerAdmin.getInstance()
+ .getCreeperSettingsDAO()
+ .getDisableFuse(
+ worldName
+ );
+
+ if (!disableFuse) {
+ return;
+ }
+
+ stopTask(
+ creeper.getUniqueId()
+ );
+
+ creeper.setIgnited(
+ false
+ );
+
+ creeper.setFuseTicks(
+ 0
+ );
+
+ event.setCancelled(
+ true
+ );
+
+ } catch (Exception ex) {
+
+ RSServerAdmin.getInstance()
+ .getLogger()
+ .warning(
+ "Failed to prevent Creeper explosion: "
+ + ex.getMessage()
+ );
+
+ }
+
+ }
+
+ private void startFusePrevention(
+ Creeper creeper
+ ) {
+
+ UUID uuid =
+ creeper.getUniqueId();
+
+ if (activeTasks.containsKey(uuid)) {
+ return;
+ }
+
+ BukkitTask task =
+ Bukkit.getScheduler()
+ .runTaskTimer(
+ RSServerAdmin.getInstance(),
+ () -> {
+
+ if (creeper.isDead()
+ || !creeper.isValid()) {
+
+ stopTask(
+ uuid
+ );
+
+ return;
+ }
+
+ try {
+
+ boolean disableFuse =
+ RSServerAdmin.getInstance()
+ .getCreeperSettingsDAO()
+ .getDisableFuse(
+ creeper.getWorld()
+ .getName()
+ );
+
+ if (!disableFuse) {
+
+ stopTask(
+ uuid
+ );
+
+ return;
+ }
+
+ if (!(creeper.getTarget()
+ instanceof Player)) {
+
+ stopTask(
+ uuid
+ );
+
+ return;
+ }
+
+ if (creeper.isIgnited()) {
+
+ creeper.setIgnited(
+ false
+ );
+
+ }
+
+ if (creeper.getFuseTicks() != 0) {
+
+ creeper.setFuseTicks(
+ 0
+ );
+
+ }
+
+ } catch (Exception ex) {
+
+ RSServerAdmin.getInstance()
+ .getLogger()
+ .warning(
+ "Failed to prevent Creeper fuse: "
+ + ex.getMessage()
+ );
+
+ stopTask(
+ uuid
+ );
+
+ }
+
+ },
+ 1L,
+ 1L
+ );
+
+ activeTasks.put(
+ uuid,
+ task
+ );
+
+ }
+
+ private void stopTask(
+ UUID uuid
+ ) {
+
+ BukkitTask task =
+ activeTasks.remove(
+ uuid
+ );
+
+ if (task != null) {
+
+ task.cancel();
+
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/rsscripting/serveradmin/listeners/CreeperMenuListener.java b/src/main/java/com/rsscripting/serveradmin/listeners/CreeperMenuListener.java
index f0ae8b9..c850dc0 100644
--- a/src/main/java/com/rsscripting/serveradmin/listeners/CreeperMenuListener.java
+++ b/src/main/java/com/rsscripting/serveradmin/listeners/CreeperMenuListener.java
@@ -2,9 +2,9 @@ package com.rsscripting.serveradmin.listeners;
import com.rsscripting.serveradmin.RSServerAdmin;
import com.rsscripting.serveradmin.gui.CreeperBlockDamageMenu;
+import com.rsscripting.serveradmin.gui.CreeperDisableFuseMenu;
import com.rsscripting.serveradmin.gui.CreeperEntityDamageMenu;
import com.rsscripting.serveradmin.gui.CreeperMenu;
-import com.rsscripting.serveradmin.gui.MainMenu;
import com.rsscripting.serveradmin.menuholder.RSMenuHolder;
import com.rsscripting.serveradmin.settings.SettingKey;
@@ -82,6 +82,29 @@ public class CreeperMenuListener implements Listener {
}
+ case 21 -> {
+
+ try {
+
+ player.openInventory(
+ CreeperDisableFuseMenu.create(
+ 1
+ )
+ );
+
+ } catch (Exception ex) {
+
+ RSServerAdmin.getInstance()
+ .getLogger()
+ .warning(
+ "Failed to open Creeper Disable Fuse menu: "
+ + ex.getMessage()
+ );
+
+ }
+
+ }
+
case 15 -> {
try {
@@ -381,6 +404,142 @@ public class CreeperMenuListener implements Listener {
}
+ case "CREEPER_DISABLE_FUSE" -> {
+
+ if (!(event.getWhoClicked() instanceof Player player)) {
+ return;
+ }
+
+ switch (event.getSlot()) {
+
+ case 3 -> {
+
+ try {
+
+ player.openInventory(
+ CreeperMenu.create()
+ );
+
+ } catch (Exception ex) {
+
+ RSServerAdmin.getInstance()
+ .getLogger()
+ .warning(
+ "Failed to open Creeper menu: "
+ + ex.getMessage()
+ );
+
+ }
+
+ }
+
+ case 5 -> {
+
+ try {
+
+ RSServerAdmin.getInstance()
+ .getSettingsDAO()
+ .toggleDefault(
+ SettingKey.CREEPER_DISABLE_FUSE
+ );
+
+ player.openInventory(
+ CreeperDisableFuseMenu.create(
+ holder.getPage()
+ )
+ );
+
+ } catch (Exception ex) {
+
+ RSServerAdmin.getInstance()
+ .getLogger()
+ .warning(
+ "Failed to toggle Creeper Disable Fuse default: "
+ + ex.getMessage()
+ );
+
+ }
+
+ }
+
+ default -> {
+
+ if (event.getSlot() < 9) {
+ return;
+ }
+
+ try {
+
+ if (event.getCurrentItem() == null) {
+ return;
+ }
+
+ if (!event.getCurrentItem().hasItemMeta()) {
+ return;
+ }
+
+ ItemMeta meta =
+ event.getCurrentItem()
+ .getItemMeta();
+
+ if (meta == null) {
+ return;
+ }
+
+ String worldName =
+ meta.getPersistentDataContainer()
+ .get(
+ new NamespacedKey(
+ RSServerAdmin.getInstance(),
+ "world_name"
+ ),
+ PersistentDataType.STRING
+ );
+
+ if (worldName == null
+ || worldName.isBlank()) {
+
+ return;
+
+ }
+
+ boolean enabled =
+ RSServerAdmin.getInstance()
+ .getCreeperSettingsDAO()
+ .getDisableFuse(
+ worldName
+ );
+
+ RSServerAdmin.getInstance()
+ .getCreeperSettingsDAO()
+ .setDisableFuse(
+ worldName,
+ !enabled
+ );
+
+ player.openInventory(
+ CreeperDisableFuseMenu.create(
+ holder.getPage()
+ )
+ );
+
+ } catch (Exception ex) {
+
+ RSServerAdmin.getInstance()
+ .getLogger()
+ .warning(
+ "Failed to update Creeper Disable Fuse setting: "
+ + ex.getMessage()
+ );
+
+ }
+
+ }
+
+ }
+
+ }
+
}
}
diff --git a/src/main/java/com/rsscripting/serveradmin/settings/SettingKey.java b/src/main/java/com/rsscripting/serveradmin/settings/SettingKey.java
index a76b759..f6b54e2 100644
--- a/src/main/java/com/rsscripting/serveradmin/settings/SettingKey.java
+++ b/src/main/java/com/rsscripting/serveradmin/settings/SettingKey.java
@@ -4,6 +4,7 @@ public enum SettingKey {
CREEPER_BLOCK_DAMAGE,
CREEPER_ENTITY_DAMAGE,
+ CREEPER_DISABLE_FUSE,
KEEP_INVENTORY_NEW_WORLD,
KEEP_INVENTORY,
PEACEFUL_MOBS_NEW_WORLD
diff --git a/src/main/java/com/rsscripting/serveradmin/utils/WorldSyncUtils.java b/src/main/java/com/rsscripting/serveradmin/utils/WorldSyncUtils.java
index 9af401d..19c4e77 100644
--- a/src/main/java/com/rsscripting/serveradmin/utils/WorldSyncUtils.java
+++ b/src/main/java/com/rsscripting/serveradmin/utils/WorldSyncUtils.java
@@ -36,6 +36,12 @@ public class WorldSyncUtils {
SettingKey.CREEPER_ENTITY_DAMAGE
);
+ boolean disableFuseDefault =
+ plugin.getSettingsDAO()
+ .getDefault(
+ SettingKey.CREEPER_DISABLE_FUSE
+ );
+
boolean peacefulMobsDefault =
plugin.getSettingsDAO()
.getDefault(
@@ -73,7 +79,8 @@ public class WorldSyncUtils {
.ensureWorldExists(
worldName,
blockDamageDefault,
- entityDamageDefault
+ entityDamageDefault,
+ disableFuseDefault
);
plugin.getEquipmentDropSettingsDAO()