feat(i18n): admin gui

This commit is contained in:
ineanto 2023-09-15 22:15:00 +02:00
parent f436c7db3a
commit 8838961f37
12 changed files with 131 additions and 54 deletions

View file

@ -22,16 +22,17 @@ public class AdminGUI {
final HomeGUI parent = new HomeGUI(player); final HomeGUI parent = new HomeGUI(player);
final GoBackItem backItem = new GoBackItem(player); final GoBackItem backItem = new GoBackItem(player);
final UnavailableItem unavailableItem = new UnavailableItem(player); final UnavailableItem unavailableItem = new UnavailableItem(player);
final ManagePlayerItem managePlayerItem = new ManagePlayerItem(i18n, player);
this.gui = Gui.normal() this.gui = Gui.normal()
.setStructure( .setStructure(
"# # # # # # # # #", "# # # # # # # # #",
"# # # S C U # # #", "# # # S C X # # #",
"B # # # # # # # #" "B # # # # # # # #"
) )
.addIngredient('S', new ManageCacheItem()) .addIngredient('S', new ManageCacheItem(i18n))
.addIngredient('C', managePlayerItem.get())
.addIngredient('U', unavailableItem.get()) .addIngredient('U', unavailableItem.get())
.addIngredient('C', new ManagePlayerItem())
.addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle())) .addIngredient('B', backItem.get(parent.getGUI(), parent.getTitle()))
.build(); .build();
this.player = player; this.player = player;

View file

@ -1,24 +1,25 @@
package xyz.atnrch.nicko.gui.items.admin; package xyz.atnrch.nicko.gui.items.admin;
import xyz.xenondevs.invui.item.builder.ItemBuilder;
import xyz.xenondevs.invui.item.builder.SkullBuilder;
import xyz.xenondevs.invui.item.impl.AsyncItem;
import xyz.atnrch.nicko.gui.CacheManagementGUI;
import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType; import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.atnrch.nicko.gui.CacheManagementGUI;
import xyz.atnrch.nicko.gui.items.common.LoadingItem;
import xyz.atnrch.nicko.i18n.I18N;
import xyz.atnrch.nicko.i18n.I18NDict;
import xyz.atnrch.nicko.i18n.ItemTranslation;
import xyz.xenondevs.invui.item.builder.SkullBuilder;
import xyz.xenondevs.invui.item.impl.AsyncItem;
public class ManageCacheItem extends AsyncItem { public class ManageCacheItem extends AsyncItem {
public ManageCacheItem() { public ManageCacheItem(I18N i18n) {
super(new ItemBuilder(Material.PAINTING) super(new LoadingItem(i18n).get(),
.setDisplayName("Manage §6skin §fcache...")
.addLoreLines("§7Access the skin cache management panel."),
() -> { () -> {
final SkullBuilder builder = new SkullBuilder("Notch"); final SkullBuilder builder = new SkullBuilder("Notch");
builder.setDisplayName("Manage §6skin §fcache..."); final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.MANAGE_CACHE);
builder.addLoreLines("§7Access the skin cache management panel."); builder.setDisplayName(translation.getName());
translation.getLore().forEach(builder::addLoreLines);
return builder; return builder;
}); });
} }

View file

@ -2,30 +2,32 @@ package xyz.atnrch.nicko.gui.items.admin;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull;
import xyz.atnrch.nicko.gui.PlayerCheckGUI; import xyz.atnrch.nicko.gui.PlayerCheckGUI;
import xyz.atnrch.nicko.i18n.I18N;
import xyz.atnrch.nicko.i18n.I18NDict;
import xyz.atnrch.nicko.i18n.ItemTranslation;
import xyz.xenondevs.invui.item.builder.ItemBuilder; import xyz.xenondevs.invui.item.builder.ItemBuilder;
import xyz.xenondevs.invui.item.impl.SuppliedItem; import xyz.xenondevs.invui.item.impl.SuppliedItem;
public class ManagePlayerItem extends SuppliedItem { public class ManagePlayerItem {
public ManagePlayerItem() { private final Player player;
super(() -> { private final I18N i18n;
final ItemBuilder builder = new ItemBuilder(Material.WRITABLE_BOOK);
builder.setDisplayName("Check a player..."); public ManagePlayerItem(I18N i18n, Player player) {
builder.addLoreLines("§7See players' disguise information."); this.i18n = i18n;
return builder; this.player = player;
},
click -> true);
} }
@Override public SuppliedItem get() {
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent return new SuppliedItem(() -> {
event) { final ItemBuilder builder = new ItemBuilder(Material.WRITABLE_BOOK);
if (clickType.isLeftClick() || clickType.isRightClick()) { final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.MANAGE_PLAYER);
event.getView().close(); builder.setDisplayName(translation.getName());
translation.getLore().forEach(builder::addLoreLines);
return builder;
}, click -> {
new PlayerCheckGUI(player).open(); new PlayerCheckGUI(player).open();
} return true;
});
} }
} }

View file

@ -31,7 +31,6 @@ public class CacheStatisticsItem {
stats.requestCount(), stats.requestCount(),
Math.round(cache.size()) Math.round(cache.size())
); );
translation.getLore().forEach(System.out::println);
// TODO (Ineanto, 9/11/23): This doesn't work. // TODO (Ineanto, 9/11/23): This doesn't work.
builder.setDisplayName(translation.getName()); builder.setDisplayName(translation.getName());
translation.getLore().forEach(builder::addLoreLines); translation.getLore().forEach(builder::addLoreLines);

View file

@ -0,0 +1,27 @@
package xyz.atnrch.nicko.gui.items.common;
import org.bukkit.Material;
import xyz.atnrch.nicko.i18n.I18N;
import xyz.atnrch.nicko.i18n.I18NDict;
import xyz.atnrch.nicko.i18n.ItemTranslation;
import xyz.xenondevs.invui.item.ItemProvider;
import xyz.xenondevs.invui.item.builder.ItemBuilder;
import xyz.xenondevs.invui.item.impl.SuppliedItem;
public class LoadingItem {
private final I18N i18n;
public LoadingItem(I18N i18n) {
this.i18n = i18n;
}
public ItemProvider get() {
return new SuppliedItem(() -> {
final ItemBuilder builder = new ItemBuilder(Material.PAINTING);
final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.LOADING);
builder.setDisplayName(translation.getName());
translation.getLore().forEach(builder::addLoreLines);
return builder;
}, (click -> true)).getItemProvider();
}
}

View file

@ -12,7 +12,6 @@ import xyz.xenondevs.invui.item.builder.ItemBuilder;
import xyz.xenondevs.invui.item.impl.SuppliedItem; import xyz.xenondevs.invui.item.impl.SuppliedItem;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
public class ResetItem { public class ResetItem {
private final I18N i18n; private final I18N i18n;
@ -33,25 +32,23 @@ public class ResetItem {
final ClickType clickType = event.getClickType(); final ClickType clickType = event.getClickType();
if (clickType.isLeftClick() || clickType.isRightClick()) { if (clickType.isLeftClick() || clickType.isRightClick()) {
final Optional<NickoProfile> optionalProfile = NickoProfile.get(player); final Optional<NickoProfile> optionalProfile = NickoProfile.get(player);
final AtomicBoolean result = new AtomicBoolean(false);
optionalProfile.ifPresent(profile -> { optionalProfile.ifPresent(profile -> {
if (!profile.hasData()) { if (!profile.hasData()) {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING)); player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING));
event.getEvent().getView().close(); event.getEvent().getView().close();
result.set(true);
return; return;
} }
final AppearanceManager appearanceManager = new AppearanceManager(player); final AppearanceManager appearanceManager = new AppearanceManager(player);
if (!appearanceManager.reset().isError()) { if (!appearanceManager.reset().isError()) {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK)); player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK));
result.set(false);
} else { } else {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.ERROR)); player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.ERROR));
result.set(true); profile.setSkin(null);
profile.setName(null);
} }
}); });
return result.get(); return true;
} }
return false; return false;
}); });

View file

@ -18,7 +18,7 @@ public class I18N {
private final MessageFormat formatter = new MessageFormat(""); private final MessageFormat formatter = new MessageFormat("");
private final Logger logger = Logger.getLogger("I18N"); private final Logger logger = Logger.getLogger("I18N");
private final NickoBukkit instance = NickoBukkit.getInstance(); private final NickoBukkit instance = NickoBukkit.getInstance();
private final Pattern replacementPattern = Pattern.compile("\\{\\d+}"); private final Pattern replacementPattern = Pattern.compile("\\{\\d+}$", Pattern.DOTALL);
private final YamlConfig yamlConfig; private final YamlConfig yamlConfig;
private final Player player; private final Player player;
private final Locale playerLocale; private final Locale playerLocale;
@ -67,14 +67,13 @@ public class I18N {
// If the line doesn't contain {i}, skip it // If the line doesn't contain {i}, skip it
final Matcher matcher = replacementPattern.matcher(currentLine); final Matcher matcher = replacementPattern.matcher(currentLine);
if (!matcher.matches()) { if (!matcher.find()) {
lineIndex++; lineIndex++;
continue; continue;
} }
// If it does, replace the content with the args at position replacementIndex // If it does, replace the content with the args at position replacementIndex
if (replacementIndex < args.length && args[replacementIndex] != null) { if (replacementIndex < args.length && args[replacementIndex] != null) {
System.out.println("replacing...");
// Replace with the corresponding varargs index // Replace with the corresponding varargs index
toTranslate.set(lineIndex, currentLine.replace("{" + replacementIndex + "}", args[replacementIndex].toString())); toTranslate.set(lineIndex, currentLine.replace("{" + replacementIndex + "}", args[replacementIndex].toString()));
replacementIndex++; replacementIndex++;

View file

@ -67,8 +67,9 @@ public class I18NDict {
private static final String GUI_KEY = "gui."; private static final String GUI_KEY = "gui.";
public static final String EXIT = GUI_KEY + "exit"; public static final String EXIT = GUI_KEY + "exit";
public static final String UNAVAILABLE = GUI_KEY + "unavailable";
public static final String GO_BACK = GUI_KEY + "go_back"; public static final String GO_BACK = GUI_KEY + "go_back";
public static final String UNAVAILABLE = GUI_KEY + "unavailable";
public static final String LOADING = GUI_KEY + "loading";
public static class Choice { public static class Choice {
private static final String CHOICE_KEY = GUI_KEY + "choice."; private static final String CHOICE_KEY = GUI_KEY + "choice.";

View file

@ -36,6 +36,8 @@ gui:
name: "Unavailable" name: "Unavailable"
lore: lore:
- "§7§oThis button is disabled." - "§7§oThis button is disabled."
loading:
name: "§7§oLoading..."
choice: choice:
confirm: confirm:
name: "§aConfirm" name: "§aConfirm"
@ -68,7 +70,7 @@ gui:
manage_cache: manage_cache:
name: "Manage §6skin §fcache..." name: "Manage §6skin §fcache..."
lore: lore:
- "§7Access the skin cache management panel." - "§7View and manage the skin cache."
manage_player: manage_player:
name: "Check a player..." name: "Check a player..."
lore: lore:

View file

@ -13,14 +13,14 @@ event:
error: "§cImpossible de mettre à jour vos paramètres. §7§o({0})" error: "§cImpossible de mettre à jour vos paramètres. §7§o({0})"
appearance: appearance:
set: set:
error: "§cImpossible d'appliquer votre déguisement. §7§o({0})" error: "§cImpossible d''appliquer votre déguisement. §7§o({0})"
ok: "§fDéguisement appliqué." ok: "§fDéguisement appliqué."
restore: restore:
error: "§cImpossible d'appliquer votre précédent déguisement. §7§o({0})" error: "§cImpossible d''appliquer votre précédent déguisement. §7§o({0})"
ok: "§aVotre précédent déguisement a été appliqué." ok: "§aVotre précédent déguisement a été appliqué."
remove: remove:
error: "§cImpossible de retirer votre déguisement. Il sera réinitialisé à votre prochaine reconnexion." error: "§cImpossible de retirer votre déguisement. Il sera réinitialisé à votre prochaine reconnexion."
missing: "§cVous n'avez pas de déguisement." missing: "§cVous n''avez pas de déguisement."
ok: "§fDéguisement retiré." ok: "§fDéguisement retiré."
admin: admin:
cache: cache:
@ -36,6 +36,8 @@ gui:
name: "Indisponible" name: "Indisponible"
lore: lore:
- "§7§oCe boutton est désactivé." - "§7§oCe boutton est désactivé."
loading:
name: "§7§oChargement..."
choice: choice:
confirm: confirm:
name: "§aConfirmer" name: "§aConfirmer"
@ -66,9 +68,9 @@ gui:
admin: admin:
title: "Nicko > Administration" title: "Nicko > Administration"
manage_cache: manage_cache:
name: "Gérer le cache d'§6skin..." name: "Gérer le cache de §6skin..."
lore: lore:
- "§7Accédez à la gestion du cache de skin." - "§7Consultez et gérez le cache de skin."
manage_player: manage_player:
name: "Vérifier un joueur..." name: "Vérifier un joueur..."
lore: lore:

View file

@ -14,10 +14,9 @@ import xyz.atnrch.nicko.i18n.I18NDict;
import xyz.atnrch.nicko.i18n.ItemTranslation; import xyz.atnrch.nicko.i18n.ItemTranslation;
import xyz.atnrch.nicko.i18n.Locale; import xyz.atnrch.nicko.i18n.Locale;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class I18NItemTranslationTest { public class ItemTranslationTest {
private static PlayerMock player; private static PlayerMock player;
@BeforeAll @BeforeAll
@ -44,8 +43,11 @@ public class I18NItemTranslationTest {
@DisplayName("Translate Item") @DisplayName("Translate Item")
public void translateItemLore() { public void translateItemLore() {
final I18N i18n = new I18N(Locale.FRENCH); final I18N i18n = new I18N(Locale.FRENCH);
final String translation = i18n.translatePrefixless(I18NDict.Event.Settings.ERROR, "Test!"); final ItemTranslation translation = i18n.translateItem(I18NDict.GUI.Admin.Cache.STATISTICS, "1", "1");
assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test!)", translation); assertFalse(translation.getLore().isEmpty());
assertEquals("§fNombre de requêtes: §b1", translation.getLore().get(0));
assertEquals("§fNb. de skin dans le cache: §b1", translation.getLore().get(1));
assertEquals("§8§oLe cache est vidé toutes les 24 heures.", translation.getLore().get(2));
} }
@AfterAll @AfterAll

View file

@ -0,0 +1,44 @@
package xyz.atnrch.nicko.test.i18n;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.entity.PlayerMock;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import xyz.atnrch.nicko.NickoBukkit;
import xyz.atnrch.nicko.config.Configuration;
import xyz.atnrch.nicko.config.DataSourceConfiguration;
import xyz.atnrch.nicko.i18n.I18N;
import xyz.atnrch.nicko.i18n.I18NDict;
import xyz.atnrch.nicko.i18n.Locale;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class TranslationTest {
private static PlayerMock player;
@BeforeAll
public static void setup() {
final Configuration config = new Configuration(
DataSourceConfiguration.SQL_EMPTY,
DataSourceConfiguration.REDIS_EMPTY,
"",
false);
MockBukkit.mock();
MockBukkit.load(NickoBukkit.class, config);
}
@Test
@DisplayName("Translate Line With Replacement")
public void translateItemTranslationWithoutLore() {
final I18N i18n = new I18N(Locale.FRENCH);
final String translation = i18n.translatePrefixless(I18NDict.Event.Settings.ERROR, "Test");
assertEquals("§cImpossible de mettre à jour vos paramètres. §7§o(Test)", translation);
}
@AfterAll
public static void shutdown() {
MockBukkit.unmock();
}
}