This commit is contained in:
Kristian Knarvik 2024-04-05 16:29:12 +02:00
parent 0360ada849
commit aa39243232
15 changed files with 266 additions and 52 deletions

16
pom.xml
View File

@ -90,6 +90,10 @@
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>opencollab-snapshot</id>
<url>https://repo.opencollab.dev/main/</url>
</repository>
</repositories>
<dependencies>
@ -129,5 +133,17 @@
<version>1.7</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.geysermc.geyser</groupId>
<artifactId>api</artifactId>
<version>2.2.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.geysermc.floodgate</groupId>
<artifactId>api</artifactId>
<version>2.2.2-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -8,6 +8,8 @@ import net.knarcraft.minigames.arena.reward.RewardCondition;
import net.knarcraft.minigames.config.MiniGameMessage;
import net.knarcraft.minigames.gui.ArenaGUI;
import net.knarcraft.minigames.gui.DropperGUI;
import net.knarcraft.minigames.gui.DropperGUIBedrock;
import net.knarcraft.minigames.util.GeyserHelper;
import net.knarcraft.minigames.util.PlayerTeleporter;
import net.knarcraft.minigames.util.RewardHelper;
import org.bukkit.entity.Player;
@ -124,7 +126,11 @@ public class DropperArenaSession extends AbstractArenaSession {
@Override
public @NotNull ArenaGUI getGUI() {
return new DropperGUI(player);
if (GeyserHelper.isGeyserPlayer(this.player)) {
return new DropperGUIBedrock(this.player);
} else {
return new DropperGUI(this.player);
}
}
@Override
@ -137,7 +143,7 @@ public class DropperArenaSession extends AbstractArenaSession {
protected void removeSession() {
// Remove this session for game sessions to stop listeners from fiddling more with the player
boolean removedSession = MiniGames.getInstance().getDropperArenaPlayerRegistry().removePlayer(
player.getUniqueId(), true);
this.player.getUniqueId(), true);
if (!removedSession) {
MiniGames.log(Level.SEVERE, "Unable to remove dropper arena session for " + player.getName() + ". " +
"This will have unintended consequences.");

View File

@ -8,6 +8,8 @@ import net.knarcraft.minigames.arena.reward.RewardCondition;
import net.knarcraft.minigames.config.MiniGameMessage;
import net.knarcraft.minigames.gui.ArenaGUI;
import net.knarcraft.minigames.gui.ParkourGUI;
import net.knarcraft.minigames.gui.ParkourGUIBedrock;
import net.knarcraft.minigames.util.GeyserHelper;
import net.knarcraft.minigames.util.PlayerTeleporter;
import net.knarcraft.minigames.util.RewardHelper;
import org.bukkit.Location;
@ -120,7 +122,11 @@ public class ParkourArenaSession extends AbstractArenaSession {
@Override
public @NotNull ArenaGUI getGUI() {
return new ParkourGUI(player);
if (GeyserHelper.isGeyserPlayer(this.player)) {
return new ParkourGUIBedrock(this.player);
} else {
return new ParkourGUI(this.player);
}
}
@Override
@ -135,8 +141,8 @@ public class ParkourArenaSession extends AbstractArenaSession {
boolean removedSession = MiniGames.getInstance().getParkourArenaPlayerRegistry().removePlayer(
player.getUniqueId(), true);
if (!removedSession) {
MiniGames.log(Level.SEVERE, "Unable to remove parkour arena session for " + player.getName() + ". " +
"This will have unintended consequences.");
MiniGames.log(Level.SEVERE, "Unable to remove parkour arena session for " + this.player.getName() +
". This will have unintended consequences.");
}
}

View File

@ -10,6 +10,7 @@ import net.knarcraft.minigames.arena.dropper.DropperArenaSession;
import net.knarcraft.minigames.config.DropperConfiguration;
import net.knarcraft.minigames.config.MiniGameMessage;
import net.knarcraft.minigames.util.GUIHelper;
import net.knarcraft.minigames.util.GeyserHelper;
import net.knarcraft.minigames.util.PlayerTeleporter;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@ -35,6 +36,11 @@ public class JoinDropperArenaCommand implements CommandExecutor {
return false;
}
if (GeyserHelper.isGeyserPlayer(player)) {
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_GEYSER_DROPPER);
return true;
}
// Disallow joining if the player is already in a mini-game arena
if (MiniGames.getInstance().getSession(player.getUniqueId()) != null) {
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ALREADY_PLAYING);
@ -107,7 +113,7 @@ public class JoinDropperArenaCommand implements CommandExecutor {
// Update the player's state to follow the arena's rules
newSession.getEntryState().setArenaState();
player.getInventory().addItem(GUIHelper.getGUIOpenItem());
player.getInventory().addItem(GUIHelper.getGUIOpenItem(player));
stringFormatter.displaySuccessMessage(player, MiniGameMessage.SUCCESS_ARENA_JOINED);
}
}

View File

@ -105,7 +105,7 @@ public class JoinParkourArenaCommand implements CommandExecutor {
// Update the player's state to follow the arena's rules
newSession.getEntryState().setArenaState();
player.getInventory().addItem(GUIHelper.getGUIOpenItem());
player.getInventory().addItem(GUIHelper.getGUIOpenItem(player));
MiniGames.getInstance().getStringFormatter().displaySuccessMessage(player,
MiniGameMessage.SUCCESS_ARENA_JOINED);
}

View File

@ -165,6 +165,11 @@ public enum MiniGameMessage implements TranslatableMessage {
*/
ERROR_REWARD_CONDITION_INVALID,
/**
* The message displayed when a geyser player tries to join a dropper arena
*/
ERROR_GEYSER_DROPPER,
/* **************** *
* Success messages *
* **************** */

View File

@ -8,6 +8,7 @@ import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
import net.knarcraft.minigames.arena.ArenaSession;
import net.knarcraft.minigames.arena.PlayerVisibilityManager;
import net.knarcraft.minigames.arena.parkour.ParkourArenaSession;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material;
import org.bukkit.event.inventory.ClickType;
@ -46,6 +47,20 @@ public abstract class ArenaGUI extends AbstractGUI {
return restartItemFactory.build();
}
/**
* Gets an item describing a retry arena action
*
* @return <p>An arena restart item</p>
*/
protected ItemStack getRestartItemBedrock() {
GUIItemFactory restartItemFactory = new GUIItemFactory(Material.MAGENTA_GLAZED_TERRACOTTA);
List<String> loreLines = getLoreLines();
loreLines.add(ChatColor.GRAY + "Use this item to retry the arena");
restartItemFactory.setName(ChatColor.BLUE + "Retry arena");
restartItemFactory.setLore(loreLines);
return restartItemFactory.build();
}
/**
* Gets an item describing player visibility toggling
*
@ -77,6 +92,35 @@ public abstract class ArenaGUI extends AbstractGUI {
return togglePlayersItemFactory.build();
}
/**
* Gets an item describing player visibility toggling
*
* @return <p>A player toggle item</p>
*/
protected ItemStack getTogglePlayersItemEnabledBedrock() {
GUIItemFactory togglePlayersItemFactory = new GUIItemFactory(Material.SKELETON_SKULL);
List<String> loreLines = getLoreLines();
loreLines.add(ChatColor.GRAY + "Use this item to enable the visibility");
loreLines.add(ChatColor.GRAY + "of other players");
togglePlayersItemFactory.setName(ChatColor.BLUE + "Enable Players");
togglePlayersItemFactory.setLore(loreLines);
return togglePlayersItemFactory.build();
}
/**
* Gets an item describing a give up action
*
* @return <p>A give up item</p>
*/
protected ItemStack getGiveUpItem() {
GUIItemFactory giveUpItemFactory = new GUIItemFactory(Material.RESPAWN_ANCHOR);
List<String> loreLines = getLoreLines();
loreLines.add(ChatColor.GRAY + "Use this item to give up");
loreLines.add(ChatColor.GRAY + "and go to the last checkpoint");
giveUpItemFactory.setName(ChatColor.RED + "Give up");
giveUpItemFactory.setLore(loreLines);
return giveUpItemFactory.build();
}
/**
* Gets an item describing a leave arena action
@ -146,16 +190,31 @@ public abstract class ArenaGUI extends AbstractGUI {
* Gets the action to run when triggering the toggle players action
*
* @param playerRegistry <p>The registry containing relevant players</p>
* @param inventorySlot <p>The inventory slot to replace when toggling</p>
* @return <p>The action for triggering player visibility</p>
*/
public GUIAction getTogglePlayersAction(ArenaPlayerRegistry<?> playerRegistry) {
public GUIAction getTogglePlayersAction(ArenaPlayerRegistry<?> playerRegistry, int inventorySlot) {
return (player) -> {
PlayerVisibilityManager visibilityManager = MiniGames.getInstance().getPlayerVisibilityManager();
visibilityManager.toggleHidePlayers(playerRegistry, player);
if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) {
setItem(0, getTogglePlayersItemEnabled());
setItem(inventorySlot, getTogglePlayersItemEnabled());
} else {
setItem(0, getTogglePlayersItemDisabled());
setItem(inventorySlot, getTogglePlayersItemDisabled());
}
};
}
/**
* Gets the action to run when triggering the give up item
*
* @return <p>The give up action</p>
*/
public static GUIAction getGiveUpAction() {
return (player) -> {
ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId());
if (session instanceof ParkourArenaSession) {
session.triggerLoss();
}
};
}

View File

@ -23,7 +23,7 @@ public class DropperGUI extends ArenaGUI {
setItem(2, getLeaveItem());
setItem(4, getRestartItem());
setAnyClickAction(0, getTogglePlayersAction(MiniGames.getInstance().getDropperArenaPlayerRegistry()));
setAnyClickAction(0, getTogglePlayersAction(MiniGames.getInstance().getDropperArenaPlayerRegistry(), 0));
setAnyClickAction(2, getLeaveAction());
setAnyClickAction(4, getRestartAction());
}

View File

@ -0,0 +1,31 @@
package net.knarcraft.minigames.gui;
import net.knarcraft.minigames.MiniGames;
import org.bukkit.entity.Player;
/**
* A GUI used in the dropper arena, altered for Bedrock players
*/
public class DropperGUIBedrock extends ArenaGUI {
/**
* Instantiates a new dropper gui
*
* @param player <p>The player the GUI is created for</p>
*/
public DropperGUIBedrock(Player player) {
super(27, "Dropper");
if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) {
setItem(9, getTogglePlayersItemEnabledBedrock());
} else {
setItem(9, getTogglePlayersItemDisabled());
}
setItem(11, getLeaveItem());
setItem(13, getRestartItemBedrock());
setAnyClickAction(9, getTogglePlayersAction(MiniGames.getInstance().getDropperArenaPlayerRegistry(), 9));
setAnyClickAction(11, getLeaveAction());
setAnyClickAction(13, getRestartAction());
}
}

View File

@ -21,7 +21,7 @@ public class MiniGamesGUI extends ArenaGUI {
setItem(0, getTogglePlayersItemDisabled());
}
setAnyClickAction(0, getTogglePlayersAction(null));
setAnyClickAction(0, getTogglePlayersAction(null, 0));
}
}

View File

@ -1,16 +1,7 @@
package net.knarcraft.minigames.gui;
import net.knarcraft.knargui.GUIAction;
import net.knarcraft.knargui.item.GUIItemFactory;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.ArenaSession;
import net.knarcraft.minigames.arena.parkour.ParkourArenaSession;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.List;
/**
* A GUI used in the parkour arena
@ -33,39 +24,10 @@ public class ParkourGUI extends ArenaGUI {
setItem(4, getLeaveItem());
setItem(6, getRestartItem());
setAnyClickAction(0, getTogglePlayersAction(MiniGames.getInstance().getParkourArenaPlayerRegistry()));
setAnyClickAction(0, getTogglePlayersAction(MiniGames.getInstance().getParkourArenaPlayerRegistry(), 0));
setAnyClickAction(2, getGiveUpAction());
setAnyClickAction(4, getLeaveAction());
setAnyClickAction(6, getRestartAction());
}
/**
* Gets an item describing a give up action
*
* @return <p>A give up item</p>
*/
private ItemStack getGiveUpItem() {
GUIItemFactory giveUpItemFactory = new GUIItemFactory(Material.RESPAWN_ANCHOR);
List<String> loreLines = getLoreLines();
loreLines.add(ChatColor.GRAY + "Use this item to give up");
loreLines.add(ChatColor.GRAY + "and go to the last checkpoint");
giveUpItemFactory.setName(ChatColor.RED + "Give up");
giveUpItemFactory.setLore(loreLines);
return giveUpItemFactory.build();
}
/**
* Gets the action to run when triggering the give up item
*
* @return <p>The give up action</p>
*/
public static GUIAction getGiveUpAction() {
return (player) -> {
ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId());
if (session instanceof ParkourArenaSession) {
session.triggerLoss();
}
};
}
}

View File

@ -0,0 +1,33 @@
package net.knarcraft.minigames.gui;
import net.knarcraft.minigames.MiniGames;
import org.bukkit.entity.Player;
/**
* A GUI used in the parkour arena, altered for Bedrock players
*/
public class ParkourGUIBedrock extends ArenaGUI {
/**
* Instantiates a new parkour gui
*
* @param player <p>The player the GUI is created for</p>
*/
public ParkourGUIBedrock(Player player) {
super(27, "Parkour");
if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) {
setItem(9, getTogglePlayersItemEnabledBedrock());
} else {
setItem(9, getTogglePlayersItemDisabled());
}
setItem(11, getGiveUpItem());
setItem(13, getLeaveItem());
setItem(15, getRestartItemBedrock());
setAnyClickAction(9, getTogglePlayersAction(MiniGames.getInstance().getParkourArenaPlayerRegistry(), 9));
setAnyClickAction(11, getGiveUpAction());
setAnyClickAction(13, getLeaveAction());
setAnyClickAction(15, getRestartAction());
}
}

View File

@ -1,16 +1,19 @@
package net.knarcraft.minigames.util;
import net.knarcraft.knargui.item.GUIItemFactory;
import net.knarcraft.knargui.item.PlayerHeadGUIItemFactory;
import net.knarcraft.minigames.MiniGames;
import net.knarcraft.minigames.arena.ArenaSession;
import net.knarcraft.minigames.gui.MiniGamesGUI;
import net.knarcraft.minigames.property.PersistentDataKey;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
/**
* A helper class for the in-arena GUI
@ -21,12 +24,26 @@ public final class GUIHelper {
}
/**
* Gets the GUI open item to give to the specified player
*
* @param player <p>The player to give a GUI opening item</p>
* @return <p>The item to give</p>
*/
public static ItemStack getGUIOpenItem(@NotNull Player player) {
if (GeyserHelper.isGeyserPlayer(player)) {
return getGUIOpenItemBedrock();
} else {
return getGUIOpenItemJava();
}
}
/**
* Gets the item used for opening the mini-games menu
*
* @return <p>The item used for opening the GUI</p>
*/
public static ItemStack getGUIOpenItem() {
public static ItemStack getGUIOpenItemJava() {
PlayerHeadGUIItemFactory factory = new PlayerHeadGUIItemFactory();
factory.useSkin("3fdab40434ed5d01f58c45ca0c9fada4662e1772ff43e2974979440a5cfe15c9");
factory.setName(ChatColor.AQUA + "§ MiniGames Menu §");
@ -41,6 +58,25 @@ public final class GUIHelper {
return item;
}
/**
* Gets the item used for opening the mini-games menu
*
* @return <p>The item used for opening the GUI</p>
*/
public static ItemStack getGUIOpenItemBedrock() {
GUIItemFactory factory = new GUIItemFactory(Material.BEACON);
factory.setName(ChatColor.AQUA + "MiniGames Menu");
ItemStack item = factory.build();
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.getPersistentDataContainer().set(new NamespacedKey(MiniGames.getInstance(),
PersistentDataKey.MENU_ITEM.getKeyName()),
PersistentDataType.INTEGER, PersistentDataKey.MENU_ITEM.getDataValue());
}
item.setItemMeta(meta);
return item;
}
/**
* Opens the correct GUI for the given player
*

View File

@ -0,0 +1,53 @@
package net.knarcraft.minigames.util;
import org.bukkit.entity.Player;
import org.geysermc.floodgate.api.FloodgateApi;
import org.geysermc.geyser.api.GeyserApi;
import org.jetbrains.annotations.NotNull;
/**
* A helper class for dealing with geyser/floodgate players
*/
public final class GeyserHelper {
private static boolean hasGeyser = true;
private static boolean hasFloodgate = true;
private GeyserHelper() {
}
/**
* Checks whether the given player is connected through Geyser
*
* @param player <p>The player to check</p>
* @return <p>True if the player is connected through Geyser</p>
*/
public static boolean isGeyserPlayer(@NotNull Player player) {
// Prevent unnecessary checking for non-geyser and floodgate servers
if (!hasGeyser && !hasFloodgate) {
return false;
}
// Use Geyser API to get connection status
if (hasGeyser) {
try {
return GeyserApi.api().connectionByUuid(player.getUniqueId()) != null;
} catch (NoClassDefFoundError error1) {
hasGeyser = false;
}
}
// Use Floodgate API to get connection status
if (hasFloodgate) {
try {
return FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId());
} catch (NoClassDefFoundError error2) {
hasFloodgate = false;
}
}
return false;
}
}

View File

@ -29,6 +29,7 @@ en:
ERROR_INVALID_COMMAND_STRING: "You specified an invalid command. Make sure you don't add a slash in front of the command definition."
ERROR_REWARD_TYPE_INVALID: "You have specified an invalid reward type"
ERROR_REWARD_CONDITION_INVALID: "You have specified an invalid reward condition"
ERROR_GEYSER_DROPPER: "Because of version differences, droppers don't work properly using the Bedrock client. Please use Minecraft Java Edition instead."
SUCCESS_ARENA_GROUP_UPDATED: "The arena's group has been updated"
SUCCESS_PLUGIN_RELOADED: "Plugin reloaded!"
SUCCESS_ARENA_CREATED: "The arena was successfully created!"