DREAMFIRE Docs ← Back to site
Loading...
Searching...
No Matches
DreamPersistentItemStack.java
Go to the documentation of this file.
1/*
2 * MIT License
3 *
4 * Copyright (c) 2025 Dreamfire Studio
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24package com.dreamfirestudios.dreamcore.DreamPersistentData;
25
26import com.dreamfirestudios.dreamcore.DreamChat.DreamChat;
27import com.dreamfirestudios.dreamcore.DreamChat.DreamMessageSettings;
28import com.dreamfirestudios.dreamcore.DreamCore;
29import org.bukkit.Bukkit;
30import org.bukkit.NamespacedKey;
31import org.bukkit.inventory.ItemStack;
32import org.bukkit.persistence.PersistentDataContainer;
33import org.bukkit.persistence.PersistentDataType;
34import org.bukkit.plugin.java.JavaPlugin;
35
36import java.util.LinkedHashMap;
37import java.util.logging.Level;
38
46
52 public static boolean isValidKey(String key) {
53 return key != null && key.matches("[a-z0-9/._-]{1,256}");
54 }
55
62 public static PersistentDataContainer ReturnPersistentDataContainer(ItemStack itemStack) {
63 if(itemStack == null){
64 throw new IllegalArgumentException("Itemstack cannot be null.");
65 }
66 if(itemStack.getItemMeta() == null){
67 throw new IllegalArgumentException("itemStack.getItemMeta() cannot be null.");
68 }
69 return itemStack.getItemMeta().getPersistentDataContainer();
70 }
71
77 public static LinkedHashMap<PersistentDataTypes, LinkedHashMap<String, Object>> GetALl(ItemStack itemStack){
78 var data = new LinkedHashMap<PersistentDataTypes, LinkedHashMap<String, Object>>();
79 for (var persistentDataType : PersistentDataTypes.values()) {
80 data.put(persistentDataType, GetALl(itemStack, persistentDataType));
81 }
82 return data;
83 }
84
91 public static LinkedHashMap<String, Object> GetALl(ItemStack itemStack, PersistentDataTypes persistentDataType){
92 var data = new LinkedHashMap<String, Object>();
93 try {
94 var persistentDataContainer = ReturnPersistentDataContainer(itemStack);
95 var persistentData = persistentDataType.persistentDataType;
96 for (var namespacedKey : persistentDataContainer.getKeys()) {
97 data.put(namespacedKey.getKey(), persistentDataContainer.get(namespacedKey, persistentData));
98 }
99 } catch (Exception e) {
100 DreamChat.SendMessageToConsole("Error while retrieving persistent data", DreamMessageSettings.all());
101 }
102 return data;
103 }
104
119 public static <T> T Get(JavaPlugin javaPlugin, ItemStack itemStack, String key, PersistentDataType<?, T> type) {
120 if (itemStack == null) {
121 DreamChat.SendMessageToConsole("Itemstack is null. Cannot retrieve persistent data.", DreamMessageSettings.all());
122 return null;
123 }
124 if (!isValidKey(key)) {
125 DreamChat.SendMessageToConsole("Invalid key: " + key, DreamMessageSettings.all());
126 return null;
127 }
128 try {
129 var container = ReturnPersistentDataContainer(itemStack);
130 javaPlugin = javaPlugin == null ? DreamCore.DreamCore : javaPlugin;
131 var namespacedKey = new NamespacedKey(javaPlugin, key);
132 return container.has(namespacedKey, type) ? container.get(namespacedKey, type) : null;
133 } catch (Exception e) {
134 DreamChat.SendMessageToConsole("Error while retrieving persistent data for key: " + key, DreamMessageSettings.all());
135 return null;
136 }
137 }
138
147 public static boolean Has(JavaPlugin javaPlugin, ItemStack itemStack, PersistentDataType persistentDataType, String key) {
148 if (itemStack == null) {
149 DreamChat.SendMessageToConsole("ItemStack is null. Cannot check for persistent data.", DreamMessageSettings.all());
150 return false;
151 }
152 if (!isValidKey(key)) {
153 DreamChat.SendMessageToConsole("Invalid key: " + key, DreamMessageSettings.all());
154 return false;
155 }
156 try {
157 javaPlugin = javaPlugin == null ? DreamCore.DreamCore : javaPlugin;
158 var persistentDataContainer = ReturnPersistentDataContainer(itemStack);
159 var namespacedKey = new NamespacedKey(javaPlugin, key);
160 return persistentDataContainer.has(namespacedKey, persistentDataType);
161 } catch (Exception e) {
162 DreamChat.SendMessageToConsole("Error while checking persistent data for key: " + key, DreamMessageSettings.all());
163 return false;
164 }
165 }
166
177 public static <T> boolean Add(JavaPlugin javaPlugin, ItemStack itemStack, PersistentDataType<?, T> type, String key, T value) {
178 if (itemStack == null) {
179 DreamChat.SendMessageToConsole("ItemStack is null. Cannot add persistent data.", DreamMessageSettings.all());
180 return false;
181 }
182 if (itemStack.getItemMeta() == null) {
183 DreamChat.SendMessageToConsole("itemStack.getItemMeta() is null. Cannot add persistent data.", DreamMessageSettings.all());
184 return false;
185 }
186 if (!isValidKey(key)) {
187 DreamChat.SendMessageToConsole("Invalid key: " + key, DreamMessageSettings.all());
188 return false;
189 }
190 try {
191 javaPlugin = javaPlugin == null ? DreamCore.DreamCore : javaPlugin;
192 var itemMeta = itemStack.getItemMeta();
193 var container = itemMeta.getPersistentDataContainer();
194 var namespacedKey = new NamespacedKey(javaPlugin, key);
195 container.set(namespacedKey, type, value);
196 itemStack.setItemMeta(itemMeta);
197 new PersistentItemStackAddedEvent(itemStack, namespacedKey, value);
198 return true;
199 } catch (Exception e) {
200 DreamChat.SendMessageToConsole("Error while adding persistent data for key: " + key, DreamMessageSettings.all());
201 return false;
202 }
203 }
204
212 public static boolean Remove(JavaPlugin javaPlugin, ItemStack itemStack, String key) {
213 if (itemStack == null) {
214 DreamChat.SendMessageToConsole("ItemStack is null. Cannot add persistent data.", DreamMessageSettings.all());
215 return false;
216 }
217 if (itemStack.getItemMeta() == null) {
218 DreamChat.SendMessageToConsole("itemStack.getItemMeta() is null. Cannot add persistent data.", DreamMessageSettings.all());
219 return false;
220 }
221 if (!isValidKey(key)) {
222 DreamChat.SendMessageToConsole("Invalid key: " + key, DreamMessageSettings.all());
223 return false;
224 }
225 try {
226 javaPlugin = javaPlugin == null ? DreamCore.DreamCore : javaPlugin;
227 var itemMeta = itemStack.getItemMeta();
228 var container = itemMeta.getPersistentDataContainer();
229 var namespacedKey = new NamespacedKey(javaPlugin, key);
230 container.remove(namespacedKey);
231 itemStack.setItemMeta(itemMeta);
232 new PersistentItemStackRemovedEvent(itemStack, namespacedKey);
233 return true;
234 } catch (Exception e) {
235 DreamChat.SendMessageToConsole("Error while adding persistent data for key: " + key, DreamMessageSettings.all());
236 return false;
237 }
238 }
239
250 public static void CloneData(ItemStack from, ItemStack to) {
251 if (from == null || to == null) {
252 DreamChat.SendMessageToConsole("Source or target entity is null. Cannot clone data.", DreamMessageSettings.all());
253 return;
254 }
255 try {
256 var fromData = GetALl(from);
257 fromData.forEach((type, values) -> {
258 values.forEach((key, value) -> Add(null, to, type.persistentDataType, key, value));
259 });
260 } catch (Exception e) {
261 DreamChat.SendMessageToConsole("Error while cloning persistent data.", DreamMessageSettings.all());
262 }
263 }
264
281 public static <T> boolean AddExpiring(JavaPlugin javaPlugin, ItemStack itemStack, PersistentDataType<?, T> type, String key, T value, long expiryMillis) {
282 if (itemStack == null) {
283 DreamChat.SendMessageToConsole("Entity is null. Cannot add expiring persistent data.", DreamMessageSettings.all());
284 return false;
285 }
286 if (!isValidKey(key)) {
287 DreamChat.SendMessageToConsole("Invalid key: " + key, DreamMessageSettings.all());
288 return false;
289 }
290 try {
291 Add(javaPlugin, itemStack, type, key, value);
292 Bukkit.getScheduler().runTaskLater(javaPlugin, () -> Remove(javaPlugin, itemStack, key), expiryMillis / 50);
293 return true;
294 } catch (Exception e) {
295 DreamChat.SendMessageToConsole("Error while adding expiring persistent data for key: " + key, DreamMessageSettings.all());
296 return false;
297 }
298 }
299}
Utilities for reading and writing PersistentDataContainer on ItemStack metadata.
static< T > boolean Add(JavaPlugin javaPlugin, ItemStack itemStack, PersistentDataType<?, T > type, String key, T value)
Adds or updates a typed value for an item stack.
static boolean isValidKey(String key)
Validates a local key for use with NamespacedKey.
static void CloneData(ItemStack from, ItemStack to)
Clones all persistent data from one item stack to another.
static< T > T Get(JavaPlugin javaPlugin, ItemStack itemStack, String key, PersistentDataType<?, T > type)
Retrieves a typed value from an item stack.
static LinkedHashMap< String, Object > GetALl(ItemStack itemStack, PersistentDataTypes persistentDataType)
Retrieves all entries of a specific logical type for an item stack.
static PersistentDataContainer ReturnPersistentDataContainer(ItemStack itemStack)
Gets the persistent data container from an item stack's meta.
static boolean Has(JavaPlugin javaPlugin, ItemStack itemStack, PersistentDataType persistentDataType, String key)
Checks if a key exists for an item stack container.
static LinkedHashMap< PersistentDataTypes, LinkedHashMap< String, Object > > GetALl(ItemStack itemStack)
Retrieves all persistent data grouped by logical types for an item stack.
static< T > boolean AddExpiring(JavaPlugin javaPlugin, ItemStack itemStack, PersistentDataType<?, T > type, String key, T value, long expiryMillis)
Adds a value that expires after the given duration.
static boolean Remove(JavaPlugin javaPlugin, ItemStack itemStack, String key)
Removes a key from an item stack's container.
Event fired when a persistent data entry is removed from an ItemStack.
Logical wrappers over Bukkit PersistentDataType constants, used for grouping and dumping containers b...