Initial RS-ItemMagnet repository

This commit is contained in:
BigPappa committed 2026-08-13 02:14:48 -05:00
commit a642ec43e7
47 files changed
+7344

No files matched your search

@@ -0,0 +1,228 @@
package com.rsscripting.itemmagnet;
import com.rsscripting.itemmagnet.commands.RSPluginCommand;
import com.rsscripting.itemmagnet.commands.RSTabCompleter;
import com.rsscripting.itemmagnet.config.ConfigManager;
import com.rsscripting.itemmagnet.database.DatabaseManager;
import com.rsscripting.itemmagnet.listeners.*;
import com.rsscripting.itemmagnet.tasks.RSErrorTask;
import com.rsscripting.itemmagnet.tasks.RSRadiusPreviewTask;
import com.rsscripting.itemmagnet.utils.GitHubUpdateChecker;
import com.rsscripting.itemmagnet.utils.RSConstants;
import com.rsscripting.itemmagnet.tasks.RSItemMagnetTask;
import org.bukkit.command.PluginCommand;
import org.bukkit.plugin.java.JavaPlugin;
public class RSItemMagnet
extends JavaPlugin {
private static RSItemMagnet instance;
@Override
public void onEnable() {
saveDefaultConfig();
instance = this;
/*
|--------------------------------------------------------------------------
| CONFIG
|--------------------------------------------------------------------------
*/
ConfigManager.setup();
/*
|--------------------------------------------------------------------------
| Database
|--------------------------------------------------------------------------
*/
DatabaseManager.initialize(
this
);
/*
|--------------------------------------------------------------------------
| LISTENERS
|--------------------------------------------------------------------------
*/
/* Convert */
RSConvertListener
conversionListener =
new RSConvertListener();
getServer().getPluginManager().registerEvents(
conversionListener,
this
);
/* Main Menu */
getServer().getPluginManager().registerEvents(
new RSMenuListener(
conversionListener
),
this
);
/* Radius */
RSRadiusListener radiusListener =
new RSRadiusListener(
conversionListener
);
getServer()
.getPluginManager()
.registerEvents(
radiusListener,
this
);
/* Admin */
RSAdminListener adminListener =
new RSAdminListener(
conversionListener
);
getServer()
.getPluginManager()
.registerEvents(
adminListener,
this
);
/* Filter */
RSFilterListener filterListener =
new RSFilterListener(
conversionListener
);
getServer()
.getPluginManager()
.registerEvents(
filterListener,
this
);
getServer()
.getPluginManager()
.registerEvents(
new RSBlockBreakListener(),
this
);
getServer()
.getPluginManager()
.registerEvents(
new RSUpdateNotificationListener(),
this
);
/*
|--------------------------------------------------------------------------
| COMMANDS
|--------------------------------------------------------------------------
*/
PluginCommand command =
getCommand(
RSConstants.COMMAND_ALIAS
);
if (command != null) {
command.setExecutor(
new RSPluginCommand()
);
command.setTabCompleter(
new RSTabCompleter()
);
}
/*
|--------------------------------------------------------------------------
| UPDATE CHECKER
|--------------------------------------------------------------------------
*/
GitHubUpdateChecker.checkForUpdates();
/*
|--------------------------------------------------------------------------
| ENABLE MESSAGE
|--------------------------------------------------------------------------
*/
getLogger().info(
RSConstants.PLUGIN_NAME
+ " Enabled"
);
new RSItemMagnetTask().runTaskTimer(
this,
20L,
20L
);
new RSRadiusPreviewTask()
.runTaskTimer(
this,
0L,
10L
);
new RSErrorTask().runTaskTimer(
this,
100L,
100L
);
}
@Override
public void onDisable() {
getLogger().info(
RSConstants.PLUGIN_NAME
+ " Disabled"
);
}
/*
|--------------------------------------------------------------------------
| GET INSTANCE
|--------------------------------------------------------------------------
*/
public static RSItemMagnet getInstance() {
return instance;
}
}
@@ -0,0 +1,102 @@
package com.rsscripting.itemmagnet.commands;
import com.rsscripting.itemmagnet.config.ConfigManager;
import com.rsscripting.itemmagnet.utils.RSConstants;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public class RSPluginCommand
implements CommandExecutor {
@Override
public boolean onCommand(
@NotNull CommandSender sender,
@NotNull Command command,
@NotNull String label,
@NotNull String @NotNull [] args
) {
/*
|--------------------------------------------------------------------------
| BASE COMMAND
|--------------------------------------------------------------------------
*/
if (args.length == 0) {
sender.sendMessage(
RSConstants.PREFIX
+ "Running "
+ RSConstants.PLUGIN_NAME
);
return true;
}
/*
|--------------------------------------------------------------------------
| RELOAD COMMAND
|--------------------------------------------------------------------------
*/
if (args[0].equalsIgnoreCase(
"reload"
)) {
if (!sender.hasPermission(
RSConstants.ADMIN_PERMISSION
)) {
sender.sendMessage(
RSConstants.PREFIX
+ "No permission."
);
return true;
}
ConfigManager.reload();
sender.sendMessage(
RSConstants.PREFIX
+ "Configuration reloaded."
);
return true;
}
/*
|--------------------------------------------------------------------------
| VERSION COMMAND
|--------------------------------------------------------------------------
*/
if (args[0].equalsIgnoreCase(
"version"
)) {
sender.sendMessage(
RSConstants.PREFIX
+ RSConstants.PLUGIN_NAME
+ " v"
+ RSConstants.VERSION
);
return true;
}
return true;
}
}
@@ -0,0 +1,46 @@
package com.rsscripting.itemmagnet.commands;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
public class RSTabCompleter
implements TabCompleter {
@Override
public List<String> onTabComplete(
@NotNull CommandSender sender,
@NotNull Command command,
@NotNull String label,
@NotNull String @NotNull [] args
) {
List<String> completions =
new ArrayList<>();
/*
|--------------------------------------------------------------------------
| FIRST ARGUMENT
|--------------------------------------------------------------------------
*/
if (args.length == 1) {
completions.add("reload");
completions.add("version");
}
return completions;
}
}
@@ -0,0 +1,247 @@
package com.rsscripting.itemmagnet.config;
import com.rsscripting.itemmagnet.RSItemMagnet;
import org.bukkit.configuration.file.FileConfiguration;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
public class ConfigManager {
private static FileConfiguration config;
/*
|--------------------------------------------------------------------------
| SETUP
|--------------------------------------------------------------------------
*/
public static void setup() {
RSItemMagnet.getInstance()
.saveDefaultConfig();
config =
RSItemMagnet.getInstance()
.getConfig();
/*
|--------------------------------------------------------------------------
| CONFIG UPDATES
|--------------------------------------------------------------------------
*/
boolean updated = false;
if (!config.isSet("item-y-distance")) {
addConfigSetting(
"item-y-distance",
"# Distance in blocks ABOVE and BELOW the magnet\n"
+ "# that items may be collected from.\n"
+ "#\n"
+ "# 0 = Unlimited (legacy behavior)\n"
+ "item-y-distance: 0\n"
);
updated = true;
RSItemMagnet.getInstance()
.getLogger()
.info(
"Added missing config setting: item-y-distance"
);
}
if (!config.isSet("max-target-distance")) {
addConfigSetting(
"max-target-distance",
"# Maximum distance in blocks a target container may be from the ItemMagnet.\n"
+ "# 0 = Unlimited.\n"
+ "max-target-distance: 30\n"
);
updated = true;
RSItemMagnet.getInstance()
.getLogger()
.info(
"Added missing config setting: max-target-distance"
);
}
if (updated) {
RSItemMagnet.getInstance()
.reloadConfig();
config =
RSItemMagnet.getInstance()
.getConfig();
RSItemMagnet.getInstance()
.getLogger()
.info(
"Config updated with missing settings and comments."
);
}
}
private static void addConfigSetting(
String path,
String documentedSetting
) {
Path configPath =
RSItemMagnet.getInstance()
.getDataFolder()
.toPath()
.resolve("config.yml");
try {
String content =
Files.readString(
configPath,
StandardCharsets.UTF_8
);
String newline =
content.contains("\r\n")
? "\r\n"
: "\n";
documentedSetting =
documentedSetting.replace("\n", newline);
String marker =
"# Whether OP players bypass permissions checks";
int markerIndex =
content.indexOf(marker);
if (markerIndex >= 0) {
content =
content.substring(0, markerIndex)
+ documentedSetting
+ newline
+ content.substring(markerIndex);
} else {
if (!content.endsWith("\n")
&& !content.endsWith("\r")) {
content += newline;
}
content += newline + documentedSetting;
}
Files.writeString(
configPath,
content,
StandardCharsets.UTF_8
);
} catch (IOException exception) {
RSItemMagnet.getInstance()
.getLogger()
.warning(
"Failed to add config setting '"
+ path
+ "' with comments: "
+ exception.getMessage()
);
config.set(
path,
path.equals("max-target-distance")
? 30
: 0
);
}
}
/*
|--------------------------------------------------------------------------
| RELOAD
|--------------------------------------------------------------------------
*/
public static void reload() {
RSItemMagnet.getInstance()
.reloadConfig();
config =
RSItemMagnet.getInstance()
.getConfig();
}
/*
|--------------------------------------------------------------------------
| GET CONFIG
|--------------------------------------------------------------------------
*/
public static FileConfiguration get() {
return config;
}
/*
|--------------------------------------------------------------------------
| SETTINGS
|--------------------------------------------------------------------------
*/
public static int getDefaultRadius() {
return config.getInt(
"default-radius"
);
}
public static int getConversionTimeout() {
return config.getInt(
"conversion-timeout"
);
}
public static int getItemYDistance() {
return config.getInt(
"item-y-distance",
0
);
}
public static int getMaxTargetDistance() {
return config.getInt(
"max-target-distance",
30
);
}
}
@@ -0,0 +1,169 @@
package com.rsscripting.itemmagnet.database;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.logging.Level;
public class DatabaseManager {
private static JavaPlugin plugin;
private static String databaseUrl;
public static void initialize(
JavaPlugin pluginInstance
) {
plugin = pluginInstance;
createDatabase();
createTables();
}
private static void createDatabase() {
try {
File databaseFile =
new File(
plugin.getDataFolder(),
"database.db"
);
if (!plugin.getDataFolder().exists()) {
if (!plugin.getDataFolder().mkdirs()) {
plugin.getLogger().severe(
"Failed to create plugin data folder."
);
return;
}
}
databaseUrl =
"jdbc:sqlite:"
+ databaseFile.getAbsolutePath();
Connection connection =
DriverManager.getConnection(
databaseUrl
);
connection.close();
plugin.getLogger().info(
"SQLite database initialized."
);
}
catch (Exception e) {
plugin.getLogger().log(
Level.SEVERE,
"Failed to initialize database.",
e
);
}
}
private static void createTables() {
try (
Connection connection =
DriverManager.getConnection(
databaseUrl
)
) {
connection.createStatement().execute(
"""
CREATE TABLE IF NOT EXISTS machines (
id INTEGER PRIMARY KEY AUTOINCREMENT,
world TEXT NOT NULL,
x INTEGER NOT NULL,
y INTEGER NOT NULL,
z INTEGER NOT NULL,
owner_uuid TEXT,
owner_name TEXT,
machine_type TEXT,
target_world TEXT,
target_x INTEGER,
target_y INTEGER,
target_z INTEGER,
radius INTEGER DEFAULT 5,
paused INTEGER DEFAULT 0,
status TEXT DEFAULT 'RUNNING',
filter_mode TEXT DEFAULT 'ALLOW_ALL',
created_at TEXT
)
"""
);
connection.createStatement().execute(
"""
CREATE TABLE IF NOT EXISTS machine_filters (
id INTEGER PRIMARY KEY AUTOINCREMENT,
machine_id INTEGER NOT NULL,
page INTEGER NOT NULL,
slot INTEGER NOT NULL,
item_data TEXT NOT NULL
)
"""
);
plugin.getLogger().info(
"Database tables initialized."
);
try {
connection.createStatement().execute(
"""
ALTER TABLE machines
ADD COLUMN status TEXT DEFAULT 'RUNNING'
"""
);
}
catch (Exception ignored) {
}
}
catch (Exception e) {
plugin.getLogger().log(
Level.SEVERE,
"Failed to create tables.",
e
);
}
}
public static Connection getConnection()
throws Exception {
return DriverManager.getConnection(
databaseUrl
);
}
}
@@ -0,0 +1,15 @@
package com.rsscripting.itemmagnet.enums;
public enum MachineStatus {
RUNNING,
PAUSED,
NO_TARGET,
TARGET_MISSING,
TARGET_INVALID
}
@@ -0,0 +1,140 @@
package com.rsscripting.itemmagnet.gui;
import com.rsscripting.itemmagnet.utils.RSMenuUtils;
import com.rsscripting.itemmagnet.utils.VersionUtils;
import com.rsscripting.itemmagnet.utils.GitHubUpdateChecker;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import net.kyori.adventure.text.Component;
import java.util.List;
public class RSAdminMenu {
public static final String MENU_TITLE = "Admin";
public static void open(
Player player
) {
Inventory menu =
Bukkit.createInventory(
new RSMenuHolder(
"ADMIN"
),
18,
Component.text(
MENU_TITLE
).color(
NamedTextColor.GOLD
)
);
/*
|--------------------------------------------------------------------------
| FILLER
|--------------------------------------------------------------------------
*/
ItemStack filler =
RSMenuUtils.createFillerPane();
for (int i = 0; i < menu.getSize(); i++) {
menu.setItem(i, filler);
}
/*
|--------------------------------------------------------------------------
| BACK
|--------------------------------------------------------------------------
*/
menu.setItem(
4,
RSMenuUtils.createMenuItem(
Material.OAK_DOOR,
"§eBack"
)
);
/*
|--------------------------------------------------------------------------
| RELOAD
|--------------------------------------------------------------------------
*/
menu.setItem(
12,
RSMenuUtils.createMenuItem(
Material.ENCHANTED_BOOK,
"§cReload Plugin"
)
);
/*
|--------------------------------------------------------------------------
| VERSION
|--------------------------------------------------------------------------
*/
menu.setItem(
14,
RSMenuUtils.createMenuItem(
Material.BOOK,
"§ePlugin Version",
List.of(
"§7Current Version: §f"
+ VersionUtils.getVersion(),
"§7Latest Version: §f"
+ (
GitHubUpdateChecker.getLatestVersion()
== null
? "Unknown"
: GitHubUpdateChecker.getLatestVersion()
),
"",
(
GitHubUpdateChecker.getLatestVersion() == null
|| GitHubUpdateChecker.getLatestVersion()
.equalsIgnoreCase("Unknown")
)
? "§cStatus: Unable To Check"
: (
!VersionUtils.getVersion().equalsIgnoreCase(
GitHubUpdateChecker.getLatestVersion()
)
? "§aStatus: Update Available"
: "§aStatus: Up To Date"
)
)
)
);
player.openInventory(menu);
}
}
@@ -0,0 +1,66 @@
package com.rsscripting.itemmagnet.gui;
import com.rsscripting.itemmagnet.utils.RSMenuUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
public class RSConversionMenu {
public static final String MENU_TITLE = "Activate Item Magnet";
public static void open(
Player player
) {
Inventory menu =
Bukkit.createInventory(
new RSMenuHolder(
"CONVERT"
),
9,
Component.text(
MENU_TITLE
).color(
NamedTextColor.BLUE
)
);
/*
|--------------------------------------------------------------------------
| FILLER
|--------------------------------------------------------------------------
*/
ItemStack filler =
RSMenuUtils.createFillerPane();
for (int i = 0; i < menu.getSize(); i++) {
menu.setItem(i, filler);
}
/*
|--------------------------------------------------------------------------
| CONVERT BUTTON
|--------------------------------------------------------------------------
*/
menu.setItem(
4,
RSMenuUtils.createMenuItem(
Material.CRAFTING_TABLE,
"§aConvert"
)
);
player.openInventory(menu);
}
}
@@ -0,0 +1,227 @@
package com.rsscripting.itemmagnet.gui;
import com.rsscripting.itemmagnet.managers.MachineManager;
import com.rsscripting.itemmagnet.utils.RSKeys;
import com.rsscripting.itemmagnet.utils.RSMenuUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.Map;
public class RSFilterMenu {
public static final String MENU_TITLE =
"Filter";
public static void open(
Player player,
Block block
) {
open(
player,
block,
1
);
}
public static void open(
Player player,
Block block,
int page
) {
RSMenuHolder holder =
new RSMenuHolder(
"FILTER"
);
holder.setPage(
page
);
Inventory menu =
Bukkit.createInventory(
holder,
54,
Component.text(
MENU_TITLE
+ " ["
+ holder.getPage()
+ "]"
).color(
NamedTextColor.BLUE
)
);
/*
|--------------------------------------------------------------------------
| TOP ROW FILLER
|--------------------------------------------------------------------------
*/
ItemStack filler =
RSMenuUtils.createFillerPane();
for (int i = 0; i < 9; i++) {
menu.setItem(
i,
filler
);
}
/*
|--------------------------------------------------------------------------
| FILTER MODE
|--------------------------------------------------------------------------
*/
String filterMode =
MachineManager.getFilterMode(
block
);
Material filterMaterial;
String filterName;
if (filterMode.equals(
RSKeys.FILTER_WHITELIST
)) {
filterMaterial =
Material.WHITE_WOOL;
filterName =
"§aWhitelist";
}
else if (filterMode.equals(
RSKeys.FILTER_BLACKLIST
)) {
filterMaterial =
Material.BLACK_WOOL;
filterName =
"§cBlacklist";
}
else {
filterMaterial =
Material.LIME_WOOL;
filterName =
"§aAllow All";
}
menu.setItem(
3,
RSMenuUtils.createMenuItem(
filterMaterial,
filterName
)
);
/*
|--------------------------------------------------------------------------
| PREVIOUS PAGE
|--------------------------------------------------------------------------
*/
if (holder.getPage() > 1) {
menu.setItem(
0,
RSMenuUtils.createMenuItem(
Material.ARROW,
"§ePrevious Page (" + holder.getPage() + ")"
)
);
}
/*
|--------------------------------------------------------------------------
| FILTER ITEMS
|--------------------------------------------------------------------------
*/
Map<Integer, ItemStack> filterItems =
MachineManager.getFilterItems(
block,
holder.getPage()
);
for (Integer slot : filterItems.keySet()) {
menu.setItem(
slot,
filterItems.get(
slot
)
);
}
/*
|--------------------------------------------------------------------------
| NEXT PAGE
|--------------------------------------------------------------------------
*/
int highestPage =
MachineManager.getHighestFilterPage(
block
);
if (holder.getPage()
<= highestPage) {
menu.setItem(
8,
RSMenuUtils.createMenuItem(
Material.ARROW,
"§eNext Page (" + holder.getPage() + ")"
)
);
}
/*
|--------------------------------------------------------------------------
| BACK
|--------------------------------------------------------------------------
*/
menu.setItem(
5,
RSMenuUtils.createMenuItem(
Material.OAK_DOOR,
"§eBack"
)
);
player.openInventory(
menu
);
}
}
@@ -0,0 +1,285 @@
package com.rsscripting.itemmagnet.gui;
import com.rsscripting.itemmagnet.managers.MachineManager;
import com.rsscripting.itemmagnet.utils.RSConstants;
import com.rsscripting.itemmagnet.utils.RSMenuUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.List;
public class RSMainMenu {
public static final String MENU_TITLE = "Main";
public static void open(
Player player,
Block block
) {
Inventory menu =
Bukkit.createInventory(
new RSMenuHolder(
"MAIN"
),
18,
Component.text(
MENU_TITLE
).color(
NamedTextColor.BLUE
)
);
/*
|--------------------------------------------------------------------------
| FILLER
|--------------------------------------------------------------------------
*/
ItemStack filler =
RSMenuUtils.createFillerPane();
for (int i = 0; i < menu.getSize(); i++) {
menu.setItem(i, filler);
}
/*
|--------------------------------------------------------------------------
| CONVERT BACK
|--------------------------------------------------------------------------
*/
menu.setItem(
2,
RSMenuUtils.createMenuItem(
Material.COMPOSTER,
"§6Convert Back"
)
);
/*
|--------------------------------------------------------------------------
| PAUSE / RESUME
|--------------------------------------------------------------------------
*/
boolean paused =
MachineManager.isPaused(
block
);
String status =
MachineManager.getStoredStatus(
block
);
String displayStatus;
switch (status) {
case "RUNNING" -> displayStatus =
"Running";
case "PAUSED" -> displayStatus =
"Paused";
case "ERROR_TARGET_MISSING" -> displayStatus =
"Target Container Missing";
case "ERROR_TARGET_INVALID" -> displayStatus =
"Invalid Target Container";
case "ERROR_NO_TARGET" -> displayStatus =
"No Target Container Assigned";
default -> displayStatus =
status;
}
menu.setItem(
6,
RSMenuUtils.createMenuItem(
paused
? Material.RED_DYE
: Material.GREEN_DYE,
paused
? "§cPaused"
: "§aRunning",
List.of(
"§7Status: §f"
+ displayStatus
)
)
);
/*
|--------------------------------------------------------------------------
| RADIUS
|--------------------------------------------------------------------------
*/
menu.setItem(
10,
RSMenuUtils.createMenuItem(
Material.COMPASS,
"§bRadius",
List.of(
"§7Current Radius: §f"
+ MachineManager.getRadius(block)
)
)
);
/*
|--------------------------------------------------------------------------
| Show Radius
|--------------------------------------------------------------------------
*/
menu.setItem(
12,
RSMenuUtils.createMenuItem(
Material.ENDER_EYE,
"§bShow Radius",
List.of(
"§7Displays a particle outline",
"§7of the ItemMagnet radius.",
"",
"§eClick to preview."
)
)
);
/*
|--------------------------------------------------------------------------
| TARGET CONTAINER
|--------------------------------------------------------------------------
*/
int[] targetContainer =
MachineManager.getTargetContainer(
block
);
if (targetContainer == null) {
menu.setItem(
14,
RSMenuUtils.createMenuItem(
Material.TARGET,
"§eTarget Container",
List.of(
"§cNo target Container assigned.",
"",
"§7Click to assign",
"§7a target Container."
)
)
);
} else {
menu.setItem(
14,
RSMenuUtils.createMenuItem(
Material.TARGET,
"§eTarget Container",
List.of(
"§7Current Container:",
" " + targetContainer[0],
" " + targetContainer[1],
" " + targetContainer[2],
"",
"§7Click to assign",
"§7a new target Container."
)
)
);
}
/*
|--------------------------------------------------------------------------
| FILTER
|--------------------------------------------------------------------------
*/
menu.setItem(
16,
RSMenuUtils.createMenuItem(
Material.HOPPER,
"§eFilter",
List.of(
"§7Mode: §f"
+ MachineManager.getFilterMode(block)
)
)
);
/*
|--------------------------------------------------------------------------
| ADMIN
|--------------------------------------------------------------------------
*/
if (player.hasPermission(
RSConstants.ADMIN_PERMISSION
)) {
menu.setItem(
4,
RSMenuUtils.createMenuItem(
Material.COMMAND_BLOCK,
"§cAdmin"
)
);
}
player.openInventory(menu);
}
}
@@ -0,0 +1,57 @@
package com.rsscripting.itemmagnet.gui;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.jetbrains.annotations.NotNull;
public class RSMenuHolder
implements InventoryHolder {
private final String menuId;
private int page = 1;
public RSMenuHolder(
String menuId
) {
this.menuId = menuId;
}
public String getMenuId() {
return menuId;
}
public int getPage() {
return page;
}
public void setPage(
int page
) {
if (page < 1) {
page = 1;
}
this.page = page;
}
@Override
public @NotNull Inventory getInventory() {
throw new UnsupportedOperationException(
"RSMenuHolder does not store an inventory."
);
}
}
@@ -0,0 +1,183 @@
package com.rsscripting.itemmagnet.gui;
import com.rsscripting.itemmagnet.managers.MachineManager;
import com.rsscripting.itemmagnet.utils.RSMenuUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.List;
public class RSRadiusMenu {
public static void open(
Player player,
Block block
) {
Inventory menu =
Bukkit.createInventory(
new RSMenuHolder(
"RADIUS"
),
18,
Component.text(
"Radius: "
+ MachineManager.getRadius(
block
)
).color(NamedTextColor.BLUE)
);
/*
|--------------------------------------------------------------------------
| FILLER
|--------------------------------------------------------------------------
*/
ItemStack filler =
RSMenuUtils.createFillerPane();
for (int i = 0; i < menu.getSize(); i++) {
menu.setItem(i, filler);
}
/*
|--------------------------------------------------------------------------
| BACK
|--------------------------------------------------------------------------
*/
menu.setItem(
4,
RSMenuUtils.createMenuItem(
Material.OAK_DOOR,
"§eBack"
)
);
/*
|--------------------------------------------------------------------------
| CURRENT RADIUS
|--------------------------------------------------------------------------
*/
menu.setItem(
13,
RSMenuUtils.createMenuItem(
Material.COMPASS,
"§bCurrent Radius",
List.of(
"§7Radius: §f"
+ MachineManager.getRadius(
block
)
)
)
);
/*
|--------------------------------------------------------------------------
| NEGATIVE BUTTONS
|--------------------------------------------------------------------------
*/
ItemStack minusTen =
RSMenuUtils.createMenuItem(
Material.RED_WOOL,
"§c-10"
);
minusTen.setAmount(10);
menu.setItem(
10,
minusTen
);
ItemStack minusFive =
RSMenuUtils.createMenuItem(
Material.RED_WOOL,
"§c-5"
);
minusFive.setAmount(5);
menu.setItem(
11,
minusFive
);
menu.setItem(
12,
RSMenuUtils.createMenuItem(
Material.RED_WOOL,
"§c-1"
)
);
/*
|--------------------------------------------------------------------------
| POSITIVE BUTTONS
|--------------------------------------------------------------------------
*/
ItemStack plusOne =
RSMenuUtils.createMenuItem(
Material.GREEN_WOOL,
"§a+1"
);
plusOne.setAmount(1);
menu.setItem(
14,
plusOne
);
ItemStack plusFive =
RSMenuUtils.createMenuItem(
Material.GREEN_WOOL,
"§a+5"
);
plusFive.setAmount(5);
menu.setItem(
15,
plusFive
);
ItemStack plusTen =
RSMenuUtils.createMenuItem(
Material.GREEN_WOOL,
"§a+10"
);
plusTen.setAmount(10);
menu.setItem(
16,
plusTen
);
player.openInventory(menu);
}
}
@@ -0,0 +1,128 @@
package com.rsscripting.itemmagnet.listeners;
import com.rsscripting.itemmagnet.config.ConfigManager;
import com.rsscripting.itemmagnet.gui.RSAdminMenu;
import com.rsscripting.itemmagnet.gui.RSMenuHolder;
import com.rsscripting.itemmagnet.utils.RSConstants;
import com.rsscripting.itemmagnet.gui.RSMainMenu;
import org.bukkit.block.Block;
import com.rsscripting.itemmagnet.utils.RSMessageUtils;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
public class RSAdminListener
implements Listener {
private final RSConvertListener
conversionListener;
public RSAdminListener(
RSConvertListener conversionListener
) {
this.conversionListener =
conversionListener;
}
@EventHandler
public void onInventoryClick(
InventoryClickEvent event
) {
if (!(event.getWhoClicked()
instanceof Player player)) {
return;
}
if (!(event.getInventory()
.getHolder()
instanceof RSMenuHolder holder)) {
return;
}
if (!holder.getMenuId()
.equals(
"ADMIN"
)) {
return;
}
event.setCancelled(true);
/*
|--------------------------------------------------------------------------
| SECURITY
|--------------------------------------------------------------------------
*/
if (!player.isOp()
||
!player.hasPermission(
RSConstants.ADMIN_PERMISSION
)) {
player.closeInventory();
return;
}
/*
|--------------------------------------------------------------------------
| BACK
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 4) {
Block block =
conversionListener.getSelectedBlock(
player
);
if (block == null) {
player.closeInventory();
return;
}
RSMainMenu.open(
player,
block
);
return;
}
/*
|--------------------------------------------------------------------------
| RELOAD
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 12) {
ConfigManager.reload();
RSMessageUtils.success(
player,
"Configuration reloaded."
);
RSAdminMenu.open(
player
);
}
}
}
@@ -0,0 +1,28 @@
package com.rsscripting.itemmagnet.listeners;
import com.rsscripting.itemmagnet.managers.MachineManager;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
public class RSBlockBreakListener
implements Listener {
@EventHandler
public void onBlockBreak(
BlockBreakEvent event
) {
if (MachineManager.machineExists(
event.getBlock()
)) {
event.setCancelled(
true
);
}
}
}
@@ -0,0 +1,470 @@
package com.rsscripting.itemmagnet.listeners;
import com.rsscripting.itemmagnet.gui.RSConversionMenu;
import com.rsscripting.itemmagnet.gui.RSMainMenu;
import com.rsscripting.itemmagnet.managers.MachineManager;
import com.rsscripting.itemmagnet.managers.PendingTargetAssignment;
import com.rsscripting.itemmagnet.utils.RSConstants;
import com.rsscripting.itemmagnet.utils.RSMessageUtils;
import com.rsscripting.itemmagnet.config.ConfigManager;
import com.rsscripting.itemmagnet.managers.PendingConversion;
import com.rsscripting.itemmagnet.managers.RSConversionManager;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class RSConvertListener
implements Listener {
private final Map<UUID, Block> selectedBlocks =
new HashMap<>();
@EventHandler
public void onPlayerInteractBlock(
PlayerInteractEvent event
) {
Player player =
event.getPlayer();
Block block =
event.getClickedBlock();
if (block == null) {
return;
}
/*
|--------------------------------------------------------------------------
| PENDING TARGET ASSIGNMENT
|--------------------------------------------------------------------------
*/
PendingTargetAssignment pendingAssignment =
RSConversionManager
.getPendingTargetAssignment(
player
);
if (pendingAssignment != null) {
if (pendingAssignment.isExpired()) {
RSConversionManager.removePendingTargetAssignment(
player
);
player.sendMessage(
RSConstants.PREFIX
+ "Target assignment expired."
);
return;
}
Block targetAssignmentMachine =
pendingAssignment.getMachine();
if (targetAssignmentMachine != null) {
Material type =
block.getType();
if (
type != Material.HOPPER
&&
type != Material.CHEST
&&
type != Material.BARREL
) {
RSMessageUtils.error(
player,
"Please select a Hopper, Chest, or Barrel."
);
return;
}
event.setCancelled(true);
if (!targetAssignmentMachine.getWorld().equals(
block.getWorld()
)) {
RSMessageUtils.error(
player,
"Target container must be in the same world."
);
return;
}
int maxDistance =
ConfigManager.getMaxTargetDistance();
if (
maxDistance > 0
&&
targetAssignmentMachine
.getLocation()
.distance(
block.getLocation()
) > maxDistance
) {
RSMessageUtils.error(
player,
"Target container must be within "
+ maxDistance
+ " blocks."
);
return;
}
MachineManager.setTargetContainer(
targetAssignmentMachine,
block
);
RSConversionManager.removePendingTargetAssignment(
player
);
RSMessageUtils.success(
player,
"Target container updated."
);
return;
}
}
/*
|--------------------------------------------------------------------------
| PENDING Conversion CONTAINER SELECTION
|--------------------------------------------------------------------------
*/
PendingConversion pendingConversion =
RSConversionManager.getPendingConversion(
player
);
if (pendingConversion != null) {
if (pendingConversion.isExpired()) {
RSConversionManager.removePendingConversion(
player
);
RSMessageUtils.error(
player,
"Conversion timed out."
);
return;
}
Material type =
block.getType();
if (
type != Material.HOPPER
&&
type != Material.CHEST
&&
type != Material.BARREL
) {
RSMessageUtils.error(
player,
"Please select a Hopper, Chest, or Barrel."
);
return;
}
event.setCancelled(true);
Block lodestone =
pendingConversion.getLodestone();
int maxDistance =
ConfigManager.getMaxTargetDistance();
if (!lodestone.getWorld().equals(
block.getWorld()
)) {
RSMessageUtils.error(
player,
"Target container must be in the same world."
);
return;
}
if (
maxDistance > 0
&&
lodestone.getLocation().distance(
block.getLocation()
) > maxDistance
) {
RSMessageUtils.error(
player,
"Target container must be within "
+ maxDistance
+ " blocks."
);
return;
}
MachineManager.insertMachine(
lodestone
);
MachineManager.setOwner(
lodestone,
player
);
MachineManager.setPaused(
lodestone,
false
);
MachineManager.setStatus(
lodestone,
"RUNNING"
);
MachineManager.setRadius(
lodestone,
ConfigManager.getDefaultRadius()
);
MachineManager.setFilterMode(
lodestone,
"ALLOW_ALL"
);
MachineManager.setTargetContainer(
lodestone,
block
);
RSConversionManager.removePendingConversion(
player
);
RSMessageUtils.success(
player,
"Target container assigned."
);
RSMainMenu.open(
player,
lodestone
);
return;
}
/*
|--------------------------------------------------------------------------
| REQUIRE SNEAKING
|--------------------------------------------------------------------------
*/
if (!player.isSneaking()) {
return;
}
/*
|--------------------------------------------------------------------------
| VALIDATE TARGET ENTITY
|--------------------------------------------------------------------------
*/
if (block.getType() !=
RSConstants.REQUIRED_TARGET_BLOCK) {
return;
}
/*
|--------------------------------------------------------------------------
| VALIDATE HELD ITEM
|--------------------------------------------------------------------------
*/
ItemStack heldItem =
player.getInventory()
.getItemInMainHand();
if (heldItem.getType() !=
RSConstants.REQUIRED_HELD_ITEM) {
return;
}
/*
|--------------------------------------------------------------------------
| CANCEL VANILLA ACTION
|--------------------------------------------------------------------------
*/
event.setCancelled(true);
/*
|--------------------------------------------------------------------------
| STORE SELECTED ENTITY
|--------------------------------------------------------------------------
*/
selectedBlocks.put(
player.getUniqueId(),
block
);
/*
|--------------------------------------------------------------------------
| ALREADY CONVERTED
|--------------------------------------------------------------------------
*/
if (MachineManager.machineExists(
block
)) {
/*
|--------------------------------------------------------------------------
| OWNER CHECK
|--------------------------------------------------------------------------
*/
if (!MachineManager.isOwner(
block,
player
)
&&
!player.hasPermission(
RSConstants.BYPASS_PERMISSION
)
) {
RSMessageUtils.error(
player,
"You are not the owner."
);
return;
}
/*
|--------------------------------------------------------------------------
| OPEN MAIN MENU
|--------------------------------------------------------------------------
*/
RSMainMenu.open(
player,
block
);
return;
}
/*
|--------------------------------------------------------------------------
| OPEN CONVERSION MENU
|--------------------------------------------------------------------------
*/
RSConversionMenu.open(player);
}
/*
|--------------------------------------------------------------------------
| GET SELECTED ENTITY
|--------------------------------------------------------------------------
*/
public Block getSelectedBlock(
Player player
) {
return selectedBlocks.get(
player.getUniqueId()
);
}
/*
|--------------------------------------------------------------------------
| Convert Back
|--------------------------------------------------------------------------
*/
public void convertBack(
Player player
) {
Block block =
selectedBlocks.get(
player.getUniqueId()
);
if (block == null) {
player.closeInventory();
return;
}
MachineManager.deleteMachine(
block
);
RSMessageUtils.success(
player,
"Machine removed."
);
player.closeInventory();
}
}
@@ -0,0 +1,297 @@
package com.rsscripting.itemmagnet.listeners;
import com.rsscripting.itemmagnet.gui.RSFilterMenu;
import com.rsscripting.itemmagnet.gui.RSMainMenu;
import com.rsscripting.itemmagnet.gui.RSMenuHolder;
import com.rsscripting.itemmagnet.managers.MachineManager;
import com.rsscripting.itemmagnet.managers.RSConversionManager;
import com.rsscripting.itemmagnet.utils.RSKeys;
import com.rsscripting.itemmagnet.utils.RSMessageUtils;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
public class RSFilterListener
implements Listener {
private final RSConvertListener
conversionListener;
public RSFilterListener(
RSConvertListener conversionListener
) {
this.conversionListener =
conversionListener;
}
@EventHandler
public void onInventoryClick(
InventoryClickEvent event
) {
if (!(event.getWhoClicked()
instanceof Player player)) {
return;
}
if (!(event.getInventory()
.getHolder()
instanceof RSMenuHolder holder)) {
return;
}
if (!holder.getMenuId()
.equals(
"FILTER"
)) {
return;
}
Block block =
conversionListener.getSelectedBlock(
player
);
if (block == null) {
player.closeInventory();
return;
}
/*
|--------------------------------------------------------------------------
| TOP ROW
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() < 9) {
event.setCancelled(true);
/*
|--------------------------------------------------------------------------
| FILTER MODE
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 3) {
String currentMode =
MachineManager.getFilterMode(
block
);
String nextMode;
if (currentMode.equals(
RSKeys.FILTER_ALLOW_ALL
)) {
nextMode =
RSKeys.FILTER_WHITELIST;
}
else if (currentMode.equals(
RSKeys.FILTER_WHITELIST
)) {
nextMode =
RSKeys.FILTER_BLACKLIST;
}
else {
nextMode =
RSKeys.FILTER_ALLOW_ALL;
}
MachineManager.setFilterMode(
block,
nextMode
);
RSFilterMenu.open(
player,
block
);
return;
}
/*
|--------------------------------------------------------------------------
| PREVIOUS PAGE
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 0
&& event.getCurrentItem() != null
&& event.getCurrentItem().getType()
== Material.ARROW) {
if (holder.getPage() > 1) {
holder.setPage(
holder.getPage() - 1
);
RSFilterMenu.open(
player,
block,
holder.getPage()
);
}
return;
}
/*
|--------------------------------------------------------------------------
| NEXT PAGE
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 8
&& event.getCurrentItem() != null
&& event.getCurrentItem().getType()
== Material.ARROW) {
int highestPage =
MachineManager.getHighestFilterPage(
block
);
if (holder.getPage()
<= highestPage) {
holder.setPage(
holder.getPage() + 1
);
RSFilterMenu.open(
player,
block,
holder.getPage()
);
}
return;
}
/*
|--------------------------------------------------------------------------
| BACK
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 5) {
RSMainMenu.open(
player,
block
);
return;
}
return;
}
if (event.getRawSlot() >= event.getInventory().getSize()) {
return;
}
/*
|--------------------------------------------------------------------------
| FILTER STORAGE
|--------------------------------------------------------------------------
*/
event.setCancelled(true);
if (event.getCursor().getType()
!= Material.AIR) {
ItemStack filterItem =
event.getCursor().clone();
filterItem.setAmount(1);
if (RSConversionManager.containsFilterItem(
block,
filterItem
)) {
RSMessageUtils.info(
player,
"That item is already in the filter."
);
return;
}
event.getInventory().setItem(
event.getRawSlot(),
filterItem
);
MachineManager.saveFilterItem(
block,
holder.getPage(),
event.getRawSlot(),
filterItem
);
RSFilterMenu.open(
player,
block,
holder.getPage()
);
return;
}
event.getInventory().setItem(
event.getRawSlot(),
null
);
MachineManager.removeFilterItem(
block,
holder.getPage(),
event.getRawSlot()
);
RSFilterMenu.open(
player,
block,
holder.getPage()
);
}
}
@@ -0,0 +1,388 @@
package com.rsscripting.itemmagnet.listeners;
import com.rsscripting.itemmagnet.config.ConfigManager;
import com.rsscripting.itemmagnet.enums.MachineStatus;
import com.rsscripting.itemmagnet.managers.MachineManager;
import com.rsscripting.itemmagnet.managers.RSConversionManager;
import com.rsscripting.itemmagnet.gui.*;
import com.rsscripting.itemmagnet.managers.RSRadiusPreviewManager;
import com.rsscripting.itemmagnet.utils.RSConstants;
import com.rsscripting.itemmagnet.utils.RSMessageUtils;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
public class RSMenuListener
implements Listener {
private final RSConvertListener
conversionListener;
public RSMenuListener(
RSConvertListener conversionListener
) {
this.conversionListener =
conversionListener;
}
@EventHandler
public void onInventoryClick(
InventoryClickEvent event
) {
Player player =
(Player) event.getWhoClicked();
/*
|--------------------------------------------------------------------------
| CONVERSION MENU
|--------------------------------------------------------------------------
*/
if (event.getInventory()
.getHolder()
instanceof RSMenuHolder holder
&& holder.getMenuId()
.equals(
"CONVERT"
)) {
event.setCancelled(true);
if (event.getCurrentItem() == null) {
return;
}
if (event.getRawSlot() == 4) {
Block block =
conversionListener.getSelectedBlock(
player
);
if (block == null){
player.closeInventory();
return;
}
RSConversionManager.startPendingConversion(
player,
block
);
RSMessageUtils.info(
player,
"Please select a Container within "
+ ConfigManager.getDefaultRadius()
+ " blocks to finish conversion."
);
player.closeInventory();
}
return;
}
/*
|--------------------------------------------------------------------------
| MAIN MENU
|--------------------------------------------------------------------------
*/
if (event.getInventory()
.getHolder()
instanceof RSMenuHolder holder
&& holder.getMenuId()
.equals(
"MAIN"
)) {
event.setCancelled(true);
if (event.getCurrentItem() == null) {
return;
}
Block block =
conversionListener.getSelectedBlock(
player
);
if (block == null) {
player.closeInventory();
return;
}
/*
|--------------------------------------------------------------------------
| CONVERT BACK
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 2) {
conversionListener.convertBack(
player
);
return;
}
/*
|--------------------------------------------------------------------------
| ADMIN MENU
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 4) {
if (!player.isOp()
||
!player.hasPermission(
RSConstants.ADMIN_PERMISSION
)) {
return;
}
RSAdminMenu.open(
player
);
}
/*
|--------------------------------------------------------------------------
| PAUSE / RESUME
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 6) {
boolean paused =
MachineManager.isPaused(
block
);
if (paused) {
MachineStatus detectedStatus =
MachineManager.getDetectedStatus(
block
);
if (
detectedStatus
!= MachineStatus.PAUSED
&&
detectedStatus
!= MachineStatus.RUNNING
) {
String line1;
String line2;
switch (detectedStatus) {
case NO_TARGET -> {
line1 =
"No target container assigned.";
line2 =
"Please assign a valid Hopper, Chest, or Barrel and press resume.";
}
case TARGET_MISSING -> {
line1 =
"Target container is missing.";
line2 =
"Assign a new container and press resume.";
}
case TARGET_INVALID -> {
line1 =
"Target container is invalid.";
line2 =
"Please assign a valid Hopper, Chest, or Barrel and press resume.";
}
default -> {
line1 =
"Machine is not ready.";
line2 =
"";
}
}
RSMessageUtils.error(
player,
line1
);
if (!line2.isEmpty()) {
RSMessageUtils.error(
player,
line2
);
}
return;
}
MachineManager.setPaused(
block,
false
);
MachineManager.setStatus(
block,
"RUNNING"
);
}
else {
MachineManager.setPaused(
block,
true
);
MachineManager.setStatus(
block,
"PAUSED"
);
}
RSMainMenu.open(
player,
block
);
return;
}
/*
|--------------------------------------------------------------------------
| RADIUS MENU
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 10) {
RSRadiusMenu.open(
player,
block
);
return;
}
/*
|--------------------------------------------------------------------------
| SHOW RADIUS
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 12) {
RSRadiusPreviewManager.startPreview(
player,
block
);
player.closeInventory();
return;
}
/*
|--------------------------------------------------------------------------
| TARGET CONTAINER
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 14) {
RSConversionManager.startPendingTargetAssignment(
player,
block
);
RSMessageUtils.info(
player,
"Please select a new target Container."
);
player.closeInventory();
return;
}
/*
|--------------------------------------------------------------------------
| FILTER
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 16) {
RSFilterMenu.open(
player,
block
);
return;
}
}
}
}
@@ -0,0 +1,158 @@
package com.rsscripting.itemmagnet.listeners;
import com.rsscripting.itemmagnet.config.ConfigManager;
import com.rsscripting.itemmagnet.gui.RSMainMenu;
import com.rsscripting.itemmagnet.gui.RSMenuHolder;
import com.rsscripting.itemmagnet.gui.RSRadiusMenu;
import com.rsscripting.itemmagnet.managers.MachineManager;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
public class RSRadiusListener
implements Listener {
private final RSConvertListener
conversionListener;
public RSRadiusListener(
RSConvertListener conversionListener
) {
this.conversionListener =
conversionListener;
}
@EventHandler
public void onInventoryClick(
InventoryClickEvent event
) {
if (!(event.getWhoClicked()
instanceof Player player)) {
return;
}
if (!(event.getInventory()
.getHolder()
instanceof RSMenuHolder holder)) {
return;
}
if (!holder.getMenuId()
.equals(
"RADIUS"
)) {
return;
}
event.setCancelled(true);
if (event.getCurrentItem() == null) {
return;
}
Block block =
conversionListener.getSelectedBlock(
player
);
if (block == null) {
player.closeInventory();
return;
}
/*
|--------------------------------------------------------------------------
| BACK
|--------------------------------------------------------------------------
*/
if (event.getRawSlot() == 4) {
RSMainMenu.open(
player,
block
);
return;
}
int radius =
MachineManager.getRadius(
block
);
int change;
switch (event.getRawSlot()) {
case 10:
change = -10;
break;
case 11:
change = -5;
break;
case 12:
change = -1;
break;
case 14:
change = 1;
break;
case 15:
change = 5;
break;
case 16:
change = 10;
break;
default:
return;
}
radius += change;
if (radius < 1) {
radius = 1;
}
int maxRadius =
(int) ConfigManager.get()
.getDouble(
"max-radius"
);
if (maxRadius > 0
&& radius > maxRadius) {
radius = maxRadius;
}
MachineManager.setRadius(
block,
radius
);
RSRadiusMenu.open(
player,
block
);
}
}
@@ -0,0 +1,42 @@
package com.rsscripting.itemmagnet.listeners;
import com.rsscripting.itemmagnet.utils.GitHubUpdateChecker;
import com.rsscripting.itemmagnet.utils.RSConstants;
import com.rsscripting.itemmagnet.utils.VersionUtils;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
public class RSUpdateNotificationListener
implements Listener {
@EventHandler
public void onPlayerJoin(
PlayerJoinEvent event
) {
if (!event.getPlayer().isOp()) {
return;
}
if (!GitHubUpdateChecker.isUpdateAvailable()) {
return;
}
event.getPlayer().sendMessage(
RSConstants.PREFIX
+ "Update Available! Current: "
+ VersionUtils.getVersion()
+ " Latest: "
+ GitHubUpdateChecker.getLatestVersionFound()
);
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,36 @@
package com.rsscripting.itemmagnet.managers;
import org.bukkit.block.Block;
public class PendingConversion {
private final Block lodestone;
private final long expirationTime;
public PendingConversion(
Block lodestone,
long expirationTime
) {
this.lodestone =
lodestone;
this.expirationTime =
expirationTime;
}
public Block getLodestone() {
return lodestone;
}
public boolean isExpired() {
return System.currentTimeMillis()
> expirationTime;
}
}
@@ -0,0 +1,34 @@
package com.rsscripting.itemmagnet.managers;
import org.bukkit.block.Block;
public class PendingTargetAssignment {
private final Block machine;
private final long expirationTime;
public PendingTargetAssignment(
Block machine,
long expirationTime
) {
this.machine = machine;
this.expirationTime = expirationTime;
}
public Block getMachine() {
return machine;
}
public boolean isExpired() {
return System.currentTimeMillis()
> expirationTime;
}
}
@@ -0,0 +1,157 @@
package com.rsscripting.itemmagnet.managers;
import com.rsscripting.itemmagnet.config.ConfigManager;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.block.Block;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class RSConversionManager {
private static final Map<UUID, PendingConversion>
pendingConversions =
new HashMap<>();
private static final Map<UUID, PendingTargetAssignment>
pendingTargetAssignments =
new HashMap<>();
public static boolean containsFilterItem(
Block block,
ItemStack item
) {
Map<Integer, ItemStack> filterItems =
MachineManager.getAllFilterItems(
block
);
for (ItemStack filterItem
: filterItems.values()) {
if (filterItem == null) {
continue;
}
if (filterItem.isSimilar(
item
)) {
return true;
}
}
return false;
}
/*
|--------------------------------------------------------------------------
| PENDING CONVERSION
|--------------------------------------------------------------------------
*/
public static void startPendingConversion(
Player player,
Block lodestone
) {
long timeoutMillis =
ConfigManager.getConversionTimeout()
* 1000L;
pendingConversions.put(
player.getUniqueId(),
new PendingConversion(
lodestone,
System.currentTimeMillis()
+ timeoutMillis
)
);
}
public static PendingConversion getPendingConversion(
Player player
) {
return pendingConversions.get(
player.getUniqueId()
);
}
public static void removePendingConversion(
Player player
) {
pendingConversions.remove(
player.getUniqueId()
);
}
/*
|--------------------------------------------------------------------------
| PENDING TARGET ASSIGNMENT
|--------------------------------------------------------------------------
*/
public static void startPendingTargetAssignment(
Player player,
Block lodestone
) {
long timeoutMillis =
ConfigManager.getConversionTimeout()
* 1000L;
pendingTargetAssignments.put(
player.getUniqueId(),
new PendingTargetAssignment(
lodestone,
System.currentTimeMillis()
+ timeoutMillis
)
);
}
public static PendingTargetAssignment getPendingTargetAssignment(
Player player
) {
return pendingTargetAssignments.get(
player.getUniqueId()
);
}
public static void removePendingTargetAssignment(
Player player
) {
pendingTargetAssignments.remove(
player.getUniqueId()
);
}
}
@@ -0,0 +1,66 @@
package com.rsscripting.itemmagnet.managers;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class RSRadiusPreviewManager {
private static final Map<UUID, PreviewData>
previews =
new HashMap<>();
public static void startPreview(
Player player,
Block block
) {
previews.put(
player.getUniqueId(),
new PreviewData(
block,
System.currentTimeMillis()
+ 30000
)
);
}
public static PreviewData getPreview(
Player player
) {
return previews.get(
player.getUniqueId()
);
}
public static void removePreview(
Player player
) {
previews.remove(
player.getUniqueId()
);
}
public record PreviewData(
Block block,
long expireTime
) {}
}
@@ -0,0 +1,62 @@
package com.rsscripting.itemmagnet.tasks;
import com.rsscripting.itemmagnet.managers.MachineManager;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.Map;
public class RSErrorTask extends BukkitRunnable {
@Override
public void run() {
Map<Location, Integer> machines =
MachineManager.getAllMachines();
for (
Location machineLocation
: machines.keySet()
) {
Block machineBlock =
machineLocation.getBlock();
String status =
MachineManager.getStoredStatus(
machineBlock
);
if (
!status.startsWith(
"ERROR_"
)
) {
continue;
}
machineLocation.getWorld()
.spawnParticle(
Particle.ANGRY_VILLAGER,
machineLocation.clone()
.add(
0.5,
0.75,
0.5
),
1
);
}
}
}
@@ -0,0 +1,255 @@
package com.rsscripting.itemmagnet.tasks;
import com.rsscripting.itemmagnet.config.ConfigManager;
import com.rsscripting.itemmagnet.enums.MachineStatus;
import com.rsscripting.itemmagnet.managers.MachineManager;
import com.rsscripting.itemmagnet.managers.RSConversionManager;
import org.bukkit.Location;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.entity.Item;
import org.bukkit.block.Block;
import org.bukkit.Particle;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class RSItemMagnetTask
extends BukkitRunnable {
@Override
public void run() {
Map<Location, Integer> machines =
MachineManager.getAllMachines();
for (Location machineLocation
: machines.keySet()) {
if (
MachineManager.isPaused(
machineLocation.getBlock()
)
) {
continue;
}
int[] targetCoordinates =
MachineManager.getTargetContainer(
machineLocation.getBlock()
);
if (targetCoordinates == null) {
continue;
}
if (!machineLocation.getWorld()
.isChunkLoaded(
targetCoordinates[0] >> 4,
targetCoordinates[2] >> 4
)) {
continue;
}
MachineStatus detectedStatus =
MachineManager.getDetectedStatus(
machineLocation.getBlock()
);
if (
detectedStatus
== MachineStatus.TARGET_MISSING
) {
MachineManager.setPaused(
machineLocation.getBlock(),
true
);
MachineManager.setStatus(
machineLocation.getBlock(),
"ERROR_TARGET_MISSING"
);
continue;
}
if (
detectedStatus
== MachineStatus.TARGET_INVALID
) {
MachineManager.setPaused(
machineLocation.getBlock(),
true
);
MachineManager.setStatus(
machineLocation.getBlock(),
"ERROR_TARGET_INVALID"
);
continue;
}
if (
detectedStatus
== MachineStatus.NO_TARGET
) {
MachineManager.setPaused(
machineLocation.getBlock(),
true
);
MachineManager.setStatus(
machineLocation.getBlock(),
"ERROR_NO_TARGET"
);
continue;
}
int radius =
MachineManager.getRadius(
machineLocation.getBlock()
);
int yDistance =
ConfigManager.getItemYDistance();
Collection<Item> nearbyItems;
if (yDistance <= 0) {
nearbyItems =
machineLocation.getWorld()
.getNearbyEntitiesByType(
Item.class,
machineLocation,
radius
);
}
else {
nearbyItems =
machineLocation.getWorld()
.getNearbyEntitiesByType(
Item.class,
machineLocation,
radius,
yDistance,
radius
);
}
Location containerLocation =
new Location(
machineLocation.getWorld(),
targetCoordinates[0] + 0.5,
targetCoordinates[1] + 0.5,
targetCoordinates[2] + 0.5
);
for (Item item : nearbyItems) {
if (item.getTicksLived() < 40) {
continue;
}
String filterMode =
MachineManager.getFilterMode(
machineLocation.getBlock()
);
boolean inFilter =
RSConversionManager.containsFilterItem(
machineLocation.getBlock(),
item.getItemStack()
);
if (filterMode.equalsIgnoreCase(
"WHITELIST"
) && !inFilter) {
continue;
}
if (filterMode.equalsIgnoreCase(
"BLACKLIST"
) && inFilter) {
continue;
}
Block containerBlock =
containerLocation.getBlock();
if (!(containerBlock.getState()
instanceof InventoryHolder container)) {
continue;
}
Inventory inventory =
container.getInventory();
ItemStack stack =
item.getItemStack();
HashMap<Integer, ItemStack> leftovers =
inventory.addItem(stack);
if (leftovers.isEmpty()) {
item.getWorld().spawnParticle(
Particle.ELECTRIC_SPARK,
item.getLocation(),
10,
0.2,
0.2,
0.2,
0.05
);
item.remove();
}
else {
ItemStack remaining =
leftovers.values()
.iterator()
.next();
item.setItemStack(
remaining
);
}
}
}
}
}
@@ -0,0 +1,235 @@
package com.rsscripting.itemmagnet.tasks;
import com.rsscripting.itemmagnet.managers.MachineManager;
import com.rsscripting.itemmagnet.managers.RSRadiusPreviewManager;
import com.rsscripting.itemmagnet.config.ConfigManager;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
public class RSRadiusPreviewTask
extends BukkitRunnable {
@Override
public void run() {
for (Player player
: org.bukkit.Bukkit.getOnlinePlayers()) {
RSRadiusPreviewManager.PreviewData
preview =
RSRadiusPreviewManager
.getPreview(
player
);
if (preview == null) {
continue;
}
if (
System.currentTimeMillis()
>= preview.expireTime()
) {
RSRadiusPreviewManager
.removePreview(
player
);
continue;
}
Block block =
preview.block();
int radius =
MachineManager.getRadius(
block
);
Location center =
block.getLocation()
.clone()
.add(
0.5,
0.05,
0.5
);
int yDistance =
ConfigManager.getItemYDistance();
if (yDistance <= 0) {
yDistance =
radius;
}
double middleY =
center.getY();
double topY =
center.getY()
+ yDistance;
double bottomY =
center.getY()
- yDistance;
Particle.DustOptions dust =
new Particle.DustOptions(
Color.RED,
1.5F
);
drawRing(
player,
center,
radius,
middleY,
dust
);
drawRing(
player,
center,
radius,
topY,
dust
);
drawRing(
player,
center,
radius,
bottomY,
dust
);
}
}
private void drawRing(
Player player,
Location center,
int radius,
double y,
Particle.DustOptions dust
) {
double offsetY =
y - center.getY();
for (
int x = -radius;
x <= radius;
x++
) {
spawnParticle(
player,
center.clone().add(
x,
offsetY,
radius - 0.5
),
dust
);
spawnParticle(
player,
center.clone().add(
x,
offsetY,
-(radius - 0.5)
),
dust
);
}
for (
int z = -radius;
z <= radius;
z++
) {
spawnParticle(
player,
center.clone().add(
radius - 0.5,
offsetY,
z
),
dust
);
spawnParticle(
player,
center.clone().add(
-radius,
offsetY,
z
),
dust
);
}
}
private void spawnParticle(
Player player,
Location location,
Particle.DustOptions dust
) {
player.spawnParticle(
Particle.DUST,
location,
1,
0,
0,
0,
0,
dust
);
}
}
@@ -0,0 +1,273 @@
package com.rsscripting.itemmagnet.utils;
import com.rsscripting.itemmagnet.RSItemMagnet;
import org.bukkit.Bukkit;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URI;
public class GitHubUpdateChecker {
/*
|--------------------------------------------------------------------------
| UPDATE STATUS
|--------------------------------------------------------------------------
*/
private static String latestVersion = null;
private static boolean updateAvailable = false;
private static String updateStatus =
"Checking...";
/*
|--------------------------------------------------------------------------
| CHECK FOR UPDATES
|--------------------------------------------------------------------------
*/
public static void checkForUpdates() {
Bukkit.getScheduler().runTaskAsynchronously(
RSItemMagnet.getInstance(),
() -> {
try {
String apiURL =
"https://raw.githubusercontent.com/"
+ RSConstants.GITHUB_USER
+ "/"
+ RSConstants.GITHUB_REPOSITORY
+ "/master/pom.xml";
HttpURLConnection connection =
(HttpURLConnection)
URI.create(apiURL)
.toURL()
.openConnection();
connection.setRequestMethod("GET");
BufferedReader reader =
new BufferedReader(
new InputStreamReader(
connection.getInputStream()
)
);
StringBuilder response =
new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
reader.close();
String pom =
response.toString();
latestVersion =
pom.split("<version>")[1]
.split("</version>")[0]
.trim();
String currentVersion =
VersionUtils.getVersion();
/*
|--------------------------------------------------------------------------
| UPDATE AVAILABLE
|--------------------------------------------------------------------------
*/
if (latestVersion == null) {
updateStatus =
"Unable To Check";
}
else if (
compareVersions(
latestVersion,
currentVersion
) > 0
) {
updateAvailable =
true;
updateStatus =
"Update Available";
RSItemMagnet.getInstance()
.getLogger()
.warning(
"Update available! Current: "
+ currentVersion
+ " Latest: "
+ latestVersion
);
}
/*
|--------------------------------------------------------------------------
| UP TO DATE
|--------------------------------------------------------------------------
*/
else {
updateAvailable =
false;
updateStatus =
"Up To Date";
Bukkit.getConsoleSender().sendMessage(
RSConstants.PREFIX
+ "RS-ItemMagnet is up to date."
);
}
}
catch (Exception exception) {
latestVersion = null;
updateStatus =
"Unable To Check";
Bukkit.getConsoleSender().sendMessage(
RSConstants.PREFIX
+ "Unable to check for updates."
);
}
}
);
}
/*
|--------------------------------------------------------------------------
| GET LATEST VERSION
|--------------------------------------------------------------------------
*/
public static String getLatestVersion() {
return latestVersion;
}
/*
|--------------------------------------------------------------------------
| GET UPDATE STATUS
|--------------------------------------------------------------------------
*/
public static String getUpdateStatus() {
return updateStatus;
}
/*
|--------------------------------------------------------------------------
| UPDATE AVAILABLE
|--------------------------------------------------------------------------
*/
public static boolean isUpdateAvailable() {
return updateAvailable;
}
/*
|--------------------------------------------------------------------------
| GET LATEST VERSION FOUND
|--------------------------------------------------------------------------
*/
public static String getLatestVersionFound() {
return latestVersion;
}
/*
|--------------------------------------------------------------------------
| VERSION COMPARISON
|--------------------------------------------------------------------------
*/
private static int compareVersions(
String version1,
String version2
) {
String[] v1 =
version1.split("\\.");
String[] v2 =
version2.split("\\.");
int length =
Math.max(
v1.length,
v2.length
);
for (int i = 0; i < length; i++) {
int num1 =
i < v1.length
? Integer.parseInt(v1[i])
: 0;
int num2 =
i < v2.length
? Integer.parseInt(v2[i])
: 0;
if (num1 < num2) {
return -1;
}
if (num1 > num2) {
return 1;
}
}
return 0;
}
}
@@ -0,0 +1,83 @@
package com.rsscripting.itemmagnet.utils;
import org.bukkit.Material;
public class RSConstants {
/*
|--------------------------------------------------------------------------
| PLUGIN INFO
|--------------------------------------------------------------------------
*/
public static final String PLUGIN_NAME =
"RS-ItemMagnet";
public static final String PREFIX =
"§7[§cRS-ItemMagnet§7] §r";
public static final String COMMAND_ALIAS =
"rsitemmagnet";
/*
|--------------------------------------------------------------------------
| GITHUB
|--------------------------------------------------------------------------
*/
public static final String GITHUB_USER =
"RS-Scripting";
public static final String GITHUB_REPOSITORY =
"RS-ItemMagnet";
/*
|--------------------------------------------------------------------------
| PERMISSIONS
|--------------------------------------------------------------------------
*/
public static final String ADMIN_PERMISSION =
"rsitemmagnet.admin";
public static final String BYPASS_PERMISSION =
"rsitemmagnet.bypass";
/*
|--------------------------------------------------------------------------
| REQUIRED CONVERSION ITEMS
|--------------------------------------------------------------------------
*/
public static final Material REQUIRED_HELD_ITEM =
Material.STICK;
/*
|--------------------------------------------------------------------------
| REQUIRED TARGET ENTITY
|--------------------------------------------------------------------------
*/
public static final Material
REQUIRED_TARGET_BLOCK =
Material.LODESTONE;
/*
|--------------------------------------------------------------------------
| MENU SETTINGS
|--------------------------------------------------------------------------
*/
public static final Material MENU_FILLER_MATERIAL =
Material.WHITE_STAINED_GLASS_PANE;
/*
|--------------------------------------------------------------------------
| Version
|--------------------------------------------------------------------------
*/
public static final String VERSION =
"1.0.0";
}
@@ -0,0 +1,20 @@
package com.rsscripting.itemmagnet.utils;
public class RSKeys {
/*
|--------------------------------------------------------------------------
| FILTER MODES
|--------------------------------------------------------------------------
*/
public static final String FILTER_ALLOW_ALL =
"ALLOW_ALL";
public static final String FILTER_WHITELIST =
"WHITELIST";
public static final String FILTER_BLACKLIST =
"BLACKLIST";
}
@@ -0,0 +1,122 @@
package com.rsscripting.itemmagnet.utils;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import net.kyori.adventure.text.Component;
import java.util.List;
public class RSMenuUtils {
/*
|--------------------------------------------------------------------------
| CREATE FILLER PANE
|--------------------------------------------------------------------------
*/
public static ItemStack createFillerPane() {
ItemStack item =
new ItemStack(
RSConstants.MENU_FILLER_MATERIAL
);
ItemMeta meta =
item.getItemMeta();
if (meta != null) {
meta.displayName(
Component.empty()
);
item.setItemMeta(meta);
}
return item;
}
/*
|--------------------------------------------------------------------------
| CREATE MENU ITEM
|--------------------------------------------------------------------------
*/
public static ItemStack createMenuItem(
Material material,
String name
) {
ItemStack item =
new ItemStack(material);
ItemMeta meta =
item.getItemMeta();
if (meta != null) {
meta.displayName(
Component.text(
name
)
);
item.setItemMeta(meta);
}
return item;
}
/*
|--------------------------------------------------------------------------
| CREATE MENU ITEM WITH LORE
|--------------------------------------------------------------------------
*/
public static ItemStack createMenuItem(
Material material,
String name,
List<String> lore
) {
ItemStack item =
new ItemStack(material);
ItemMeta meta =
item.getItemMeta();
if (meta != null) {
meta.displayName(
Component.text(
name
)
);
meta.lore(
lore.stream()
.map(Component::text)
.toList()
);
item.setItemMeta(meta);
}
return item;
}
}
@@ -0,0 +1,171 @@
package com.rsscripting.itemmagnet.utils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.entity.Player;
public class RSMessageUtils {
/*
|--------------------------------------------------------------------------
| PREFIX
|--------------------------------------------------------------------------
*/
private static final Component PREFIX =
Component.text("[")
.color(NamedTextColor.GRAY)
.append(
Component.text(
"RS-ItemMagnet"
).color(
NamedTextColor.RED
)
)
.append(
Component.text("] ")
.color(
NamedTextColor.GRAY
)
);
/*
|--------------------------------------------------------------------------
| SUCCESS
|--------------------------------------------------------------------------
*/
public static void success(
Player player,
String message
) {
player.sendMessage(
PREFIX.append(
Component.text(
message
).color(
NamedTextColor.GREEN
)
)
);
}
/*
|--------------------------------------------------------------------------
| WARNING
|--------------------------------------------------------------------------
*/
@SuppressWarnings("unused")
public static void warning(
Player player,
String message
) {
player.sendMessage(
PREFIX.append(
Component.text(
message
).color(
NamedTextColor.YELLOW
)
)
);
}
/*
|--------------------------------------------------------------------------
| ERROR
|--------------------------------------------------------------------------
*/
public static void error(
Player player,
String message
) {
player.sendMessage(
PREFIX.append(
Component.text(
message
).color(
NamedTextColor.RED
)
)
);
}
/*
|--------------------------------------------------------------------------
| INFO
|--------------------------------------------------------------------------
*/
public static void info(
Player player,
String message
) {
player.sendMessage(
PREFIX.append(
Component.text(
message
).color(
NamedTextColor.AQUA
)
)
);
}
/*
|--------------------------------------------------------------------------
| ADMIN
|--------------------------------------------------------------------------
*/
@SuppressWarnings("unused")
public static void admin(
Player player,
String message
) {
player.sendMessage(
PREFIX.append(
Component.text(
message
).color(
NamedTextColor.GOLD
)
)
);
}
}
@@ -0,0 +1,20 @@
package com.rsscripting.itemmagnet.utils;
import com.rsscripting.itemmagnet.RSItemMagnet;
public class VersionUtils {
/*
|--------------------------------------------------------------------------
| GET INSTALLED VERSION
|--------------------------------------------------------------------------
*/
public static String getVersion() {
return RSItemMagnet.getInstance()
.getDescription()
.getVersion();
}
}
+9
View File
@@ -0,0 +1,9 @@
2.0.0
FIXED
* Issue causing players to be unable to open gates, doors, etc when assigning destination
chests, hoppers, and barrels.
ADDED
* Y distance setting to config allowing server admin to set vertical distance for magnets to scan.
Default: 0 (infinite)
* Trigger in magnet menu to show that magnets radius using a sparkle outline.
+32
View File
@@ -0,0 +1,32 @@
#
# ----------------------------------------
# RS-ItemMagnet Configuration
# ----------------------------------------
#
# Default scan radius for RS-ItemMagnet to scan for dropped items.
default-radius: 10
# Maximum radius players may set their RS-ItemMagnets to.
# 0 = Unlimited.
max-radius: 25
# Seconds allowed to select a target Container.
conversion-timeout: 30
# Distance in blocks ABOVE and BELOW the magnet
# that items may be collected from.
#
# 0 = Unlimited (legacy behavior)
# >0 = Limit vertical collection distance.
item-y-distance: 0
# Maximum distance in blocks a target container may be from the ItemMagnet.
# 0 = Unlimited.
max-target-distance: 30
# Whether OP players bypass permissions checks
admin-bypass: true
# Enable debug logging.
debug-mode: false
+21
View File
@@ -0,0 +1,21 @@
name: RS-ItemMagnet
version: ${project.version}
main: com.rsscripting.itemmagnet.RSItemMagnet
api-version: '1.21'
author: RSScripting
description: RS Item magnet
commands:
rsim:
description: Main plugin command
usage: /rsbt
permissions:
rsim.admin:
description: Admin access
default: op
rsim.bypass:
description: Bypass ownership protection
default: op