v3.0 Release

This commit is contained in:
NotAlexNoyle committed 2024-07-05 22:39:43 -04:00
1 parent 9152e4d385
commit 54e6927103
10 files changed
+292 -148

No files matched your search

+12 -14
View File
@@ -1,18 +1,6 @@
# Compiled class file
*.class
# Eclipse classpath file
*.classpath
# Eclipse project file
*.project
# Eclipse settings
*.settings
# Gradle build output
bin/
# Log file
*.log
@@ -33,7 +21,17 @@ bin/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*
# Gradle post-build folders
.gradle
# macOS system files
.DS_Store
# gradle build output files
build/
.gradle/
# eclipse project files
.settings/
.project
.classpath
bin/
+10 -2
View File
@@ -14,6 +14,14 @@ To build:
The resulting .jar file will be in build/libs/
*Version 3.0 Changelog:*
- Setting the age now applies to all items.
- Added more logic for persistence.
- Added support for human readable time format.
*Version 2.1 Changelog:*
- Fixed NBT-API import in gradle.
@@ -44,9 +52,9 @@ The resulting .jar file will be in build/libs/
- Change the amount of time it takes for items to despawn.
- Set in-game warnings for when items are about to despawn. (Coming in 3.0)
- Set in-game warnings for when items are about to despawn. (Coming in 3.1)
- Clear items with an in-game command. (Coming in 3.0)
- Clear items with an in-game command. (Coming in 3.1)
Uses [NBTAPI](https://github.com/tr7zw/Item-NBT-API).
-68
View File
@@ -1,68 +0,0 @@
plugins {
id "java" // Tell gradle this is a java project.
id "com.github.johnrengelman.shadow" version "7.1.2" // Import utility to package libraries into .jar file.
}
group = "net.trueog.nodespawnog" // Declare package name.
version = "2.1" // Declare package version.
def apiVersion = "1.19.4" // Declare minecraft server target version.
def targetJavaVersion = 17 // Declare java compatibility minimum.
apply plugin: "eclipse" // Enable integration with Eclipse IDE for development.
processResources {
def props = [
version: version,
apiVersion: apiVersion,
]
inputs.properties props // Indicates to rerun if version changes.
filesMatching("plugin.yml") {
expand props
}
}
repositories {
mavenCentral()
maven {
url "https://repo.purpurmc.org/snapshots" // Get purpur API from purpur maven repository.
}
maven {
name = "CodeMC"
url = uri("https://repo.codemc.org/repository/maven-public/") // Get NBT-API from codemc maven repository.
}
}
dependencies {
compileOnly "org.purpurmc.purpur:purpur-api:1.18.2-R0.1-SNAPSHOT" // Declare purpur API version to be packaged.
implementation("de.tr7zw:item-nbt-api:2.11.1") // Declare NBT-API version to be packaged.
}
shadowJar {
minimize()
relocate 'de.tr7zw', 'net.trueog.nodespawnog.item-nbt-api' // Prevent conflicts with other NBT-API utilizing plugins.
}
jar.dependsOn shadowJar
+93
View File
@@ -0,0 +1,93 @@
plugins {
java // Tell gradle this is a java project.
id("io.github.goooler.shadow") version "8.1.8"
eclipse // Import eclipse plugin for IDE integration.
kotlin("jvm") version "1.9.23" // Import kotlin jvm plugin for kotlin/java integration.
}
java {
// Declare java version.
sourceCompatibility = JavaVersion.VERSION_17
}
group = "net.trueog.nodespawnog" // Declare bundle identifier.
version = "3.0" // Declare plugin version (will be in .jar).
val apiVersion = "1.19" // Declare minecraft server target version.
tasks.named<ProcessResources>("processResources") {
val props = mapOf(
"version" to version,
"apiVersion" to apiVersion
)
inputs.properties(props) // Indicates to rerun if version changes.
filesMatching("plugin.yml") {
expand(props)
}
}
repositories {
mavenCentral()
maven {
url = uri("https://repo.purpurmc.org/snapshots")
}
maven {
url = uri("https://repo.codemc.org/repository/maven-public/") // Get NBT-API from codemc maven repository.
}
}
dependencies {
compileOnly("org.purpurmc.purpur:purpur-api:1.19.4-R0.1-SNAPSHOT") // Declare purpur API version to be packaged.
compileOnly("io.github.miniplaceholders:miniplaceholders-api:2.2.3") // Import MiniPlaceholders API.
implementation("de.tr7zw:item-nbt-api:2.11.1") // Declare NBT-API version to be packaged.
}
tasks.withType<AbstractArchiveTask>().configureEach {
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
}
tasks.shadowJar {
exclude("io.github.miniplaceholders.*") // Exclude the MiniPlaceholders package from being shadowed.
relocate("de.tr7zw", "net.trueog.nodespawnog.item-nbt-api") // Prevent conflicts with other NBT-API utilizing plugins
minimize()
}
tasks.jar {
dependsOn(tasks.shadowJar)
archiveClassifier.set("part")
}
tasks.shadowJar {
archiveClassifier.set("") // Use empty string instead of null
from("LICENSE") {
into("/")
}
}
tasks.jar {
dependsOn("shadowJar")
}
tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add("-parameters")
options.encoding = "UTF-8"
options.isFork = true
}
kotlin {
jvmToolchain(17)
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(17)
vendor = JvmVendorSpec.GRAAL_VM
}
}
Vendored
+1 -1
View File
@@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
File renamed without changes.
@@ -1,13 +1,23 @@
package net.trueog.nodespawnog;
import org.bukkit.Chunk;
import org.bukkit.NamespacedKey;
import org.bukkit.World;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import de.tr7zw.changeme.nbtapi.NBTEntity;
import de.tr7zw.changeme.nbtapi.NBTItem;
// Class to watch for in-game events.
public class EventListener implements Listener {
@@ -18,87 +28,190 @@ public class EventListener implements Listener {
// If despawn time is set to this, it never changes.
public short minimumValue = -32768;
// Get the user-set death despawn time value.
private short valueOfDespawnTime() {
// Determine the despawn time using the number taken from the config file.
private short calculateDespawnTime() {
// Declare an empty short object for holding the death despawn time from the config file after input validation.
short valueOfDespawnTime = 0;
// Get the user-defined despawn time from the config file.
String timeString = config.getString("time-to-death-despawns");
// Read config for death despawn in such a way as to validate that it would be a valid 'short'.
try {
// If the config value is empty, do this...
if (timeString == null || timeString.isEmpty()) {
// TODO: Allow for specifying time in seconds, minutes, or hours, instead of ticks.
// Get value for time to death despawns from config file.
int intOfDespawnTime = config.getInt("time-to-death-despawns");
// Convert the integer specified by the user to a negative short via a string for data type compliance and error handling.
valueOfDespawnTime = Short.valueOf(String.valueOf(-1 * intOfDespawnTime));
// Set short to valid user-set death despawn time.
// This will only run if the short the user specified in the config was in range.
return valueOfDespawnTime;
// Default to 5 minutes (using ticks).
return Short.valueOf(String.valueOf(-1 * 6000));
}
// If the value the user set in the config is out of range, do this.
catch(NumberFormatException error) {
// Return default value of 6000 ticks (5 minutes) to replace invalid user-set value in the config.
// Deconstruct and interpret the user-specified time string.
try {
// Declare a variable to hold the time.
long time;
// Extract the unit (s, m, h).
String unit = timeString.replaceAll("\\d", "");
// Extract the numeric value.
int value = Integer.parseInt(timeString.replaceAll("\\D", ""));
switch (unit.toLowerCase()) {
case "s":
// Convert seconds to ticks.
time = value * 20L;
break;
case "m":
// Convert minutes to ticks.
time = value * 20L * 60L;
break;
case "h":
// Convert hours to ticks.
time = value * 20L * 60L * 60L;
break;
default:
// Default to ticks if no unit is provided.
time = value;
}
// Start the countdown to despawn.
return Short.valueOf(String.valueOf(-1 * time));
}
// If the user-specified time string is in an invalid format, do this...
catch (NumberFormatException error) {
// Default to 5 minutes (using ticks).
return Short.valueOf(String.valueOf(-1 * 6000));
}
}
// Override entityDeathEvent with the highest possible priority.
// Prioritize this event listener over all other plugins.
@EventHandler(priority = EventPriority.HIGHEST)
public void entityDeathEvent(EntityDeathEvent PlayerDeathEvent) {
// Runs whenever an entity dies.
public void entityDeathEvent(EntityDeathEvent event) {
// If a player died, do this.
if (PlayerDeathEvent.getEntity().getType().equals(org.bukkit.entity.EntityType.PLAYER)) {
// Check if the entity is a player.
if (! (event.getEntity() instanceof Player)) {
// If the player's inventory was not empty, do this.
if(! PlayerDeathEvent.getDrops().isEmpty()) {
// If the entity is not a player, skip this event.
return;
// If disable death despawns option is enabled in config file, do this.
if(config.getBoolean("disable-death-despawns") == true) {
}
// For each intended drop item, do this.
PlayerDeathEvent.getDrops().forEach(element -> {
// If the player's inventory was not empty...
if (! event.getDrops().isEmpty()) {
// Get what the item was.
Item droppedItem = PlayerDeathEvent.getEntity().getWorld().dropItem(PlayerDeathEvent.getEntity().getLocation(), element);
// Loop through every item in the death pile.
event.getDrops().forEach(itemStack -> {
// Create a new item drop of the same thing using NBT.
NBTEntity newDropNBT = new NBTEntity(droppedItem);
// Get each item from the dropped entities.
Item droppedItem = event.getEntity().getWorld().dropItem(event.getEntity().getLocation(), itemStack);
NBTItem nbtItem = new NBTItem(itemStack);
// Set items upon death to stay spawned in infinitely
newDropNBT.setShort("Age", minimumValue);
// Set the Age tag based on the value set in the config file.
nbtItem.setShort("Age", config.getBoolean("disable-death-despawns") ? minimumValue : calculateDespawnTime());
});
// Save the modified NBT data.
PersistentDataContainer pdc = droppedItem.getPersistentDataContainer();
NamespacedKey key = new NamespacedKey(NoDespawnOG.getPlugin(), "nodespawn_age");
pdc.set(key, PersistentDataType.INTEGER, (int) nbtItem.getShort("Age"));
// Delete the original entities to prevent duplication.
PlayerDeathEvent.getDrops().clear();
// Apply the modified NBTItem back to the ItemStack and update the dropped Item.
itemStack = nbtItem.getItem();
droppedItem.setItemStack(itemStack);
});
// Clear the original drops.
event.getDrops().clear();
}
}
// Runs every time a chunk is loaded.
@EventHandler
public void onChunkLoad(ChunkLoadEvent event) {
// Get the chunk that was loaded.
Chunk chunk = event.getChunk();
// Loop through every entity in the chunk.
for (Entity entity : chunk.getEntities()) {
// If the entity is an Item, do this...
if (entity instanceof Item) {
// Cast the entity to an Item since it is one.
Item item = (Item) entity;
// Declare a container to hold item data.
PersistentDataContainer pdc = item.getPersistentDataContainer();
NamespacedKey key = new NamespacedKey(NoDespawnOG.getPlugin(), "nodespawn_age");
// Check for item age.
if (pdc.has(key, PersistentDataType.INTEGER)) {
// Derive the item age.
short savedAge = pdc.get(key, PersistentDataType.INTEGER).shortValue();
// Get the ItemStack from the Item.
ItemStack itemStack = item.getItemStack();
// Apply the saved age using NBTItem.
NBTItem nbtItem = new NBTItem(itemStack);
nbtItem.setShort("Age", savedAge);
itemStack = nbtItem.getItem();
// Update the Item with the modified ItemStack.
item.setItemStack(itemStack);
}
// If disable death despawns is disabled in the config file, do this.
else {
// For each intended drop item, do this.
PlayerDeathEvent.getDrops().forEach(element -> {
}
// Get what the item was.
Item droppedItem = PlayerDeathEvent.getEntity().getWorld().dropItem(PlayerDeathEvent.getEntity().getLocation(), element);
}
// Create a new item drop of the same thing using NBT.
NBTEntity newDropNBT = new NBTEntity(droppedItem);
}
// Set items upon death to stay spawned in for the calculated amount of time.
newDropNBT.setShort("Age", valueOfDespawnTime());
// Runs every time a world is loaded.
@EventHandler
public void onWorldLoad(WorldLoadEvent event) {
});
// Get the world that was loaded.
World world = event.getWorld();
// Loop through all loaded chunks in the world.
for (Chunk chunk : world.getLoadedChunks()) {
// Delete the original entities to prevent duplication.
PlayerDeathEvent.getDrops().clear();
// Loop through every entity in the chunk.
for (Entity entity : chunk.getEntities()) {
// If the entity is an Item, do this...
if (entity instanceof Item) {
// Cast the entity to an Item since it is one.
Item item = (Item) entity;
// Declare a container to hold item data.
PersistentDataContainer pdc = item.getPersistentDataContainer();
NamespacedKey key = new NamespacedKey(NoDespawnOG.getPlugin(), "nodespawn_age");
// Check for item age.
if (pdc.has(key, PersistentDataType.INTEGER)) {
// Derive the item age.
short savedAge = pdc.get(key, PersistentDataType.INTEGER).shortValue();
// Get the ItemStack from the Item.
ItemStack itemStack = item.getItemStack();
// Apply the saved age using NBTItem.
NBTItem nbtItem = new NBTItem(itemStack);
nbtItem.setShort("Age", savedAge);
itemStack = nbtItem.getItem();
// Update the Item with the modified ItemStack.
item.setItemStack(itemStack);
}
}
@@ -23,7 +23,7 @@ public class NoDespawnOG extends JavaPlugin {
saveDefaultConfig();
// Log valid plugin launch to console.
getLogger().info("NoDespawn 2.1 Loaded.");
getLogger().info("NoDespawn 2.2 Loaded.");
}
@@ -31,7 +31,7 @@ public class NoDespawnOG extends JavaPlugin {
@Override public void onDisable() {
// Log valid plugin shut-down to console.
getLogger().info("NoDespawn 2.1 Shut Down without errors.");
getLogger().info("NoDespawn 2.2 Shut Down without errors.");
}
+7 -7
View File
@@ -1,14 +1,14 @@
# NoDespawn-OG 2.1 Config.
# NoDespawn-OG 3.0 Config.
# Should item despawning be completely disabled on player death?
disable-death-despawns: true
# How long should all other entities take to despawn? (in ticks).
# How long should all other entities take to despawn? (in ticks, seconds (s), minutes (m), or hours (h))
# The vanilla behavior is 300 seconds, or 5 Minutes (roughly 6000 ticks).
# This will not impact non-death-pile entities until 3.0.
time-to-despawn: 6000
# If the format of this option is invalid, NoDespawn-OG will default to 5 minutes.
time-to-despawn: 5m
# If disable despawns is set to false, how long (in ticks) should items dropped on death last until despawn?
# Values range from 0 (instant despawn) to 32767 ticks (roughly 27 minutes).
# If disable despawns is set to false, how long (in ticks, seconds (s), minutes (m), or hours (h))
# should items dropped on death last until despawn?
# If higher than the max or lower than the min, defaults to the value of time-to-despawn above.
time-to-death-despawns: 12000
time-to-death-despawns: 20m
+2 -2
View File
@@ -3,5 +3,5 @@ name: NoDespawn-OG
authors: [BadPylot, NotAlexNoyle]
description: A Spigot plugin that allows you to easily determine when exactly you or others first joined the server!
website: https://github.com/NotAlexNoyle/NoDespawn-OG
version: 2.1
api-version: 1.19
version: '${version}'
api-version: 1.19