Merge pull request #18 from BlazingGames/lodestone-interface-refactor
All checks were successful
Build, Test and Publish / test (push) Successful in 4m39s
Build, Test and Publish / build-and-publish (push) Successful in 2m42s

make the lodestone interface use the UserInterface class
This commit is contained in:
XTerPL 2025-01-31 18:55:53 +01:00 committed by GitHub
commit 7372118f84
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 194 additions and 126 deletions

View file

@ -31,7 +31,6 @@ import de.blazemcworld.blazinggames.packs.ResourcePackManager;
import de.blazemcworld.blazinggames.packs.ResourcePackManager.PackConfig;
import de.blazemcworld.blazinggames.items.recipes.CustomRecipes;
import de.blazemcworld.blazinggames.teleportanchor.LodestoneInteractionEventListener;
import de.blazemcworld.blazinggames.teleportanchor.LodestoneInventoryClickEventListener;
import io.jsonwebtoken.Jwts.SIG;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.DecodingException;
@ -55,7 +54,6 @@ import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
@ -226,7 +224,6 @@ public class BlazingGames extends JavaPlugin {
pluginManager.registerEvents(new BlockPlaceEventListener(), this);
pluginManager.registerEvents(new SpawnerSpawnEventListener(), this);
pluginManager.registerEvents(new LodestoneInteractionEventListener(), this);
pluginManager.registerEvents(new LodestoneInventoryClickEventListener(), this);
pluginManager.registerEvents(new BlockDestroyEventListener(), this);
pluginManager.registerEvents(new BlockExplodeEventListener(), this);
pluginManager.registerEvents(new EntityExplodeEventListener(), this);

View file

@ -26,7 +26,7 @@ public class BlockDestroyEventListener implements Listener {
@EventHandler
public void onExplosion(BlockDestroyEvent event) {
if (event.getBlock().getType() == Material.LODESTONE) {
LodestoneStorage.destoryLodestone(event.getBlock().getLocation());
LodestoneStorage.destroyLodestone(event.getBlock().getLocation());
LodestoneStorage.refreshAllInventories();
}
}

View file

@ -31,7 +31,7 @@ public class BlockExplodeEventListener implements Listener {
List<Block> blocks = event.blockList();
for (Block block : blocks) {
if (block.getType() == Material.LODESTONE) {
LodestoneStorage.destoryLodestone(block.getLocation());
LodestoneStorage.destroyLodestone(block.getLocation());
LodestoneStorage.refreshAllInventories();
}
}

View file

@ -342,7 +342,7 @@ public class BreakBlockEventListener implements Listener {
private static void onAnyBlockBreak(Block block) {
if (block.getType() == Material.LODESTONE) {
LodestoneStorage.destoryLodestone(block.getLocation());
LodestoneStorage.destroyLodestone(block.getLocation());
LodestoneStorage.refreshAllInventories();
}

View file

@ -31,7 +31,7 @@ public class EntityExplodeEventListener implements Listener {
List<Block> blocks = event.blockList();
for (Block block : blocks) {
if (block.getType() == Material.LODESTONE) {
LodestoneStorage.destoryLodestone(block.getLocation());
LodestoneStorage.destroyLodestone(block.getLocation());
LodestoneStorage.refreshAllInventories();
}
}

View file

@ -17,10 +17,8 @@ package de.blazemcworld.blazinggames.teleportanchor;
import de.blazemcworld.blazinggames.BlazingGames;
import de.blazemcworld.blazinggames.items.CustomItems;
import de.blazemcworld.blazinggames.utils.TextLocation;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket;
@ -36,14 +34,10 @@ 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.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class LodestoneInteractionEventListener implements Listener {
@EventHandler
@ -60,7 +54,10 @@ public class LodestoneInteractionEventListener implements Listener {
signLines.add(Component.text(""));
signLines.add(Component.text("^^^^^^^^^^^^^^^"));
sendSignPacket(event.getPlayer(), signLocation, signLines);
} else openTeleportAnchor(event.getPlayer());
}
else {
event.getPlayer().openInventory(new TeleportAnchorInterface(BlazingGames.get(), event.getPlayer()).getInventory());
}
}
}
}
@ -95,32 +92,4 @@ public class LodestoneInteractionEventListener implements Listener {
});
}, 1);
}
public static void openTeleportAnchor(Player player) {
Inventory inventory = Bukkit.createInventory(null, 54, Component.text("Teleportation Menu").color(NamedTextColor.AQUA));
Map<Location, String> lodestones = LodestoneStorage.getSavedLodestones(player.getUniqueId());
ItemStack[] items = new ItemStack[lodestones.size()];
int index = 0;
for (Location lodestoneLoc : lodestones.keySet()) {
String lodestoneName = lodestones.get(lodestoneLoc);
ItemStack lodeStoneItem = new ItemStack(Material.LODESTONE);
ItemMeta meta = lodeStoneItem.getItemMeta();
meta.displayName(Component.text(lodestoneName).color(NamedTextColor.AQUA).decoration(TextDecoration.ITALIC, false));
List<Component> lore = new ArrayList<>();
lore.add(Component.text("World: " + lodestoneLoc.getWorld().getName()).color(NamedTextColor.WHITE).decoration(TextDecoration.ITALIC, false));
lore.add(Component.text("X: " + lodestoneLoc.getBlockX() + " Y: " + lodestoneLoc.getBlockY() + " Z: " + lodestoneLoc.getBlockZ()).color(NamedTextColor.WHITE).decoration(TextDecoration.ITALIC, false));
meta.lore(lore);
meta.getPersistentDataContainer().set(new NamespacedKey("blazinggames", "loc"), PersistentDataType.STRING, TextLocation.serializeRounded(lodestoneLoc));
lodeStoneItem.setItemMeta(meta);
items[index] = lodeStoneItem;
index++;
}
inventory.setContents(items);
player.openInventory(inventory);
}
}

View file

@ -1,63 +0,0 @@
/*
* Copyright 2025 The Blazing Games Maintainers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.blazemcworld.blazinggames.teleportanchor;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import de.blazemcworld.blazinggames.utils.TextLocation;
public class LodestoneInventoryClickEventListener implements Listener {
@EventHandler
public void onLodestoneClick(InventoryClickEvent event) {
if (event.getView().title().equals(Component.text("Teleportation Menu").color(NamedTextColor.AQUA))) {
event.setCancelled(true);
if (event.getCurrentItem() == null) return;
Player player = (Player) event.getWhoClicked();
ItemMeta meta = event.getCurrentItem().getItemMeta();
if (!meta.getPersistentDataContainer().has(new NamespacedKey("blazinggames", "loc"))) return;
Location location = TextLocation.deserialize(meta.getPersistentDataContainer().get(new NamespacedKey("blazinggames", "loc"), PersistentDataType.STRING));
if (location == null) return;
if (location.getBlock().getType() != Material.LODESTONE || event.getClick() == ClickType.SHIFT_LEFT || event.getClick() == ClickType.SHIFT_RIGHT) {
LodestoneStorage.removeSavedLodestoneForPlayer(player.getUniqueId(), location);
player.playSound(player.getLocation(), Sound.ENTITY_ENDER_EYE_DEATH, 1, 1);
LodestoneInteractionEventListener.openTeleportAnchor(player);
} else {
location = location.toCenterLocation();
location.setY(location.getY() + 1);
location.setPitch(player.getLocation().getPitch());
location.setYaw(player.getLocation().getYaw());
player.teleport(location);
player.playSound(location, Sound.ITEM_CHORUS_FRUIT_TELEPORT, 1, 1);
event.getView().close();
}
}
}
}

View file

@ -0,0 +1,100 @@
/*
* Copyright 2025 The Blazing Games Maintainers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.blazemcworld.blazinggames.teleportanchor;
import de.blazemcworld.blazinggames.userinterfaces.UserInterface;
import de.blazemcworld.blazinggames.userinterfaces.UserInterfaceSlot;
import io.papermc.paper.datacomponent.DataComponentTypes;
import io.papermc.paper.datacomponent.item.ItemLore;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.event.inventory.InventoryAction;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class LodestoneSlot implements UserInterfaceSlot {
private final int index;
public LodestoneSlot(int index) {
this.index = index;
}
@Override
public void onUpdate(UserInterface inventory, int slot) {
if(!(inventory instanceof TeleportAnchorInterface tpi)) {
return;
}
Map.Entry<Location, String> lodestone = tpi.getLodestone(index);
if(lodestone == null) {
inventory.setItem(slot, ItemStack.empty());
return;
}
ItemStack lodestoneItem = new ItemStack(Material.LODESTONE);
Location loc = lodestone.getKey();
lodestoneItem.setData(DataComponentTypes.ITEM_NAME, Component.text(lodestone.getValue()).color(NamedTextColor.AQUA));
List<Component> lore = new ArrayList<>();
lore.add(Component.text("World: " + loc.getWorld().getName()).color(NamedTextColor.WHITE).decoration(TextDecoration.ITALIC, false));
lore.add(Component.text("X: " + loc.getBlockX() + " Y: " + loc.getBlockY() + " Z: " + loc.getBlockZ()).color(NamedTextColor.WHITE).decoration(TextDecoration.ITALIC, false));
lodestoneItem.setData(DataComponentTypes.LORE, ItemLore.lore(lore));
inventory.setItem(slot, lodestoneItem);
}
@Override
public boolean onClick(UserInterface inventory, ItemStack current, ItemStack cursor, int slot, InventoryAction action, boolean isShiftClick, InventoryClickEvent event) {
if(!(inventory instanceof TeleportAnchorInterface tpi) || isShiftClick) {
return false;
}
Map.Entry<Location, String> lodestone = tpi.getLodestone(index);
if(lodestone == null) {
return false;
}
if(lodestone.getKey().getBlock().getType() != Material.LODESTONE || event.isShiftClick()) {
LodestoneStorage.removeSavedLodestoneForPlayer(tpi.getPlayer().getUniqueId(), lodestone.getKey());
tpi.getPlayer().playSound(tpi.getPlayer().getLocation(), Sound.ENTITY_ENDER_EYE_DEATH, 1, 1);
tpi.reload();
return false;
}
Location tpLoc = lodestone.getKey().toCenterLocation();
tpLoc.setY(tpLoc.getY() + 1);
tpLoc.setPitch(tpi.getPlayer().getLocation().getPitch());
tpLoc.setYaw(tpi.getPlayer().getLocation().getYaw());
tpi.getPlayer().teleport(tpLoc);
tpi.getPlayer().playSound(tpLoc, Sound.ITEM_CHORUS_FRUIT_TELEPORT, 1, 1);
event.getView().close();
return false;
}
}

View file

@ -31,14 +31,12 @@ import de.blazemcworld.blazinggames.data.compression.GZipCompressionProvider;
import de.blazemcworld.blazinggames.data.name.ULIDNameProvider;
import de.blazemcworld.blazinggames.data.storage.GsonStorageProvider;
import de.blazemcworld.blazinggames.utils.TextLocation;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
public class LodestoneStorage {
private LodestoneStorage() {}
private static final DataStorage<HashMap<UUID, String>, String> dataStorage = DataStorage.forClass(
LodestoneStorage.class, null,
new GsonStorageProvider<HashMap<UUID, String>>(new TypeToken<HashMap<UUID, String>>() {}.getType()),
new GsonStorageProvider<>(new TypeToken<HashMap<UUID, String>>() {}.getType()),
new ULIDNameProvider(), new GZipCompressionProvider()
);
@ -61,14 +59,14 @@ public class LodestoneStorage {
.stream().collect(Collectors.toMap(TextLocation::deserialize, i -> dataStorage.getData(i).getOrDefault(player, "error")));
}
public static void destoryLodestone(Location location) {
public static void destroyLodestone(Location location) {
dataStorage.deleteData(TextLocation.serializeRounded(location));
}
public static void refreshAllInventories() {
for (Player p : Bukkit.getOnlinePlayers()) {
if (p.getOpenInventory().title().equals(Component.text("Teleportation Menu").color(NamedTextColor.AQUA))) {
LodestoneInteractionEventListener.openTeleportAnchor(p);
if (p.getInventory().getHolder(false) instanceof TeleportAnchorInterface tpi) {
tpi.reload();
}
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright 2025 The Blazing Games Maintainers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.blazemcworld.blazinggames.teleportanchor;
import de.blazemcworld.blazinggames.BlazingGames;
import de.blazemcworld.blazinggames.userinterfaces.UserInterface;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.Map;
public class TeleportAnchorInterface extends UserInterface {
private final Player player;
private final Map<Location, String> lodestones = new HashMap<>();
public TeleportAnchorInterface(BlazingGames plugin, Player player) {
super(plugin, "Teleport Anchor", 6);
this.player = player;
}
public Player getPlayer() {
return player;
}
public Map.Entry<Location, String> getLodestone(int index) {
int current = 0;
for(Map.Entry<Location, String> lodestone : lodestones.entrySet()) {
if(current == index) {
return lodestone;
}
current++;
}
return null;
}
@Override
protected void preload() {
for(int i = 0; i < 6*9; i++) {
addSlot(i, new LodestoneSlot(i));
}
}
@Override
protected void reload() {
reloadLodestones();
super.reload();
}
private void reloadLodestones() {
this.lodestones.clear();
this.lodestones.putAll(LodestoneStorage.getSavedLodestones(player.getUniqueId()));
}
}

View file

@ -16,10 +16,8 @@
package de.blazemcworld.blazinggames.userinterfaces;
import de.blazemcworld.blazinggames.BlazingGames;
import de.blazemcworld.blazinggames.utils.NamespacedKeyDataType;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryAction;
@ -28,7 +26,6 @@ import org.bukkit.event.inventory.InventoryDragEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
@ -45,7 +42,7 @@ public abstract class UserInterface implements InventoryHolder {
this.rows = rows;
preload();
reload();
Bukkit.getScheduler().runTask(BlazingGames.get(), this::reload);
}
protected abstract void preload();
@ -153,17 +150,6 @@ public abstract class UserInterface implements InventoryHolder {
}
}
public static ItemStack element(Material material, NamespacedKey elementKey) {
ItemStack element = new ItemStack(material);
ItemMeta meta = element.getItemMeta();
meta.getPersistentDataContainer().set(guiKey, NamespacedKeyDataType.instance, elementKey);
meta.setHideTooltip(true);
element.setItemMeta(meta);
return element;
}
public final ItemStack getItem(int slot) {
ItemStack result = inventory.getItem(slot);
return result == null ? ItemStack.empty() : result;
@ -183,6 +169,16 @@ public abstract class UserInterface implements InventoryHolder {
slots.put(x+y*9, slot);
}
protected final void addSlot(int slotIndex, UserInterfaceSlot slot) {
if(slotIndex < 0) {
throw new IllegalStateException("Can't have a slot outside bounds!");
}
if(slotIndex >= rows * 9) {
throw new IllegalStateException("Can't have a slot outside bounds!");
}
slots.put(slotIndex, slot);
}
public void onDrag(InventoryDragEvent event) {
event.setCancelled(true);