feat: split prompt from AnvilGUI dependency

This commit is contained in:
ineanto 2025-03-26 19:29:12 +01:00
parent 11730d5234
commit 1a81c7c657
Signed by: ineanto
GPG key ID: E511F9CAA2F9CE84
13 changed files with 280 additions and 175 deletions

View file

@ -37,6 +37,7 @@ dependencies {
compileOnly("net.kyori:adventure-api:4.17.0")
compileOnly("xyz.xenondevs.invui:invui-core:$invuiVersion")
implementation("de.rapha149.signgui:signgui:2.5.0")
implementation("com.github.jsixface:yamlconfig:1.2")
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.1")
implementation("com.fasterxml.jackson.core:jackson-core:2.18.1")

View file

@ -1,148 +0,0 @@
package xyz.ineanto.nicko.anvil;
import net.kyori.adventure.text.Component;
import net.wesjd.anvilgui.AnvilGUI;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import xyz.ineanto.nicko.Nicko;
import xyz.ineanto.nicko.appearance.ActionResult;
import xyz.ineanto.nicko.appearance.AppearanceManager;
import xyz.ineanto.nicko.event.custom.PlayerDisguiseEvent;
import xyz.ineanto.nicko.language.LanguageKey;
import xyz.ineanto.nicko.language.PlayerLanguage;
import xyz.ineanto.nicko.mojang.MojangUtils;
import xyz.ineanto.nicko.profile.NickoProfile;
import xyz.ineanto.nicko.storage.PlayerDataStore;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
public class AnvilManager {
private final Player player;
private final AppearanceManager appearanceManager;
private final PlayerDataStore dataStore = Nicko.getInstance().getDataStore();
private final NickoProfile profile;
private final PlayerLanguage playerLanguage;
public AnvilManager(Player player) {
this.player = player;
this.playerLanguage = new PlayerLanguage(player);
final Optional<NickoProfile> optionalProfile = dataStore.getData(player.getUniqueId());
this.profile = optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone());
this.appearanceManager = new AppearanceManager(player);
}
public void openNameThenSkinAnvil() {
getNameThenSkinAnvil().open(player);
}
public void openSkinAnvil() {
getSkinAnvil().open(player);
}
public void openNameAnvil() {
getNameAnvil().open(player);
}
private AnvilGUI.Builder getNameThenSkinAnvil() {
return new AnvilGUI.Builder()
.plugin(Nicko.getInstance())
.itemLeft(getLeftItem(false))
.interactableSlots(AnvilGUI.Slot.OUTPUT)
.onClick((slot, snapshot) -> {
if (slot == AnvilGUI.Slot.OUTPUT) {
if (MojangUtils.isUsernameInvalid(snapshot.getText())) {
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
} else {
profile.setName(snapshot.getText());
openSkinAnvil();
return Collections.singletonList(AnvilGUI.ResponseAction.close());
}
}
return Collections.emptyList();
})
.text("New name...");
}
private AnvilGUI.Builder getNameAnvil() {
return new AnvilGUI.Builder()
.plugin(Nicko.getInstance())
.itemLeft(getLeftItem(false))
.interactableSlots(AnvilGUI.Slot.OUTPUT)
.onClick((slot, snapshot) -> {
if (slot == AnvilGUI.Slot.OUTPUT) {
if (MojangUtils.isUsernameInvalid(snapshot.getText())) {
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
} else {
profile.setName(snapshot.getText());
dataStore.updateCache(player.getUniqueId(), profile);
return sendResultAndClose(false);
}
}
return Collections.emptyList();
})
.text("New name...");
}
private AnvilGUI.Builder getSkinAnvil() {
return new AnvilGUI.Builder()
.plugin(Nicko.getInstance())
.itemLeft(getLeftItem(true))
.interactableSlots(AnvilGUI.Slot.OUTPUT)
.onClick((slot, snapshot) -> {
if (slot == AnvilGUI.Slot.OUTPUT) {
if (MojangUtils.isUsernameInvalid(snapshot.getText())) {
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
} else {
profile.setSkin(snapshot.getText());
dataStore.updateCache(player.getUniqueId(), profile);
return sendResultAndClose(true);
}
}
return Collections.emptyList();
})
.text("New skin...");
}
private List<AnvilGUI.ResponseAction> sendResultAndClose(boolean skinChange) {
final PlayerDisguiseEvent event = new PlayerDisguiseEvent(player, profile.getSkin(), player.getName());
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) { return Collections.singletonList(AnvilGUI.ResponseAction.close()); }
final ActionResult actionResult = appearanceManager.update(skinChange, false);
if (!actionResult.isError()) {
player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Set.OK));
player.playSound(player.getLocation(), Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f);
} else {
player.sendMessage(
playerLanguage.translateWithOops(
LanguageKey.Event.Appearance.Set.ERROR,
playerLanguage.translate(actionResult.getErrorKey(), false)
));
player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1f, 1f);
}
return Collections.singletonList(AnvilGUI.ResponseAction.close());
}
private ItemStack getLeftItem(boolean skin) {
final ItemStack item = new ItemStack(Material.PAPER);
final ItemMeta meta = item.getItemMeta();
if (meta != null) {
if (skin) {
meta.displayName(Component.text(playerLanguage.translate(LanguageKey.GUI.NEW_SKIN, false)));
} else {
meta.displayName(Component.text(playerLanguage.translate(LanguageKey.GUI.NEW_NAME, false)));
}
}
item.setItemMeta(meta);
return item;
}
}

View file

@ -1,8 +1,11 @@
package xyz.ineanto.nicko.appearance;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import xyz.ineanto.nicko.Nicko;
import xyz.ineanto.nicko.event.custom.PlayerDisguiseEvent;
import xyz.ineanto.nicko.event.custom.PlayerResetDisguiseEvent;
import xyz.ineanto.nicko.packet.InternalPacketSender;
import xyz.ineanto.nicko.packet.PacketSender;
import xyz.ineanto.nicko.profile.NickoProfile;
@ -24,25 +27,24 @@ public class AppearanceManager {
this.packetSender = new InternalPacketSender(player, getNickoProfile());
}
public ActionResult reset(boolean apply) {
public ActionResult reset() {
final NickoProfile profile = getNickoProfile();
final String defaultName = nameStore.getStoredName(player);
// Call the event.
final PlayerResetDisguiseEvent event = new PlayerResetDisguiseEvent(player);
Bukkit.getPluginManager().callEvent(event);
profile.setName(defaultName);
profile.setSkin(defaultName);
final ActionResult result = update(true, true);
profile.setName(null);
profile.setSkin(null);
dataStore.getCache().cache(player.getUniqueId(), profile);
if (apply) {
final ActionResult result = update(true, true);
profile.setName(null);
profile.setSkin(null);
dataStore.getCache().cache(player.getUniqueId(), profile);
return result;
}
return ActionResult.ok();
return result;
}
public ActionResult update(boolean skinChange, boolean reset) {
@ -52,9 +54,13 @@ public class AppearanceManager {
final ActionResult result = packetSender.sendGameProfileUpdate(displayName, skinChange, reset);
if (result.isError()) {
return reset(false);
return reset();
}
// Call the event.
final PlayerDisguiseEvent event = new PlayerDisguiseEvent(player, profile.getSkin(), profile.getName());
Bukkit.getPluginManager().callEvent(event);
packetSender.sendEntityMetadataUpdate();
packetSender.sendTabListUpdate(displayName);
respawnPlayer();

View file

@ -0,0 +1,36 @@
package xyz.ineanto.nicko.event.custom;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
public class PlayerResetDisguiseEvent extends Event implements Cancellable {
private static final HandlerList HANDLERS_LIST = new HandlerList();
private boolean isCancelled;
private final Player player;
public PlayerResetDisguiseEvent(Player player) {
this.player = player;
}
@Override
public boolean isCancelled() {
return isCancelled;
}
@Override
public void setCancelled(boolean isCancelled) {
this.isCancelled = isCancelled;
}
@Override
public @NotNull HandlerList getHandlers() {
return HANDLERS_LIST;
}
public Player getPlayer() {
return player;
}
}

View file

@ -78,7 +78,7 @@ public class PlayerInformationItem extends AsyncItem {
@Override
public void onConfirm() {
final AppearanceManager appearanceManager = new AppearanceManager(target);
appearanceManager.reset(true);
appearanceManager.reset();
player.playSound(player.getLocation(), Sound.ENTITY_VILLAGER_TRADE, 1, 1f);
player.sendMessage(playerLanguage.translate(LanguageKey.Event.Admin.Check.REMOVE_SKIN, true, target.getName()));
}

View file

@ -3,9 +3,9 @@ package xyz.ineanto.nicko.gui.items.appearance;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import xyz.ineanto.nicko.anvil.AnvilManager;
import xyz.ineanto.nicko.language.PlayerLanguage;
import xyz.ineanto.nicko.gui.prompt.PromptManager;
import xyz.ineanto.nicko.language.LanguageKey;
import xyz.ineanto.nicko.language.PlayerLanguage;
import xyz.xenondevs.invui.item.builder.ItemBuilder;
import xyz.xenondevs.invui.item.impl.SuppliedItem;
@ -24,8 +24,8 @@ public class ChangeBothItem {
final ClickType clickType = click.getClickType();
if (clickType.isLeftClick() || clickType.isRightClick()) {
click.getEvent().getView().close();
final AnvilManager manager = new AnvilManager(click.getPlayer());
manager.openNameThenSkinAnvil();
final PromptManager manager = new PromptManager(click.getPlayer());
manager.displayNameThenSkinPrompt();
}
return true;
});

View file

@ -3,16 +3,21 @@ package xyz.ineanto.nicko.gui.items.appearance;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import xyz.ineanto.nicko.anvil.AnvilManager;
import xyz.ineanto.nicko.language.PlayerLanguage;
import xyz.ineanto.nicko.appearance.AppearanceManager;
import xyz.ineanto.nicko.gui.prompt.PromptManager;
import xyz.ineanto.nicko.language.LanguageKey;
import xyz.ineanto.nicko.language.PlayerLanguage;
import xyz.xenondevs.invui.item.builder.ItemBuilder;
import xyz.xenondevs.invui.item.impl.SuppliedItem;
public class ChangeNameItem {
private final AppearanceManager appearanceManager;
private final Player player;
private final PlayerLanguage playerLanguage;
public ChangeNameItem(Player player) {
this.appearanceManager = new AppearanceManager(player);
this.player = player;
this.playerLanguage = new PlayerLanguage(player);
}
@ -24,8 +29,8 @@ public class ChangeNameItem {
final ClickType clickType = click.getClickType();
if (clickType.isLeftClick() || clickType.isRightClick()) {
click.getEvent().getView().close();
final AnvilManager manager = new AnvilManager(click.getPlayer());
manager.openNameAnvil();
final PromptManager manager = new PromptManager(click.getPlayer());
manager.displayNamePromptThenUpdate();
}
return true;
});

View file

@ -4,7 +4,8 @@ import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import xyz.ineanto.nicko.Nicko;
import xyz.ineanto.nicko.anvil.AnvilManager;
import xyz.ineanto.nicko.appearance.AppearanceManager;
import xyz.ineanto.nicko.gui.prompt.PromptManager;
import xyz.ineanto.nicko.language.LanguageKey;
import xyz.ineanto.nicko.language.PlayerLanguage;
import xyz.ineanto.nicko.storage.name.PlayerNameStore;
@ -17,11 +18,13 @@ import xyz.xenondevs.invui.util.MojangApiUtils;
import java.io.IOException;
public class ChangeSkinItem {
private final AppearanceManager appearanceManager;
private final PlayerLanguage playerLanguage;
private final PlayerNameStore playerNameStore;
private final Player player;
public ChangeSkinItem(Player player) {
this.appearanceManager = new AppearanceManager(player);
this.playerLanguage = new PlayerLanguage(player);
this.playerNameStore = Nicko.getInstance().getNameStore();
this.player = player;
@ -42,8 +45,8 @@ public class ChangeSkinItem {
final ClickType clickType = click.getClickType();
if (clickType.isLeftClick() || clickType.isRightClick()) {
click.getEvent().getView().close();
final AnvilManager manager = new AnvilManager(click.getPlayer());
manager.openSkinAnvil();
final PromptManager manager = new PromptManager(click.getPlayer());
manager.displaySkinPromptThenUpdate();
}
return true;
});

View file

@ -49,7 +49,7 @@ public class RandomSkinItem {
playerLanguage.translate(result.getErrorKey(), false)
)
);
appearanceManager.reset(false);
appearanceManager.reset();
}
});
return true;

View file

@ -36,7 +36,7 @@ public class ResetItem {
}
final AppearanceManager appearanceManager = new AppearanceManager(player);
if (!appearanceManager.reset(true).isError()) {
if (!appearanceManager.reset().isError()) {
player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Remove.OK));
} else {
player.sendMessage(playerLanguage.translateWithOops(LanguageKey.Event.Appearance.Remove.ERROR));

View file

@ -0,0 +1,112 @@
package xyz.ineanto.nicko.gui.prompt;
import net.kyori.adventure.text.Component;
import net.wesjd.anvilgui.AnvilGUI;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import xyz.ineanto.nicko.Nicko;
import xyz.ineanto.nicko.language.LanguageKey;
import xyz.ineanto.nicko.language.PlayerLanguage;
import xyz.ineanto.nicko.mojang.MojangUtils;
import java.util.Collections;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
public class AnvilPrompt implements Prompt {
private final Player player;
private final PlayerLanguage playerLanguage;
private final AtomicReference<Optional<String>> name = new AtomicReference<>();
private final AtomicReference<Optional<String>> skin = new AtomicReference<>();
public AnvilPrompt(Player player, PlayerLanguage playerLanguage) {
this.player = player;
this.playerLanguage = playerLanguage;
}
@Override
public Optional<String[]> displayNameThenSkinPrompt() {
new AnvilGUI.Builder()
.plugin(Nicko.getInstance())
.itemLeft(getLeftItem(false))
.interactableSlots(AnvilGUI.Slot.OUTPUT)
.onClick((slot, snapshot) -> {
if (slot == AnvilGUI.Slot.OUTPUT) {
if (MojangUtils.isUsernameInvalid(snapshot.getText())) {
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
} else {
// Praying that it works. This is untested code!
name.set(Optional.of(snapshot.getText()));
final Optional<String> skinFromAnvil = displaySkinPrompt();
skin.set(skinFromAnvil);
}
}
return Collections.emptyList();
})
.text("New name...").open(player);
if (name.get().isEmpty() || skin.get().isEmpty()) {
return Optional.empty();
}
return Optional.of(new String[]{name.get().orElse(player.getName()), skin.get().orElse(player.getName())});
}
@Override
public Optional<String> displaySkinPrompt() {
new AnvilGUI.Builder()
.plugin(Nicko.getInstance())
.itemLeft(getLeftItem(true))
.interactableSlots(AnvilGUI.Slot.OUTPUT)
.onClick((slot, snapshot) -> {
if (slot == AnvilGUI.Slot.OUTPUT) {
if (MojangUtils.isUsernameInvalid(snapshot.getText())) {
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
} else {
skin.set(Optional.of(snapshot.getText()));
return Collections.singletonList(AnvilGUI.ResponseAction.close());
}
}
return Collections.emptyList();
})
.text("New skin...").open(player);
return skin.get();
}
@Override
public Optional<String> displayNamePrompt() {
new AnvilGUI.Builder()
.plugin(Nicko.getInstance())
.itemLeft(getLeftItem(false))
.interactableSlots(AnvilGUI.Slot.OUTPUT)
.onClick((slot, snapshot) -> {
if (slot == AnvilGUI.Slot.OUTPUT) {
if (MojangUtils.isUsernameInvalid(snapshot.getText())) {
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
} else {
name.set(Optional.of(snapshot.getText()));
return Collections.singletonList(AnvilGUI.ResponseAction.close());
}
}
return Collections.emptyList();
})
.text("New name...").open(player);
return name.get();
}
private ItemStack getLeftItem(boolean skin) {
final ItemStack item = new ItemStack(Material.PAPER);
final ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.displayName(Component.text(playerLanguage.translate(skin ? LanguageKey.GUI.NEW_SKIN : LanguageKey.GUI.NEW_NAME, false)));
}
item.setItemMeta(meta);
return item;
}
}

View file

@ -0,0 +1,11 @@
package xyz.ineanto.nicko.gui.prompt;
import java.util.Optional;
public interface Prompt {
Optional<String[]> displayNameThenSkinPrompt();
Optional<String> displaySkinPrompt();
Optional<String> displayNamePrompt();
}

View file

@ -0,0 +1,79 @@
package xyz.ineanto.nicko.gui.prompt;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import xyz.ineanto.nicko.Nicko;
import xyz.ineanto.nicko.appearance.ActionResult;
import xyz.ineanto.nicko.appearance.AppearanceManager;
import xyz.ineanto.nicko.language.LanguageKey;
import xyz.ineanto.nicko.language.PlayerLanguage;
import xyz.ineanto.nicko.profile.NickoProfile;
import xyz.ineanto.nicko.storage.PlayerDataStore;
import java.util.Optional;
public class PromptManager {
private final AppearanceManager appearanceManager;
private final NickoProfile profile;
private final Player player;
private final Prompt prompt;
private final PlayerDataStore dataStore = Nicko.getInstance().getDataStore();
private final PlayerLanguage playerLanguage;
public PromptManager(Player player) {
this.player = player;
this.playerLanguage = new PlayerLanguage(player);
final Optional<NickoProfile> optionalProfile = dataStore.getData(player.getUniqueId());
this.profile = optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone());
this.appearanceManager = new AppearanceManager(player);
this.prompt = new AnvilPrompt(player, playerLanguage);
}
public void displayNameThenSkinPrompt() {
final Optional<String[]> optionalValues = prompt.displayNameThenSkinPrompt();
if (optionalValues.isPresent()) {
final String[] values = optionalValues.get();
profile.setName(values[0]);
profile.setSkin(values[1]);
dataStore.updateCache(player.getUniqueId(), profile);
update(true);
}
}
public void displaySkinPromptThenUpdate() {
final Optional<String> name = prompt.displaySkinPrompt();
if (name.isPresent()) {
profile.setName(name.get());
dataStore.updateCache(player.getUniqueId(), profile);
update(false);
}
}
public void displayNamePromptThenUpdate() {
final Optional<String> name = prompt.displayNamePrompt();
if (name.isPresent()) {
profile.setName(name.get());
dataStore.updateCache(player.getUniqueId(), profile);
update(false);
}
}
private void update(boolean skinChange) {
final ActionResult actionResult = appearanceManager.update(skinChange, false);
if (!actionResult.isError()) {
player.sendMessage(playerLanguage.translateWithWhoosh(LanguageKey.Event.Appearance.Set.OK));
player.playSound(player.getLocation(), Sound.BLOCK_WOODEN_BUTTON_CLICK_ON, 1, 1f);
} else {
player.sendMessage(
playerLanguage.translateWithOops(
LanguageKey.Event.Appearance.Set.ERROR,
playerLanguage.translate(actionResult.getErrorKey(), false)
));
player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_PLACE, 1f, 1f);
}
}
}