DREAMFIRE Docs ← Back to site
Loading...
Searching...
No Matches
DreamPersistentBlock.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.block.Block;
32import org.bukkit.block.TileState;
33import org.bukkit.persistence.PersistentDataContainer;
34import org.bukkit.persistence.PersistentDataType;
35import org.bukkit.plugin.java.JavaPlugin;
36
37import java.util.LinkedHashMap;
38import java.util.logging.Level;
39
48
53 public static boolean isValidKey(String key) {
54 return key != null && key.matches("[a-z0-9/._-]{1,256}");
55 }
56
63 public static PersistentDataContainer ReturnPersistentDataContainer(Block block) {
64 if(block == null){
65 throw new IllegalArgumentException("Block cannot be null.");
66 }
67 if(!(block instanceof TileState tileState)){
68 throw new IllegalArgumentException("Block must be instance of tile state!");
69 }
70 return tileState.getPersistentDataContainer();
71 }
72
84 public static LinkedHashMap<PersistentDataTypes, LinkedHashMap<String, Object>> GetALl(Block block){
85 var data = new LinkedHashMap<PersistentDataTypes, LinkedHashMap<String, Object>>();
86 for(var persistentDataTypeEnum : PersistentDataTypes.values()) data.put(persistentDataTypeEnum, GetALl(block, persistentDataTypeEnum));
87 return data;
88 }
89
96 public static LinkedHashMap<String, Object> GetALl(Block block, PersistentDataTypes persistentDataType){
97 var data = new LinkedHashMap<String, Object>();
98 try {
99 var persistentDataContainer = ReturnPersistentDataContainer(block);
100 var persistentData = persistentDataType.persistentDataType;
101 for (var namespacedKey : persistentDataContainer.getKeys()) {
102 data.put(namespacedKey.getKey(), persistentDataContainer.get(namespacedKey, persistentData));
103 }
104 } catch (Exception e) {
105 DreamChat.SendMessageToConsole("Error while retrieving persistent data", DreamMessageSettings.all());
106 }
107 return data;
108 }
109
124 public static <T> T Get(JavaPlugin javaPlugin, Block block, String key, PersistentDataType<?, T> type) {
125 if (block == null) {
126 DreamChat.SendMessageToConsole("block is null. Cannot retrieve persistent data.", DreamMessageSettings.all());
127 return null;
128 }
129 if (!isValidKey(key)) {
130 DreamChat.SendMessageToConsole("Invalid key: " + key, DreamMessageSettings.all());
131 return null;
132 }
133 try {
134 var container = ReturnPersistentDataContainer(block);
135 javaPlugin = javaPlugin == null ? DreamCore.DreamCore : javaPlugin;
136 var namespacedKey = new NamespacedKey(javaPlugin, key);
137 return container.has(namespacedKey, type) ? container.get(namespacedKey, type) : null;
138 } catch (Exception e) {
139 DreamChat.SendMessageToConsole("Error while retrieving persistent data for key: " + key, DreamMessageSettings.all());
140 return null;
141 }
142 }
143
152 public static boolean Has(JavaPlugin javaPlugin, Block block, PersistentDataType persistentDataType, String key) {
153 if (block == null) {
154 DreamChat.SendMessageToConsole("block is null. Cannot retrieve persistent data.", DreamMessageSettings.all());
155 return false;
156 }
157 if (!isValidKey(key)) {
158 DreamChat.SendMessageToConsole("Invalid key: " + key, DreamMessageSettings.all());
159 return false;
160 }
161 try {
162 javaPlugin = javaPlugin == null ? DreamCore.DreamCore : javaPlugin;
163 var persistentDataContainer = ReturnPersistentDataContainer(block);
164 var namespacedKey = new NamespacedKey(javaPlugin, key);
165 return persistentDataContainer.has(namespacedKey, persistentDataType);
166 } catch (Exception e) {
167 DreamChat.SendMessageToConsole("Error while checking persistent data for key: " + key, DreamMessageSettings.all());
168 return false;
169 }
170 }
171
187 public static <T> boolean Add(JavaPlugin javaPlugin, Block block, PersistentDataType<?, T> type, String key, T value) {
188 if (block == null) {
189 DreamChat.SendMessageToConsole("block is null. Cannot retrieve persistent data.", DreamMessageSettings.all());
190 return false;
191 }
192 if (!isValidKey(key)) {
193 DreamChat.SendMessageToConsole("Invalid key: " + key, DreamMessageSettings.all());
194 return false;
195 }
196 if(!(block instanceof TileState tileState)){
197 throw new IllegalArgumentException("Block must be instance of tile state!");
198 }
199 try {
200 javaPlugin = javaPlugin == null ? DreamCore.DreamCore : javaPlugin;
201 var persistentDataContainer = tileState.getPersistentDataContainer();
202 var namespacedKey = new NamespacedKey(javaPlugin, key);
203 persistentDataContainer.set(namespacedKey, type, value);
204 tileState.update();
205 new PersistentBlockAddedEvent(block, namespacedKey, value);
206 return true;
207 } catch (Exception e) {
208 DreamChat.SendMessageToConsole("Error while adding persistent data for key: " + key, DreamMessageSettings.all());
209 return false;
210 }
211 }
212
220 public static boolean Remove(JavaPlugin javaPlugin, Block block, String key) {
221 if (block == null) {
222 DreamChat.SendMessageToConsole("block is null. Cannot retrieve persistent data.", DreamMessageSettings.all());
223 return false;
224 }
225 if (!isValidKey(key)) {
226 DreamChat.SendMessageToConsole("Invalid key: " + key, DreamMessageSettings.all());
227 return false;
228 }
229 if(!(block instanceof TileState tileState)){
230 throw new IllegalArgumentException("Block must be instance of tile state!");
231 }
232 try {
233 javaPlugin = javaPlugin == null ? DreamCore.DreamCore : javaPlugin;
234 var persistentDataContainer = tileState.getPersistentDataContainer();
235 var namespacedKey = new NamespacedKey(javaPlugin, key);
236 persistentDataContainer.remove(namespacedKey);
237 tileState.update();
238 new PersistentBlockRemovedEvent(block, namespacedKey);
239 return true;
240 } catch (Exception e) {
241 DreamChat.SendMessageToConsole("Error while adding persistent data for key: " + key, DreamMessageSettings.all());
242 return false;
243 }
244 }
245
256 public static void CloneData(Block from, Block to) {
257 if (from == null || to == null) {
258 DreamChat.SendMessageToConsole("Source or target entity is null. Cannot clone data.", DreamMessageSettings.all());
259 return;
260 }
261 try {
262 var fromData = GetALl(from);
263 fromData.forEach((type, values) -> {
264 values.forEach((key, value) -> Add(null, to, type.persistentDataType, key, value));
265 });
266 } catch (Exception e) {
267 DreamChat.SendMessageToConsole("Error while cloning persistent data.", DreamMessageSettings.all());
268 }
269 }
270
287 public static <T> boolean AddExpiring(JavaPlugin javaPlugin, Block block, PersistentDataType<?, T> type, String key, T value, long expiryMillis) {
288 if (block == null) {
289 DreamChat.SendMessageToConsole("Entity is null. Cannot add expiring persistent data.", DreamMessageSettings.all());
290 return false;
291 }
292 if (!isValidKey(key)) {
293 DreamChat.SendMessageToConsole("Invalid key: " + key, DreamMessageSettings.all());
294 return false;
295 }
296 try {
297 Add(javaPlugin, block, type, key, value);
298 Bukkit.getScheduler().runTaskLater(javaPlugin, () -> Remove(javaPlugin, block, key), expiryMillis / 50);
299 return true;
300 } catch (Exception e) {
301 DreamChat.SendMessageToConsole("Error while adding expiring persistent data for key: " + key, DreamMessageSettings.all());
302 return false;
303 }
304 }
305}
Utilities for working with PersistentDataContainer on Block tile entities.
static LinkedHashMap< String, Object > GetALl(Block block, PersistentDataTypes persistentDataType)
Retrieves all persistent data of a specific type from a block's container.
static boolean isValidKey(String key)
Validates whether a given key conforms to NamespacedKey requirements.
static LinkedHashMap< PersistentDataTypes, LinkedHashMap< String, Object > > GetALl(Block block)
Retrieves all persistent data stored in a block's container, grouped by data types.
static boolean Remove(JavaPlugin javaPlugin, Block block, String key)
Removes a value by key from a block's container.
static< T > boolean Add(JavaPlugin javaPlugin, Block block, PersistentDataType<?, T > type, String key, T value)
Adds or updates a typed value in a block's container.
static void CloneData(Block from, Block to)
Clones all persistent data from one block to another (key/type preserving).
static PersistentDataContainer ReturnPersistentDataContainer(Block block)
Returns the PersistentDataContainer for a tile Block.
static boolean Has(JavaPlugin javaPlugin, Block block, PersistentDataType persistentDataType, String key)
Checks if a key exists in a block's container.
static< T > T Get(JavaPlugin javaPlugin, Block block, String key, PersistentDataType<?, T > type)
Retrieves a typed value for a given key from a block's container.
static< T > boolean AddExpiring(JavaPlugin javaPlugin, Block block, PersistentDataType<?, T > type, String key, T value, long expiryMillis)
Adds a value that automatically expires after a given duration.
Event fired when a persistent data entry is removed from a Block.
Logical wrappers over Bukkit PersistentDataType constants, used for grouping and dumping containers b...