Initial commit: Right Click Harvester plugin

This commit is contained in:
Professor Doom 2026-05-18 15:04:57 -05:00
commit a780c49f42
24 changed files with 369 additions and 0 deletions

4
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,4 @@
{
"java.configuration.updateBuildConfiguration": "interactive",
"java.compile.nullAnalysis.mode": "disabled"
}

56
pom.xml Normal file
View file

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://www.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>harvester</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>Right Click Harvester</name>
<url>https://example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>papermc</id>
<url>https://repo.papermc.io/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>io.papermc.paper</groupId>
<artifactId>paper-api</artifactId>
<version>1.21.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.11.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
<includes>
<include>plugin.yml</include>
<include>paper-plugin.yml</include>
</includes>
</resource>
</resources>
<plugins>
</plugins>
</build>
</project>

View file

@ -0,0 +1,31 @@
package test;
import org.bukkit.plugin.java.JavaPlugin;
import test.managers.PluginManager;
import test.managers.ConfigManager;
import test.listeners.PlayerListener;
import test.listeners.CropHarvestListener;
public class Harvester extends JavaPlugin {
@Override
public void onEnable() {
// Initialize managers
ConfigManager.initialize(this);
PluginManager.getInstance().initialize();
// Register listeners
getServer().getPluginManager().registerEvents(new PlayerListener(), this);
getServer().getPluginManager().registerEvents(new CropHarvestListener(), this);
getLogger().info("Right Click Harvester has been enabled!");
}
@Override
public void onDisable() {
getLogger().info("Right Click Harvester has been disabled!");
}
}

View file

@ -0,0 +1,110 @@
package test.listeners;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.data.Ageable;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.Damageable;
import test.managers.ConfigManager;
import java.util.Collection;
import java.util.Map;
public class CropHarvestListener implements Listener {
@EventHandler
public void onCropHarvest(PlayerInteractEvent event) {
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
}
Block block = event.getClickedBlock();
if (block == null) {
return;
}
BlockData blockData = block.getBlockData();
if (!(blockData instanceof Ageable ageable)) {
return;
}
// Check if fully grown
if (ageable.getAge() < ageable.getMaximumAge()) {
return;
}
Player player = event.getPlayer();
ItemStack itemInHand = player.getInventory().getItemInMainHand();
ConfigManager.ConfigData config = ConfigManager.getInstance().getConfig();
// Check if holding a hoe
if (config.Require_Hoe && !isHoe(itemInHand.getType())) {
return;
}
// Harvest crop
Collection<ItemStack> drops = block.getDrops(itemInHand);
Material seedType = getSeedType(block.getType());
for (ItemStack drop : drops) {
// If Drop_Seeds is false, skip seeds
if (!config.Drop_Seeds && drop.getType() == seedType) {
continue;
}
if (config.DropTo.equalsIgnoreCase("inventory")) {
Map<Integer, ItemStack> leftover = player.getInventory().addItem(drop);
if (!leftover.isEmpty()) {
// Inventory full!
player.sendActionBar(Component.text("Inventory full!", NamedTextColor.RED));
for (ItemStack item : leftover.values()) {
block.getWorld().dropItemNaturally(block.getLocation(), item);
}
}
} else {
block.getWorld().dropItemNaturally(block.getLocation(), drop);
}
}
// Reset age to 0 (freshly planted)
ageable.setAge(0);
block.setBlockData(ageable);
// Use durability if enabled
if (config.Use_Durability) {
if (itemInHand.getItemMeta() instanceof Damageable damageable) {
damageable.setDamage(damageable.getDamage() + 1);
itemInHand.setItemMeta(damageable);
if (damageable.getDamage() >= itemInHand.getType().getMaxDurability()) {
itemInHand.setAmount(0);
}
}
}
event.setCancelled(true);
}
private boolean isHoe(Material material) {
return material.name().endsWith("_HOE");
}
private Material getSeedType(Material crop) {
return switch (crop) {
case WHEAT -> Material.WHEAT_SEEDS;
case CARROTS -> Material.CARROT;
case POTATOES -> Material.POTATO;
case BEETROOTS -> Material.BEETROOT_SEEDS;
case NETHER_WART -> Material.NETHER_WART;
case COCOA -> Material.COCOA_BEANS;
default -> null;
};
}
}

View file

@ -0,0 +1,13 @@
package test.listeners;
import org.bukkit.event.Listener;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerJoinEvent;
public class PlayerListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
// Handle player join event
}
}

View file

@ -0,0 +1,77 @@
package test.managers;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import test.Harvester;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class ConfigManager {
private static ConfigManager instance;
private final File configFile;
private ConfigData configData;
private final Gson gson;
private ConfigManager(Harvester plugin) {
this.configFile = new File(plugin.getDataFolder(), "harvester.json");
this.gson = new GsonBuilder().setPrettyPrinting().create();
load();
}
public static void initialize(Harvester plugin) {
instance = new ConfigManager(plugin);
}
public static ConfigManager getInstance() {
return instance;
}
public void load() {
if (!configFile.getParentFile().exists()) {
configFile.getParentFile().mkdirs();
}
if (!configFile.exists()) {
this.configData = new ConfigData();
save();
} else {
try (Reader reader = new InputStreamReader(new FileInputStream(configFile), StandardCharsets.UTF_8)) {
this.configData = gson.fromJson(reader, ConfigData.class);
if (this.configData == null) {
this.configData = new ConfigData();
}
} catch (IOException e) {
e.printStackTrace();
this.configData = new ConfigData();
}
}
}
public void save() {
try (Writer writer = new OutputStreamWriter(new FileOutputStream(configFile), StandardCharsets.UTF_8)) {
gson.toJson(configData, writer);
} catch (IOException e) {
e.printStackTrace();
}
}
public ConfigData getConfig() {
return configData;
}
public static class ConfigData {
public String _comment1 = "Drop_Seeds: Whether to drop seeds when harvesting (true/false)";
public boolean Drop_Seeds = true;
public String _comment2 = "Use_Durability: Whether the hoe should lose durability (true/false)";
public boolean Use_Durability = false;
public String _comment3 = "DropTo: Where to put harvested items ('ground' or 'inventory')";
public String DropTo = "ground";
public String _comment4 = "Require_Hoe: Whether a hoe is required to harvest (true/false)";
public boolean Require_Hoe = true;
}
}

View file

@ -0,0 +1,16 @@
package test.managers;
public class PluginManager {
private static PluginManager instance;
public static PluginManager getInstance() {
if (instance == null) {
instance = new PluginManager();
}
return instance;
}
public void initialize() {
// Initialize your managers here
}
}

View file

@ -0,0 +1,21 @@
package test.utils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
public class Utils {
public static Component colorize(String msg) {
if (msg.contains("<") && msg.contains(">")) {
return MiniMessage.miniMessage().deserialize(msg);
}
return LegacyComponentSerializer.legacyAmpersand().deserialize(msg);
}
public static String legacyColorize(String msg) {
return LegacyComponentSerializer.legacyAmpersand().serialize(
LegacyComponentSerializer.legacyAmpersand().deserialize(msg)
);
}
}

View file

@ -0,0 +1,6 @@
name: Harvester
version: 1.0.0-SNAPSHOT
main: test.Harvester
api-version: '1.21'
author: test
folia-supported: true

View file

@ -0,0 +1,5 @@
main: test.Harvester
version: 1.0.0-SNAPSHOT
name: Harvester
author: test
api-version: 1.21

View file

@ -0,0 +1,6 @@
name: Harvester
version: 1.0.0-SNAPSHOT
main: test.Harvester
api-version: '1.21'
author: test
folia-supported: true

View file

@ -0,0 +1,5 @@
main: test.Harvester
version: 1.0.0-SNAPSHOT
name: Harvester
author: test
api-version: 1.21

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,5 @@
#Generated by Maven
#Mon May 18 14:52:10 CDT 2026
artifactId=harvester
groupId=test
version=1.0.0-SNAPSHOT

View file

@ -0,0 +1,8 @@
test/managers/ConfigManager$ConfigData.class
test/managers/PluginManager.class
test/listeners/PlayerListener.class
test/managers/ConfigManager.class
test/utils/Utils.class
test/listeners/CropHarvestListener$1.class
test/Harvester.class
test/listeners/CropHarvestListener.class

View file

@ -0,0 +1,6 @@
/home/bunchy7s/programs/mcplugins/test1/test/src/main/java/test/Harvester.java
/home/bunchy7s/programs/mcplugins/test1/test/src/main/java/test/listeners/PlayerListener.java
/home/bunchy7s/programs/mcplugins/test1/test/src/main/java/test/listeners/CropHarvestListener.java
/home/bunchy7s/programs/mcplugins/test1/test/src/main/java/test/utils/Utils.java
/home/bunchy7s/programs/mcplugins/test1/test/src/main/java/test/managers/PluginManager.java
/home/bunchy7s/programs/mcplugins/test1/test/src/main/java/test/managers/ConfigManager.java