Jump to content

best way for externally loading .lang files/other resources...


jredfox

Recommended Posts

is there already a way in forge for loading external resources such as .lang files or does this require vanilla implementation of IResourcePack? How do you register an IResourcePack? Yes the point is automation and I already have a config library in place for this already I just need to know best way for mc/forge to load this into a resource

Edited by jredfox
Link to comment
Share on other sites

1 hour ago, diesieben07 said:

On the server you have to use Class::getResource resp. Class::getResourceAsStream. 1.13 will change this with data packs.

On the client resource packs are the way to go, using IResourceManager::getResource. To register a new "default" resource pack (one that will always be considered, like mods or vanilla textures), you need to add it to Minecraft::defaultResourcePacks on startup (you'll need reflection).

Is lang files on the server I thought it was client only for altering strings into readable names? Ok so I do need IResourcePack start working on this tomorrow 

 

Link to comment
Share on other sites

5 minutes ago, diesieben07 said:

Yes, language files are client-only.

ok so how do I convert this code to client only the constructor has the lang object but, how do I make it do nothing on the server side for the lang objects(basically just a set of 3 strings[id,name,langaguetype])? 
https://gist.github.com/jredfox/b55321cd33653f919fac659cd3128b96

 

Constructor call snip:

for(LangEntry entry : langlist)
{
	entry.langId = "tile." + unlocalname + ".name";
	this.langs.add(entry);
}

 

Edited by jredfox
Link to comment
Share on other sites

4 minutes ago, diesieben07 said:

I have no idea what that LangEntry is supposed to achieve, so I cannot answer that.

package com.EvilNotch.lib.util.minecraft.content;

public class LangEntry {
	
	public String langDisplayName = null;
	public String langType = null;
	public String langId = null;
	
	/**
	 * use this one if your manually calling it for advanced constructors in basic items/blocks
	 */
	public LangEntry(String display,String langType){
		this.langDisplayName = display;
		this.langType = langType;
	}
	
	/**
	 * Don't use this one if your using the advanced constructor on basic items/blocks as it auto fills in the id of the lang
	 */
	public LangEntry(String display,String langType,String langid){
		this.langDisplayName = display;
		this.langType = langType;
		this.langId = langid;
	}
	
	@Override
	public String toString(){return this.langId + "=" + this.langDisplayName + " Lang:" + this.langType;}
	
	public String getString(){return this.langId + "=" + this.langDisplayName;}
	
	@Override
	public boolean equals(Object obj){
		if(!(obj instanceof LangEntry))
			return false;
		LangEntry lang = (LangEntry)obj;
		return this.langId.equals(lang.langId) && this.langType.equals(lang.langType);
	}

}

 

Basically it's three strings that organized like a resource location
lang.id is "tile.minecraft.stone.name"

lang.displayname is the name to display "Stone"

lang.entryType = "en_us" || "ru" etc...


I was going to use a set of three strings but, code started looking like a mess for myself so I converted it to an object the user inputs lang language and lang display name then the constructor takes care of the lang.id 

Edited by jredfox
Link to comment
Share on other sites

4 minutes ago, diesieben07 said:

No. Don't do this.

Make a lang file.

my program auto adds the file though. I just need it running on only client side.

 

it doesn't take much ms like 50ms for a huge file once per launch. It only reads it once and then writes it if and only if it detects an update. Also one file per language for all mods using the specific object and if not registered won't create that file.

You didn't have a problem with generating json models which is more on ram?

Edited by jredfox
Link to comment
Share on other sites

7 minutes ago, diesieben07 said:

You make it impossible for people to add translations for your mod...

Just make a lang file like everyone else.

Ok I undersand why you so mad now? I use my line library so if the identifier of the line is tile.stone.name it will say hey this line already exists don't add it for the default addLine() keeping them as configurations. 

 

ConfigBase config = new ConfigBase(file);
config.addLine(new LineBase("tile.stone.name=Ardvark");
config.updateConfig(true,false,true);//first is alphabitize,force update,the third is messege when updating

Output if already exists:

none since it already has the line tile.stone.name

 

Same concept with my dungeon tweaks it only appends a line if it doesn't exists so the main point of a configuration file is to gather data.

You can config them with my mod via > config > evilnotchlib > lang > en_us.lang. And since it's a resource pack the higher ones will be overriding me so there is nothing to worry about.

Edited by jredfox
Link to comment
Share on other sites

7 minutes ago, diesieben07 said:

The question is why... You are just duplicating things and making it harder for everyone.

new BasicBlock(new ResourceLocation("modid:block"),new LangEntry("Basic Block","en_us") );

goal creates registers after preinits models,registers to forge as well as setting the lang. Sadly models are WIP right now so they don't auto gen defaults based on type as of yet. As for when it registers it does it during the register event.

I don't know about you but, I enjoy the lazy life just need to optimize it so it registers lang on client side only. That's why I enjoyed 1.7.10 so much 1-2 lines of code you got a block into the game not hundreds later

Edited by jredfox
Link to comment
Share on other sites

5 minutes ago, diesieben07 said:

Oh god it's even worse...

Don't put translations in code.

it's not those are the initial values people can config them in the actual file later from where it is generated. Think of it like forge's config hey I want this int forge says ok give me the default value so if it doesn't exists I can create them if it does I will grab them. Difference is I keep lines in memory till I am done forges you can turn off and then have to reload. Although you can simulate this with mine by simply never storing it for more then you need it. 

So basically the display name can be whatever but, it will re-add them if you call a new block and it can't find the line

generated.PNG

Edited by jredfox
Link to comment
Share on other sites

14 minutes ago, diesieben07 said:

The what now?

 

My point is that having translations in your code makes things harder in many ways:

  • Someone wanting to translate your mod cannot simply take your lang file and translate. They have to guess what keys you used.
  • Translations are scattered all over your code. If you decide to change the name of something that's used in multiple places, you better find them all!
  • Overall it's just bad programming practice. Data and code should be kept separate.

Isn't that the case with every mod you need to open up your lang file to find the keys anyways? Mine is no different just a different location I suppose I could just add a description saying where to config them and if they refuse to do that they simply just use a resource pack.

 

Maybe you misunderstood me the key of the lang is always going to be in the file the user doesn't have to specify the key in code as it's auto generated from the resource location they put in. and it can be changed to as long as it's during preinit


2d point is valid you would have to delete old lang files before regenerating them I put that on modders fault not client's( I guess I could prevent this by having a mode where it always deletes the old lang files making them unconfigurable unless you have a resource pack but, of course this would be disabled by default it would solely be for dev people using my library. I already have a boolean for isEclipse so it's highly possible to do so


3d point yes I know so how do I get this to be kept only on client?

Edited by jredfox
Link to comment
Share on other sites

5 minutes ago, diesieben07 said:

You open the lang file, save it under a different name and then translate every value. No coding knowledge required. With your method the translator needs to dig through your code, understand it, carefully extract language keys and their English translations and then build the language file themselves.

 

"old lang files"? What? Your model does not have lang files by default. You just write everything in code. What the fuck do you want to delete? What the fuck does "isEclipse" mean?

 

You don't. You write a lang file.

 

They don't have to have coding language to change anything. It's also in vanilla lang format otherwise I would have to do serious work but, yes it does the line library stuff I said before.

A: Coder inputs default line
B: User inputs modified display name > located at "configs/evilnotchlib/resourcepack/lang/yourlang.lang"
C: User overrides original Code
D: the lang entries get converted into "tile.modid.block.name=value" in a lang file exterior to the jar for safety precautions

If you won't help that's fine but, I will find a way 

Edited by jredfox
Link to comment
Share on other sites

46 minutes ago, diesieben07 said:

Wait... what?

You are ... generating .lang files? While the mod is loading? Why are you doing this... Please stop. Please please stop.

Ok then how do I get an IResourcePack working then? I have been looking for an hour and I can't seem to find the method to pointing the interface into the directory of the new location since it's not in resourcepacks folder

Link to comment
Share on other sites

public class LangPack extends DefaultResourcePack{
	
	public static Set<String> domains = new HashSet();
	protected ResourceIndex resourceIndex = null;
	
	public LangPack(ResourceIndex resourceIndexIn)
	{
	    super(resourceIndexIn);
	    domains.add(MainJava.MODID);
	}

	@Override
	public Set<String> getResourceDomains() {
		return domains;
	}

	@Override
	public String getPackName() {
		return "Lang Pack";
	}

}

I did and it's not working. I don't know what file it's looking for of the ResourceIndex and what's going on with that I tried many file locations. I also verified that I was adding it to the resource pack default list.

It's not even showing up on the menu if it was I could start debugging 


Client Proxy Pre-Init:
 

List<IResourcePack> list = (List<IResourcePack>)ReflectionUtil.getObject(Minecraft.getMinecraft(), Minecraft.class,MCPMappings.getField(Minecraft.class, "defaultResourcePacks"));
File dir = new File(Config.cfg.getParent(),"resourcepacks/langpack");
dir.mkdirs();
System.out.println(dir);
IResourcePack pack = new LangPack(new ResourceIndexFolder(dir) );
list.add(pack);

 

Edited by jredfox
Link to comment
Share on other sites

2 hours ago, diesieben07 said:

Why are you extending DefaultResourcePack?

 

Default resource packs will not show up in the menu, I am not sure if there is a way to add additional packs to the selection screen.

They don't then why does the regular defualt show up to the right menu? How can I verify if it's even loading any resources what directory should I be feeding it? am I doing something wrong?

You know what that's fine I guess but, for the future I want to know how to get it in the menu and right now I need to know how I can verify it's loading the right directory.

 

"DefaultResourcePack"
because, I looked at the implementation from the interface and made almost no sense as no direct directory was there

Edited by jredfox
Link to comment
Share on other sites

2 hours ago, diesieben07 said:

DefaultResourcePack is vanilla's default textures. You do not want to extend it.

Yeah well it's kind of hard to do anything if the names don't tell you their function where it's looking and no documentation on this. I got this working though I can't take all the credit I cheated by looking at other mods resource directories that had IResourcePack.

Code:
https://gist.github.com/jredfox/1f3057d86627648d9eef67b5b9db4f1f

So I finally figured out why it wasn't working the resources were not getting loaded but, I was calling this at init I thought forge use to call reload resource packs at post init or after post init why the change of order? So how do I refresh/forceload and only my custom IResourcePack into minecraft's system after preinit?

I also tried printing the ms for refreshing the mc resources this way it's horrible:
Done Refreshing:9185ms

Client Proxy:

@Override
public void init() 
{
  File dir = new File(Config.cfg.getParent(),"resourcepacks/customResourcePack");
  IResourcePack pack = new CustomResourcePack(dir);
  list.add(pack);
  Minecraft.getMinecraft().refreshResources();
}

 

Edited by jredfox
Link to comment
Share on other sites

14 hours ago, diesieben07 said:

DefaultResourcePack is vanilla's default textures. You do not want to extend it.

So how do I refresh only my resource pack I tried calling this code but, it didn't do anything I had to refresh manually in game? This is in my client proxy's post init. I already added it to the default list but, I only want to refresh my own
 

SimpleReloadableResourceManager manager = (SimpleReloadableResourceManager) Minecraft.getMinecraft().getResourceManager();
manager.reloadResourcePack(pack);

 

Link to comment
Share on other sites

48 minutes ago, diesieben07 said:

postInit is to late. Use preInit. You cannot refresh individual resource packs, that's not how resource loading works.

The Seasons Mod refreshes a couple single resources in game and it takes like 20ms not even a second later it changes the blocks textures. I have my reasons on why it needs to be later then preinit. Otherewise I would have to make another mod extract it during asm and then let forge load it because it needs to fire after my initial mods preinit. Trying to make a dynamic resource pack like the seasons mod A: so I can use it for my lib B: so when I make another mod that uses it It doesn't take 10 whole seconds to reload a couple textures for like a holiday mod
https://minecraft.curseforge.com/projects/the-seasons-mod/files/2453185

And it was done with 1.7.10-1.8 and worked with modded blocks so It can't be the model thing using dynamic textures because it there was no model event and I kind of browsed the code couldn't figure out where it was refreshing it but, I did find that it wasn't using any custom models to do so.

Edited by jredfox
Link to comment
Share on other sites

41 minutes ago, diesieben07 said:

If you want textures to change in game (as a result of in-game events) then yes, you need custom texture implementations.

However this requires quite a bit of work.

 

If you simply want to load textures from somewhere else than the normal asset paths, you want a resource pack. And yes, it must be registered in preInit. And no, there is zero reason for it to be done later. Please clarify why you think it needs to be done later.

I plan on generating resources from mods that depend on my mod when does it load after or during preint, images, etc...? Could I register it in preinit but, my resources won't be done generating from other mods until preinit is guaranteed to be done? How do I get around this? Is there something inbetween preinit and the model event?
 

Edited by jredfox
Link to comment
Share on other sites

1 minute ago, diesieben07 said:

If you want to generate things for other mods, they should be calling a registration method (in your API) in their preInit, which will then generate the required resources and register the resource pack.

but, the mods will fire after evil notch lib that will depend upon it so then I would have to have a before pre init now you see my issue?

Link to comment
Share on other sites

4 minutes ago, diesieben07 said:

No, you don't understand.

In your preInit you do not register anything for other mods. You wait for other mods to call you from their preInit.

register IResourcePack preinit

other mods call me
other mods dependond upon me so their preinit fires after me. Registering something to generate from other mods calling me would do nothing for the IResourcepack since evil notch's lib preinit has been done that would mean I would have to generate everything from my lib after

If I made each mod generate the files I wouldn't be an api the other mods requiring me would become the api

 

 

Edited by jredfox
Link to comment
Share on other sites

11 minutes ago, diesieben07 said:

No, you don't understand.

In your preInit you do not register anything for other mods. You wait for other mods to call you from their preInit.

My code I sent you earlier doesn't even work when it's in preinit i still have to refresh it in game what am I suppose to call to make miencraft load it the first time into the game?

  File dir = new File(Config.cfg.getParent(),"resourcepacks/customResourcePack");
  IResourcePack pack = new CustomResourcePack(dir);
  list.add(pack);


Also the mods load after me editing an mcmeta/json would be highly unoptimized rather then the core doing the work all at once it would be load file edit file save file for every single thing. There has got to be an optimized way to force the resource loaded from my pack into minecraft after preinit

Edited by jredfox
Link to comment
Share on other sites

55 minutes ago, diesieben07 said:

WAT?

 

No, there is not. Refreshing resources is expensive.

Well after looking at some code I think it's possible to manually call everything, one for language, one for images, one for models.

I just succeeded in a first hard coded lang file test. If it's possible with lang it should be possible with everything else. Best parts is ms is 10-12k less between 0-5ms
 

/**
	 * Manually refresh resources
	 */
	public void init() 
	{
		if(lang == null)
			lang = (LanguageMap) ReflectionUtil.getObject(null, I18n.class, MCPMappings.getField(I18n.class, "localizedName"));
		try {
			lang.inject(new FileInputStream(new File(this.rootDir,"assets/evilnotchlib/lang/en_us.lang")) );
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

 

Link to comment
Share on other sites

2 minutes ago, diesieben07 said:

Oh god please stop... 

Why do you insist on always hacking the flying shit out of everything...

if you must know it's so it will make modding easier for me in the future. For my actual mods I make one-two lines of code for an item and texture as well as generated textures. I could make a block generator if I felt like 10k where each block has a random pattern color and random name.

 

I plan on using this lazy modding for coalification,vanilla life, charcoal block mod

Edited by jredfox
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

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