From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 11 Aug 2020 19:16:09 +0200
Subject: [PATCH] Add methods to get translation keys

== AT ==
public org.bukkit.craftbukkit.inventory.CraftMetaFirework
public org.bukkit.craftbukkit.inventory.CraftMetaFirework power
public org.bukkit.craftbukkit.inventory.CraftMetaFirework getNBT(Lorg/bukkit/FireworkEffect$Type;)Lnet/minecraft/world/item/component/FireworkExplosion$Shape;

Co-authored-by: MeFisto94 <MeFisto94@users.noreply.github.com>

diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index f041b5d80bff9c022b007e04ef1558e9116acc6b..a586442422a2b2c06b785af0d261d3e19eb1d59b 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -669,5 +669,10 @@ public class CraftBlock implements Block {
     public org.bukkit.SoundGroup getBlockSoundGroup() {
         return org.bukkit.craftbukkit.CraftSoundGroup.getSoundGroup(this.getNMS().getSoundType());
     }
+
+    @Override
+    public String translationKey() {
+        return this.getNMS().getBlock().getDescriptionId();
+    }
     // Paper end
 }
diff --git a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
index d839a0edf31f6803e5813b28a23fa17e20916b2c..bb8a3e670924ebcce48669c5dce57e2df03fad77 100644
--- a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
+++ b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
@@ -145,6 +145,11 @@ public class CraftEnchantment extends Enchantment implements Handleable<net.mine
     public net.kyori.adventure.text.Component displayName(int level) {
         return io.papermc.paper.adventure.PaperAdventure.asAdventure(getHandle().getFullname(level));
     }
+
+    @Override
+    public String translationKey() {
+        return this.handle.getDescriptionId();
+    }
     // Paper end
 
     @Override
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java
index ebdb19d7ee0460d50c082b0a41b3a6a57a3534ee..b444bd26d6c3def3494d3cc0520e462408272be3 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java
@@ -111,7 +111,7 @@ class CraftMetaFirework extends CraftMetaItem implements FireworkMeta {
         return new FireworkExplosion(CraftMetaFirework.getNBT(effect.getType()), colors, fadeColors, effect.hasTrail(), effect.hasFlicker());
     }
 
-    static FireworkExplosion.Shape getNBT(Type type) {
+    public static FireworkExplosion.Shape getNBT(Type type) { // Paper - package-private -> public
         switch (type) {
             case BALL:
                 return FireworkExplosion.Shape.SMALL_BALL;
diff --git a/src/test/java/io/papermc/paper/world/TranslationKeyTest.java b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
index 7f8b6462d2a1bbd39a870d2543bebc135f7eb45b..441e8fbd548e425ca9b0dfd69d08f7b83081888c 100644
--- a/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
+++ b/src/test/java/io/papermc/paper/world/TranslationKeyTest.java
@@ -1,12 +1,27 @@
 package io.papermc.paper.world;
 
 import com.destroystokyo.paper.ClientOption;
+import java.util.Map;
+import net.minecraft.core.registries.BuiltInRegistries;
+import net.minecraft.network.chat.contents.TranslatableContents;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.resources.ResourceLocation;
 import net.minecraft.world.entity.player.ChatVisiblity;
+import net.minecraft.world.level.GameType;
+import net.minecraft.world.level.biome.Biome;
 import org.bukkit.Difficulty;
+import org.bukkit.FireworkEffect;
+import org.bukkit.GameMode;
+import org.bukkit.GameRule;
+import org.bukkit.MusicInstrument;
+import org.bukkit.attribute.Attribute;
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
+import org.bukkit.support.AbstractTestingBase;
 import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
-public class TranslationKeyTest {
+public class TranslationKeyTest extends AbstractTestingBase {
 
     @Test
     public void testChatVisibilityKeys() {
@@ -15,4 +30,69 @@ public class TranslationKeyTest {
             Assertions.assertEquals(ChatVisiblity.valueOf(chatVisibility.name()).getKey(), chatVisibility.translationKey(), chatVisibility + "'s translation key doesn't match");
         }
     }
+
+    @Test
+    public void testDifficultyKeys() {
+        for (Difficulty bukkitDifficulty : Difficulty.values()) {
+            Assertions.assertEquals(((TranslatableContents) net.minecraft.world.Difficulty.byId(bukkitDifficulty.ordinal()).getDisplayName().getContents()).getKey(), bukkitDifficulty.translationKey(), bukkitDifficulty + "'s translation key doesn't match");
+        }
+    }
+
+    @Test
+    public void testGameruleKeys() {
+        for (GameRule<?> rule : GameRule.values()) {
+            Assertions.assertEquals(org.bukkit.craftbukkit.CraftWorld.getGameRulesNMS().get(rule.getName()).getDescriptionId(), rule.translationKey(), rule.getName() + "'s translation doesn't match");
+        }
+    }
+
+    @Test
+    public void testAttributeKeys() {
+        for (Attribute attribute : Attribute.values()) {
+            Assertions.assertEquals(org.bukkit.craftbukkit.attribute.CraftAttribute.bukkitToMinecraft(attribute).getDescriptionId(), attribute.translationKey(), "translation key mismatch for " + attribute);
+        }
+    }
+
+    @Test
+    public void testFireworkEffectType() {
+        for (final FireworkEffect.Type type : FireworkEffect.Type.values()) {
+            final net.minecraft.world.item.component.FireworkExplosion.Shape nmsType = org.bukkit.craftbukkit.inventory.CraftMetaFirework.getNBT(type);
+            Assertions.assertTrue(nmsType.getName().getContents() instanceof TranslatableContents, "contents aren't translatable");
+            Assertions.assertEquals(((TranslatableContents) nmsType.getName().getContents()).getKey(), type.translationKey(), "translation key mismatch for " + type);
+        }
+    }
+
+    @Test
+    @Disabled // TODO fix
+    public void testCreativeCategory() {
+        // for (CreativeModeTab tab : CreativeModeTabs.tabs()) {
+        //     CreativeCategory category = Objects.requireNonNull(CraftCreativeCategory.fromNMS(tab));
+        //     Assertions.assertEquals("translation key mismatch for " + category, ((TranslatableContents) tab.getDisplayName().getContents()).getKey(), category.translationKey());
+        // }
+    }
+
+    @Test
+    public void testGameMode() {
+        for (GameType nms : GameType.values()) {
+            GameMode bukkit = GameMode.getByValue(nms.getId());
+            Assertions.assertNotNull(bukkit);
+            Assertions.assertEquals(((TranslatableContents) nms.getLongDisplayName().getContents()).getKey(), bukkit.translationKey(), "translation key mismatch for " + bukkit);
+        }
+    }
+
+    @Test
+    public void testBiome() {
+        for (Map.Entry<ResourceKey<Biome>, Biome> nms : AbstractTestingBase.BIOMES.entrySet()) {
+            org.bukkit.block.Biome bukkit = org.bukkit.block.Biome.valueOf(nms.getKey().location().getPath().toUpperCase());
+            Assertions.assertEquals(nms.getKey().location().toLanguageKey("biome"), bukkit.translationKey(), "translation key mismatch for " + bukkit);
+        }
+    }
+
+    @Test
+    public void testMusicInstrument() {
+        for (final ResourceLocation nms : BuiltInRegistries.INSTRUMENT.keySet()) {
+            final MusicInstrument bukkit = MusicInstrument.getByKey(CraftNamespacedKey.fromMinecraft(nms));
+            Assertions.assertNotNull(bukkit, "Missing bukkit instrument for " + nms);
+            Assertions.assertEquals(nms.toLanguageKey("instrument"), bukkit.translationKey(), "translation key mismatch for " + bukkit);
+        }
+    }
 }
