Resource [1.7.2 - 1.15+] Show translated item/entity/etc. names in CLIENT's language

Discussion in 'Spigot Plugin Development' started by PikaMug, Mar 13, 2019.

  1. Hello, everyone! I'm the current developer of the free Quests plugin. At time of writing, it fully supports 13 languages and counting, but some non-English users reported item names popping up in English to be an eyesore. Others were annoyed by the difference between Material names and their actual Minecraft names, especially on pre-1.13. Personally, I was frustrated by the removal of the Item API from Vault.

    Thus, this resource was born out of necessity. I believe it to be the only sane and legal method of getting item names from the client's internal locale file to display on-screen, from Bukkit 1.7.2 to 1.13.2 and beyond.

    As of Minecraft 1.13.2, players can choose from 118 languages in their client. All except for the included "English (US)" are hosted here on Crowdin, a wonderful platform where those qualified may submit translations to the game. However, the managers have disabled file downloads, so there's no easy way to just go and package it all into your plugin.

    Not that you'd want to! Those files would likely be property of Mojang and publishing their translations in your plugin would probably be illegal (IANAL). However, one could open a Minecraft server jar in an archive manager and navigate to assets\minecraft\lang\en_us.lang to obtain the English (US) file.

    Each translation within the file has a "key" (or "identifier") and "value", which looks like this on 1.13+:
    In Español (México), this would look something like:
    Note that while the value ("Stone" versus "Piedra") is different, the key ("tile.stone.stone.name") is the same. As long as we have the key, the client can determine the value based on whatever language the player has chosen.

    That's where this resource comes in! For 1.13 and up, we're going to use reflection to get the right key from a Bukkit Material. For 1.12.2 and below, the class has maps which link Material+durability combinations to their keys. Similar maps are also present for EntityType and Enchantment.

    Once we have the key, we can create a message to send to a Player which contains our item to translate.

    How does it get sent to the client?

    This resource abuses the /tellraw command to send raw JSON text which the client will translate for us on receipt. If you're only supporting a single version or have a module project, feel free to use NMS via PacketPlayOutChat. Additionally, I've opted to forego using the Chat Component API so we can support both Spigot and plain ol' Bukkit.

    Once it's imported, all you'd have to do is send messages to the Player like this:

    Code (Java):
    localeManager.sendMessage(player, "I make " + ChatColor.GREEN + "<item>" + ChatColor.RESET  +" look good", Material.DIRT, (short) 0, null);
    Which on an English (US) client and Español (México) client would respectively appear as:

    [​IMG] [​IMG]

    Great! Where do I get started?

    You can drop this single LocaleQuery class into your plugin to get started (outdated 10/7/19):
    https://gist.github.com/PikaMug/eeb622a5c609bd00d1db3de4794b3424

    Or, you can link to this library I've created which is functionally identical (also contains more documentation):
    https://www.spigotmc.org/resources/localelib.65617/

    If you'd like to contribute to the project code-wise, please submit a Pull request here:
    https://github.com/PikaMug/LocaleLib

    * Big thanks to this resource by @KyleDaHorsey for kicking this off.
     
    #1 PikaMug, Mar 13, 2019
    Last edited: Oct 8, 2019
    • Useful Useful x 3