Jump to content

[1.8] Dynamically update .lang files


PixelsNeverDie

Recommended Posts

For my current Project, I've allowed translators to change the localization for their main language on a nice website. I've provided an API call to generate a .lang file from the strings in the database.

 

I now want to automatically update the .lang files for the requested language whenever the language is changed or the mod is restarted. Therefore, I've registered the following IResourceManagerReloadListener:

 

((SimpleReloadableResourceManager)mc.getResourceManager()).registerReloadListener(new IResourceManagerReloadListener() {
            @Override
            public void onResourceManagerReload(IResourceManager resourceManager) {
                SimpleReloadableResourceManager rm = (SimpleReloadableResourceManager) resourceManager;
                Language current = mc.getLanguageManager().getCurrentLanguage();
                String languageCode = current.getLanguageCode();

                try {
                    File file = new File("./" + languageCode + ".lang");
                    file.createNewFile();
                    apiClient.downloadTranslation(languageCode, file);

                    ArrayList arraylist = Lists.newArrayList(new String[]{"en_US"});

                    if(!"en_US".equals(languageCode)) {
                        arraylist.add(languageCode);
                    }

                    Properties prop = new Properties();
                    prop.load(new FileInputStream(file));

                    HashMap<String, String> lang_prop = StringTranslate.parseLangFile(new FileInputStream(file));

                    net.minecraftforge.fml.common.registry.LanguageRegistry.instance().mergeLanguageTable(lang_prop, languageCode);

                    for(Map.Entry e : lang_prop.entrySet()) {
                        System.out.println(e.getKey() + " => " + e.getValue());
                    }

                    StringTranslate.replaceWith(lang_prop);

                    System.out.println("Written to " + file.getAbsolutePath());
                } catch(Exception e) {
                    e.printStackTrace();
                }
            }
        });

 

The mappings in the lang_prop Map are correct (thus the debug output), but it doesn't translate the localized Strings from the mod.

And yes, my localization is properly implemented using I18n.format();

 

Any suggestions?

 

Thanks in advance,

CrushedPixel

Link to comment
Share on other sites

Make it WAY less complicated.

Implement IResourcePack. For a given language, emulate an "langcode.lang" file (e.g. en_US.lang) via the getInputStream method in IResourcePack (to convert a string use ByteArrayInputStream with String.getBytes(Charsets.UTF8)).

 

Then put the IResourcePack into the default resource packs (Minecraft#defaultResourcePacks, you need reflection).

 

Done, leave all the language loading to MC.

 

Should I have any physical Resource Pack on the Hard Drive? Or is everything just emulated by the mod itself?

I think I need a code example for the getInputStream Method to get started.

Link to comment
Share on other sites

Example implementation that adds a translation in english from "foo" to "bar":

 

 

public class IResourcePackImpl implements IResourcePack {
    public InputStream getInputStream(ResourceLocation location) throws IOException {
        if (location.getResourcePath().equals("lang/en_US.lang")) {
            return new ByteArrayInputStream("foo:bar".getBytes(Charsets.UTF_);
        } else {
            return null;
        }
    }

    public boolean resourceExists(ResourceLocation location) {
        return location.getResourcePath().equals("lang/en_US.lang");
    }

    public Set getResourceDomains() {
        return Collections.singleton("myResourceDomain");
    }

    public IMetadataSection getPackMetadata(IMetadataSerializer p_135058_1_, String p_135058_2_) throws IOException {
        return null;
    }

    public BufferedImage getPackImage() throws IOException {
        return null;
    }

    public String getPackName() {
        return "MyResourcePack";
    }
}

 

 

Untested.

As for needing files on disk, that depends on your usecase. Minecraft just wants an InputStream. Whether that reads from a constant String, downloads a File from the internet or whatever does not matter.

 

I've got everything to work. Thank you so much!

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.