From 84e792880f73819ca1a2fe91caff029e19deb28a Mon Sep 17 00:00:00 2001 From: ineanto Date: Fri, 22 Dec 2023 17:23:36 +0100 Subject: [PATCH] feat(i18n): move to adventure --- build.gradle.kts | 1 + .../nicko/appearance/AppearanceManager.java | 8 +- .../java/xyz/ineanto/nicko/gui/HomeGUI.java | 9 +- .../gui/items/admin/cache/CacheEntryItem.java | 25 +++--- .../gui/items/common/ScrollDownItem.java | 3 +- .../nicko/gui/items/common/ScrollUpItem.java | 3 +- .../nicko/gui/items/home/RandomSkinItem.java | 53 ++++++++++++ .../nicko/gui/items/home/ResetItem.java | 2 - .../items/settings/LanguageCyclingItem.java | 3 +- .../java/xyz/ineanto/nicko/i18n/I18N.java | 16 +++- .../java/xyz/ineanto/nicko/i18n/I18NDict.java | 1 + src/main/resources/en.yml | 85 +++++++++---------- src/main/resources/fr.yml | 76 +++++++++-------- 13 files changed, 175 insertions(+), 110 deletions(-) create mode 100644 src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java diff --git a/build.gradle.kts b/build.gradle.kts index cbce73f..39403a9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -49,6 +49,7 @@ dependencies { implementation("com.comphenix.protocol:ProtocolLib:5.1.1-SNAPSHOT") shadowImplementation("me.clip:placeholderapi:2.11.4") + shadowImplementation("net.kyori:adventure-api:4.14.0") shadowImplementation("xyz.xenondevs.invui:invui:1.23") shadowImplementation("net.wesjd:anvilgui:1.9.0-SNAPSHOT") shadowImplementation("com.github.jsixface:yamlconfig:1.2") diff --git a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java index fa7bd53..c4cd1e0 100644 --- a/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java +++ b/src/main/java/xyz/ineanto/nicko/appearance/AppearanceManager.java @@ -40,13 +40,7 @@ public class AppearanceManager { profile.setName(defaultName); profile.setSkin(defaultName); dataStore.getCache().cache(player.getUniqueId(), profile); - final ActionResult actionResult = updatePlayer(true, true); - if (!actionResult.isError()) { - profile.setSkin(null); - profile.setName(null); - dataStore.getCache().cache(player.getUniqueId(), profile); - } - return actionResult; + return updatePlayer(true, true); } public ActionResult updatePlayer(boolean skinChange, boolean reset) { diff --git a/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java b/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java index 24d9b06..92e3d1b 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java +++ b/src/main/java/xyz/ineanto/nicko/gui/HomeGUI.java @@ -4,10 +4,7 @@ import org.bukkit.entity.Player; import xyz.ineanto.nicko.gui.items.appearance.ChangeBothItem; import xyz.ineanto.nicko.gui.items.appearance.ChangeNameItem; import xyz.ineanto.nicko.gui.items.appearance.ChangeSkinItem; -import xyz.ineanto.nicko.gui.items.home.AdminAccessItem; -import xyz.ineanto.nicko.gui.items.home.ExitItem; -import xyz.ineanto.nicko.gui.items.home.ResetItem; -import xyz.ineanto.nicko.gui.items.home.SettingsAccessItem; +import xyz.ineanto.nicko.gui.items.home.*; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; import xyz.xenondevs.invui.gui.Gui; @@ -20,7 +17,7 @@ public class HomeGUI { public HomeGUI(Player player) { final String[] dynamicStructure = new String[]{ - "# # # # # # # # #", + "# # # # D # # # #", "A # # N B S # # #", "E P # # # # # # R"}; @@ -38,6 +35,7 @@ public class HomeGUI { final ChangeSkinItem changeSkinItem = new ChangeSkinItem(player); final SettingsAccessItem settingsAccessItem = new SettingsAccessItem(player); final AdminAccessItem adminAccessItem = new AdminAccessItem(player); + final RandomSkinItem randomSkinItem = new RandomSkinItem(player); this.gui = Gui.normal() .setStructure(dynamicStructure) @@ -48,6 +46,7 @@ public class HomeGUI { .addIngredient('S', changeSkinItem.get()) .addIngredient('P', settingsAccessItem.get()) .addIngredient('A', adminAccessItem.get()) + .addIngredient('D', randomSkinItem.get()) .build(); this.player = player; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java index 56a5cd1..286cade 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/admin/cache/CacheEntryItem.java @@ -1,5 +1,6 @@ package xyz.ineanto.nicko.gui.items.admin.cache; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; @@ -27,17 +28,19 @@ public class CacheEntryItem extends AsyncItem { private final MojangAPI mojangAPI = NickoBukkit.getInstance().getMojangAPI(); public CacheEntryItem(I18N i18n, String uuid) { - super(new ItemBuilder(Material.PAINTING).setDisplayName("§7§oLoading..."), () -> { - final String dashedUuid = uuid.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); - final UUID uuidObject = UUID.fromString(dashedUuid); - try { - final SkullBuilder skull = new SkullBuilder(uuidObject); - return i18n.translateItem(skull, I18NDict.GUI.Admin.Cache.ENTRY, NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); - } catch (MojangApiUtils.MojangApiException | IOException e) { - NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for specified UUID (" + uuid + ")! (GUI/Cache/Entry)"); - return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Admin.Cache.ENTRY, NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); - } - }); + super(new ItemBuilder(Material.PAINTING) + .setDisplayName(Component.text(i18n.translateStringWithoutPrefix(I18NDict.GUI.LOADING)).content()), + () -> { + final String dashedUuid = uuid.replaceAll("(.{8})(.{4})(.{4})(.{4})(.+)", "$1-$2-$3-$4-$5"); + final UUID uuidObject = UUID.fromString(dashedUuid); + try { + final SkullBuilder skull = new SkullBuilder(uuidObject); + return i18n.translateItem(skull, I18NDict.GUI.Admin.Cache.ENTRY, NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); + } catch (MojangApiUtils.MojangApiException | IOException e) { + NickoBukkit.getInstance().getLogger().warning("Unable to get Head texture for specified UUID (" + uuid + ")! (GUI/Cache/Entry)"); + return ItemDefaults.getErrorSkullItem(i18n, I18NDict.GUI.Admin.Cache.ENTRY, NickoBukkit.getInstance().getMojangAPI().getUUIDName(uuid)); + } + }); this.uuid = uuid; this.name = mojangAPI.getUUIDName(uuid); } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java index f836f78..44b32ab 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollDownItem.java @@ -1,5 +1,6 @@ package xyz.ineanto.nicko.gui.items.common; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; @@ -21,7 +22,7 @@ public class ScrollDownItem extends ScrollItem { public ItemProvider getItemProvider(ScrollGui gui) { final ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE); final Translation translation = i18n.translate(I18NDict.GUI.SCROLL_DOWN); - builder.setDisplayName(translation.name()); + builder.setDisplayName(Component.text(translation.name()).content()); if (!gui.canScroll(1)) translation.lore().forEach(builder::addLoreLines); return builder; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java index 51dc950..0e60dfa 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/common/ScrollUpItem.java @@ -1,5 +1,6 @@ package xyz.ineanto.nicko.gui.items.common; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import xyz.ineanto.nicko.i18n.I18N; import xyz.ineanto.nicko.i18n.I18NDict; @@ -21,7 +22,7 @@ public class ScrollUpItem extends ScrollItem { public ItemProvider getItemProvider(ScrollGui gui) { final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE); final Translation translation = i18n.translate(I18NDict.GUI.SCROLL_UP); - builder.setDisplayName(translation.name()); + builder.setDisplayName(Component.text(translation.name()).content()); if (!gui.canScroll(-1)) translation.lore().forEach(builder::addLoreLines); return builder; } diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java new file mode 100644 index 0000000..16d6675 --- /dev/null +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/RandomSkinItem.java @@ -0,0 +1,53 @@ +package xyz.ineanto.nicko.gui.items.home; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import xyz.ineanto.nicko.NickoBukkit; +import xyz.ineanto.nicko.appearance.AppearanceManager; +import xyz.ineanto.nicko.i18n.I18N; +import xyz.ineanto.nicko.i18n.I18NDict; +import xyz.ineanto.nicko.profile.NickoProfile; +import xyz.xenondevs.invui.item.builder.SkullBuilder; +import xyz.xenondevs.invui.item.impl.SuppliedItem; + +import java.util.Optional; + +public class RandomSkinItem { + private final I18N i18n; + private final NickoBukkit instance; + + public RandomSkinItem(Player player) { + this.instance = NickoBukkit.getInstance(); + this.i18n = new I18N(player); + } + + public SuppliedItem get() { + return new SuppliedItem(() -> { + final SkullBuilder.HeadTexture texture = new SkullBuilder.HeadTexture("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzgzMTEzOGMyMDYxMWQzMDJjNDIzZmEzMjM3MWE3NDNkMTc0MzdhMTg5NzNjMzUxOTczNDQ3MGE3YWJiNCJ9fX0="); + final SkullBuilder builder = new SkullBuilder(texture); + return i18n.translateItem(builder, I18NDict.GUI.Home.RANDOM_SKIN); + }, (event) -> { + final Player player = event.getPlayer(); + final ClickType clickType = event.getClickType(); + if (clickType.isLeftClick() || clickType.isRightClick()) { + final Optional optionalProfile = NickoProfile.get(player); + optionalProfile.ifPresent(profile -> { + final String name = instance.getNameFetcher().getRandomUsername(); + final String skin = instance.getNameFetcher().getRandomUsername(); + profile.setName(name); + profile.setSkin(skin); + instance.getDataStore().updateCache(player.getUniqueId(), profile); + + final AppearanceManager appearanceManager = new AppearanceManager(player); + if (!appearanceManager.updatePlayer(true, false).isError()) { + player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Set.OK)); + } else { + player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Set.ERROR)); + } + }); + return true; + } + return false; + }); + } +} diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java index f8bf299..4ee2bad 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/home/ResetItem.java @@ -40,8 +40,6 @@ public class ResetItem { player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Remove.OK)); } else { player.sendMessage(i18n.translateString(I18NDict.Event.Appearance.Remove.ERROR)); - profile.setSkin(null); - profile.setName(null); } }); return true; diff --git a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java index 4a2946e..3fa196a 100644 --- a/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java +++ b/src/main/java/xyz/ineanto/nicko/gui/items/settings/LanguageCyclingItem.java @@ -1,5 +1,6 @@ package xyz.ineanto.nicko.gui.items.settings; +import net.kyori.adventure.text.Component; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.entity.Player; @@ -59,7 +60,7 @@ public class LanguageCyclingItem { final Translation translation = i18n.translate(I18NDict.GUI.Settings.LANGUAGE); final Translation cyclingChoicesTranslation = i18n.translate(I18NDict.GUI.Settings.CYCLING_CHOICES); - builder.setDisplayName(translation.name()); + builder.setDisplayName(Component.text(translation.name()).content()); for (Locale value : locales) { if (locale != value) { builder.addLoreLines("§7> " + value.getName()); diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java index 1b1f14b..fd33cec 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18N.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18N.java @@ -1,6 +1,9 @@ package xyz.ineanto.nicko.i18n; import com.github.jsixface.YamlConfig; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.entity.Player; import xyz.ineanto.nicko.NickoBukkit; import xyz.ineanto.nicko.profile.NickoProfile; @@ -36,7 +39,18 @@ public class I18N { public AbstractItemBuilder translateItem(AbstractItemBuilder item, String key, Object... args) { final Translation translation = translate(key, args); - item.setDisplayName(translation.name()); + + // Name serialization + final Component deserializedName = MiniMessage.miniMessage().deserialize(translation.name()); + final String serializedName = LegacyComponentSerializer.legacySection().serialize(deserializedName); + + // Lore serialization + translation.lore().replaceAll(s -> { + final Component deserializedLoreLine = MiniMessage.miniMessage().deserialize(s); + return LegacyComponentSerializer.legacySection().serialize(deserializedLoreLine); + }); + + item.setDisplayName(serializedName); translation.lore().forEach(item::addLoreLines); return item; } diff --git a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java index 0934179..8055a4c 100644 --- a/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java +++ b/src/main/java/xyz/ineanto/nicko/i18n/I18NDict.java @@ -105,6 +105,7 @@ public class I18NDict { public static final String CHANGE_SKIN = HOME_KEY + "change_skin"; public static final String CHANGE_BOTH = HOME_KEY + "change_both"; public static final String RESET = HOME_KEY + "reset"; + public static final String RANDOM_SKIN = HOME_KEY + "random_skin"; public static final String SETTINGS = HOME_KEY + "settings"; } diff --git a/src/main/resources/en.yml b/src/main/resources/en.yml index 4b46b11..c719d68 100644 --- a/src/main/resources/en.yml +++ b/src/main/resources/en.yml @@ -39,11 +39,6 @@ gui: cache: "Nicko > Admin... > Cache" invalidate_skin: "... > Cache > Invalidate" - cycling_choices: - name: "IGNOREME" - lore: - - "§7§oGet through the values" - - "§7§oby left or right clicking." exit: name: "Exit" go_back: @@ -51,99 +46,97 @@ gui: unavailable: name: "Unavailable" lore: - - "§7§oThis button is disabled." + - "This button is disabled." error: name: "Error!" lore: - - "§7" - - "§7The item texture failed to load, but it might still work." + - "The item texture failed to load, but it might still work." loading: - name: "§7§oLoading..." + name: "Loading..." choice: confirm: - name: "§aConfirm" + name: "Confirm" choose: - name: "§6§oChoose an option..." + name: "Choose an option..." cancel: - name: "§cCancel" + name: "Cancel" scroll_up: name: "Scroll up" lore: - - "§8§o(You can't scroll any higher.)" + - "(You can't scroll any higher.)" scroll_down: name: "Scroll down" lore: - - "§8§o(You can't scroll any further down.)" + - "(You can't scroll any further down.)" home: admin: name: "Administration panel" lore: - - "§7Configure and manage Nicko." + - "Configure and manage Nicko." settings: name: "Settings" lore: - - "§7Fine tune your experience with Nicko." + - "Fine tune your experience with Nicko." change_name: - name: "§6Nickname §fchange" + name: "Change your nickname" change_skin: - name: "§6Skin §fchange" + name: "Change your skin" change_both: - name: "Change §6both" + name: "Change both" + random_skin: + name: "Get a random appearance!" reset: name: "Reset appearance" lore: - - "§7Completely remove your disguise." + - "Completely remove your disguise." admin: manage_cache: - name: "Manage §6skin §fcache..." + name: "Manage the skin cache..." lore: - - "§7View and manage the skin cache." + - "View and manage the skin cache." manage_player: - name: "Check a player..." + name: "Inspect a player..." lore: - - "§7See players' disguise information." + - "See players' disguise information." check: - name: "§6{0}" + name: "{0}" lore: - - "§cNicked: §a{1}" - - "§cName: §6{2}" - - "§cSkin: §6{3}" + - "Nicked: {1}" + - "Name: {2}" + - "Skin: {3}" - " " - - "§7§oClick to remove skin!" + - "Click to remove skin!" cache: statistics: name: "Statistics" lore: - - "§fRequest count: §b{0}" - - "§fNumber of skin cached: §b{1}" - - "§8§oCache is cleared every 24 hours." + - "Request count: {0}" + - "Number of skin cached: {1}" + - "Cache is cleared every 24 hours." invalidate_cache: name: "Invalidate cache" lore: - - "§c§oNOT RECOMMENDED" - - "§7Invalidate the entirety of the skin cache." - - "§7This doesn't reset player's disguises." + - "NOT RECOMMENDED" + - "Invalidate the entirety of the skin cache." + - "This doesn't reset player's disguises." invalidate_skin: name: "Invalidate a skin..." lore: - - "§7Select a specific skin to invalidate." - - "§7Useful if a skin has been recently updated." + - "Select a specific skin to invalidate." + - "Useful if a skin has been recently updated." entry: - name: "§6{0}" + name: "{0}" lore: - - "§7Click to invalidate..." + - "Click to invalidate..." settings: toggleable_button: - name: "IGNORE_ME" lore: - # {0}/{1} represents the carets that shows the current selected option. - - "§b{0} Disabled" - - "§b{1} Enabled" + - "{0} Disabled" + - "{1} Enabled" cycling_choices: - name: "IGNORE_ME" lore: - - "§7§oCycle through the values" - - "§7§oby left or right clicking." + - "Cycle through the values" + - "by left or right clicking." language: name: "Language" random_skin: diff --git a/src/main/resources/fr.yml b/src/main/resources/fr.yml index 9b01306..5532c1e 100644 --- a/src/main/resources/fr.yml +++ b/src/main/resources/fr.yml @@ -46,84 +46,90 @@ gui: unavailable: name: "Indisponible" lore: - - "§7§oCe boutton est désactivé." + - "Ce boutton est désactivé." + error: + name: "Erreur!" + lore: + - "La texture de l'objet n'a pas chargé" + - "correctement mais il fonctionne encore." loading: - name: "§7§oChargement..." + name: "Chargement..." choice: confirm: - name: "§aConfirmer" + name: "Confirmer" choose: - name: "§6§oChoisissez une option..." + name: "Choisissez une option..." cancel: - name: "§cAnnuler" + name: "Annuler" scroll_up: name: "Défiler vers le haut" lore: - - "§8§o(Impossible de défiler plus haut.)" + - "(Impossible de défiler plus haut.)" scroll_down: name: "Défiler vers le bas" lore: - - "§8§o(Impossible de défiler plus bas.)" + - "(Impossible de défiler plus bas.)" home: admin: name: "Panel d'administration" lore: - - "§7Configurez et gérez Nicko." + - "Configurez et gérez Nicko." settings: name: "Paramètres" lore: - - "§7Gérez votre expérience avec Nicko." + - "Gérez votre expérience avec Nicko." change_name: - name: "Changer le §6pseudo" + name: "Changer le pseudo" change_skin: - name: "Changer le §6skin" + name: "Changer le skin" change_both: - name: "Changer les §6deux" + name: "Changer les deux" + random_skin: + name: "Obtenir une apparence aléatoire !" reset: name: "Réinitialiser l'apparence" lore: - - "§7Supprime complètement votre déguisement." + - "Supprime complètement votre déguisement." admin: manage_cache: - name: "Gérer le cache de §6skin..." + name: "Gérer le cache de skin..." lore: - - "§7Consultez et gérez le cache de skin." + - "Consultez et gérez le cache de skin." manage_player: name: "Vérifier un joueur..." lore: - - "§7Vérifiez les informations de déguisement d'un joueur." + - "Vérifiez les informations de déguisement d'un joueur." check: - name: "§6{0}" + name: "{0}" lore: - - "§cDéguisé: §a{1}" - - "§cNom: §6{2}" - - "§cSkin: §6{3}" + - "Déguisé: {1}" + - "Nom: {2}" + - "Skin: {3}" - " " - - "§7§oCliquez pour retirer le skin!" + - "Cliquez pour retirer le skin !" cache: statistics: name: "Statistiques" lore: - - "§fNombre de requêtes: §b{0}" - - "§fNb. de skin dans le cache: §b{1}" - - "§8§oLe cache est vidé toutes les 24 heures." + - "Nombre de requêtes: {0}" + - "Nb. de skin dans le cache: {1}" + - "Le cache est vidé toutes les 24 heures." invalidate_cache: name: "Invalider le cache" lore: - - "§c§oDÉCONSEILLÉ" - - "§7Invalide l'entièreté du cache des skin." - - "§7Ne retire pas les déguisements" - - "§7pour les joueurs en disposant." + - "DÉCONSEILLÉ" + - "Invalide l'entièreté du cache des skin." + - "Ne retire pas les déguisements des joueurs." invalidate_skin: name: "Invalider un skin..." lore: - - "§7Sélectionnez une apparence spécifique à" - - "§7invalider. Utile dans le cas où un skin" - - "§7a récemment été mis à jour." + - "Sélectionnez une apparence spécifique à" + - "invalider. Utile dans le cas où un skin" + - "a récemment été mis à jour." entry: - name: "§6{0}" + name: "{0}" lore: - - "§7Cliquez pour invalider..." + - "Cliquez pour invalider..." settings: toggleable_button: lore: @@ -131,8 +137,8 @@ gui: - "{1} Activé" cycling_choices: lore: - - "§7§oParcourez les valeurs" - - "§7§oavec un clique gauche/droit." + - "Parcourez les valeurs" + - "avec un clique gauche/droit." language: name: "Langage" random_skin: