-
-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Make heads persistent, arbitrary object serializer (#4)
* Fix typo in URL for WRENCH resource pack and DRY it During module registration, the URL had a trailing 0. * Add general PersistentDataType which uses GSON for arbitrary object serialization * Add PersistentHeads module, allowing for keeping name/lore after placing and breaking them
- Loading branch information
1 parent
b25fd38
commit ed4dc66
Showing
5 changed files
with
138 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions
88
src/main/java/me/machinemaker/vanillatweaks/persistentheads/PersistentHeads.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package me.machinemaker.vanillatweaks.persistentheads; | ||
|
||
import io.papermc.lib.PaperLib; | ||
import io.papermc.lib.features.blockstatesnapshot.BlockStateSnapshotResult; | ||
import me.machinemaker.vanillatweaks.BaseModule; | ||
import me.machinemaker.vanillatweaks.VanillaTweaks; | ||
import me.machinemaker.vanillatweaks.utils.datatypes.JsonDataType; | ||
import org.bukkit.Material; | ||
import org.bukkit.NamespacedKey; | ||
import org.bukkit.block.Block; | ||
import org.bukkit.block.BlockState; | ||
import org.bukkit.block.TileState; | ||
import org.bukkit.entity.Item; | ||
import org.bukkit.event.EventHandler; | ||
import org.bukkit.event.Listener; | ||
import org.bukkit.event.block.BlockBreakEvent; | ||
import org.bukkit.event.block.BlockDropItemEvent; | ||
import org.bukkit.event.block.BlockPlaceEvent; | ||
import org.bukkit.inventory.ItemStack; | ||
import org.bukkit.inventory.meta.ItemMeta; | ||
import org.bukkit.persistence.PersistentDataContainer; | ||
import org.bukkit.persistence.PersistentDataType; | ||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
import java.util.Arrays; | ||
import java.util.List; | ||
|
||
public class PersistentHeads extends BaseModule implements Listener { | ||
|
||
private final NamespacedKey NAME_KEY = new NamespacedKey(plugin, "head_name"); | ||
private final NamespacedKey LORE_KEY = new NamespacedKey(plugin, "head_lore"); | ||
private final PersistentDataType<String,String[]> LORE_PDT = new JsonDataType<>(String[].class); | ||
|
||
public PersistentHeads(VanillaTweaks plugin) { | ||
super(plugin, config -> config.persistHeadData); | ||
} | ||
|
||
@EventHandler | ||
public void onBlockPlaceEvent(BlockPlaceEvent event) { | ||
@NotNull ItemStack headItem = event.getItemInHand(); | ||
if (headItem.getType() != Material.PLAYER_HEAD) return; | ||
ItemMeta meta = headItem.getItemMeta(); | ||
if (meta == null) return; | ||
@NotNull String name = meta.getDisplayName(); | ||
@Nullable List<String> lore = meta.getLore(); | ||
@NotNull Block block = event.getBlockPlaced(); | ||
// NOTE: Not using snapshots is broken: https://github.com/PaperMC/Paper/issues/3913 | ||
BlockStateSnapshotResult blockStateSnapshotResult = PaperLib.getBlockState(block, true); | ||
TileState skullState = (TileState) blockStateSnapshotResult.getState(); | ||
@NotNull PersistentDataContainer skullPDC = skullState.getPersistentDataContainer(); | ||
skullPDC.set(NAME_KEY, PersistentDataType.STRING, name); | ||
if (lore != null) skullPDC.set(LORE_KEY, LORE_PDT, lore.toArray(new String[0])); | ||
if (blockStateSnapshotResult.isSnapshot()) skullState.update(); | ||
} | ||
|
||
@EventHandler | ||
public void onBlockDropItemEvent(BlockDropItemEvent event) { | ||
@NotNull BlockState blockState = event.getBlockState(); | ||
if (blockState.getType() != Material.PLAYER_HEAD) return; | ||
TileState skullState = (TileState) blockState; | ||
@NotNull PersistentDataContainer skullPDC = skullState.getPersistentDataContainer(); | ||
@Nullable String name = skullPDC.get(NAME_KEY, PersistentDataType.STRING); | ||
@Nullable String[] lore = skullPDC.get(LORE_KEY, LORE_PDT); | ||
if (name == null) return; | ||
for (Item item: event.getItems()) { // Ideally should only be one... | ||
@NotNull ItemStack itemstack = item.getItemStack(); | ||
if (itemstack.getType() == Material.PLAYER_HEAD) { | ||
@Nullable ItemMeta meta = itemstack.getItemMeta(); | ||
if (meta == null) continue; // This shouldn't happen | ||
meta.setDisplayName(name); | ||
if (lore != null) meta.setLore(Arrays.asList(lore)); | ||
itemstack.setItemMeta(meta); | ||
} | ||
} | ||
|
||
} | ||
|
||
@Override | ||
public void register() { | ||
registerEvents(this); | ||
} | ||
|
||
@Override | ||
public void unregister() { | ||
unregisterEvents(this); | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
src/main/java/me/machinemaker/vanillatweaks/utils/datatypes/JsonDataType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package me.machinemaker.vanillatweaks.utils.datatypes; | ||
|
||
import com.google.gson.Gson; | ||
import org.bukkit.persistence.PersistentDataAdapterContext; | ||
import org.bukkit.persistence.PersistentDataType; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
/** | ||
* Lets you store arbitrary data in PDC. | ||
* @param <T> | ||
*/ | ||
public class JsonDataType<T> implements PersistentDataType<String, T> { | ||
|
||
private static final Gson gson = new Gson(); | ||
private final Class<T> typeClass; | ||
|
||
public JsonDataType(Class<T> typeClass) { | ||
this.typeClass = typeClass; | ||
} | ||
|
||
@Override | ||
public @NotNull Class<String> getPrimitiveType() { | ||
return String.class; | ||
} | ||
|
||
@Override | ||
public @NotNull Class<T> getComplexType() { | ||
return typeClass; | ||
} | ||
|
||
@NotNull | ||
@Override | ||
public String toPrimitive(@NotNull T complex, @NotNull PersistentDataAdapterContext persistentDataAdapterContext) { | ||
return gson.toJson(complex); | ||
} | ||
|
||
@NotNull | ||
@Override | ||
public T fromPrimitive(@NotNull String primitive, @NotNull PersistentDataAdapterContext context) { | ||
return gson.fromJson(primitive, getComplexType()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters