Jump to content

[1.10.2] Key bind overflow?


JimiIT92

Recommended Posts

In my mod i'm registering different key bindings. However for some reason if i go to the Controls screen, to view the keys and re-map them, the game crashes with this error

java.lang.ArrayIndexOutOfBoundsException: 42
    at net.minecraft.client.gui.GuiKeyBindingList.<init>(GuiKeyBindingList.java:49)
    at net.minecraft.client.gui.GuiControls.initGui(GuiControls.java:38)
    at net.minecraft.client.gui.GuiScreen.setWorldAndResolution(GuiScreen.java:553)
    at net.minecraft.client.Minecraft.displayGuiScreen(Minecraft.java:1018)
    at net.minecraft.client.gui.GuiOptions.actionPerformed(GuiOptions.java:152)
    at net.minecraft.client.gui.GuiScreen.mouseClicked(GuiScreen.java:504)
    at net.minecraft.client.gui.GuiScreen.handleMouseInput(GuiScreen.java:619)
    at net.minecraft.client.gui.GuiScreen.handleInput(GuiScreen.java:585)
    at net.minecraft.client.Minecraft.runTick(Minecraft.java:1797)
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:1118)
    at net.minecraft.client.Minecraft.run(Minecraft.java:406)
    at net.minecraft.client.main.Main.main(Main.java:118)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at net.minecraft.launchwrapper.Launch.launch(Launch.java:135)
    at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at net.minecraftforge.gradle.GradleStartCommon.launch(GradleStartCommon.java:97)
    at GradleStart.main(GradleStart.java:26)


These are my key bindings

	package com.rpg.core;
	import java.lang.reflect.Field;
	import org.lwjgl.input.Keyboard;
	import net.minecraft.client.settings.KeyBinding;
import net.minecraftforge.fml.client.registry.ClientRegistry;
	public class RPGKeys {
    public static KeyBinding KEY_GUILD;
    public static KeyBinding KEY_SHOP;
    public static KeyBinding KEY_SKILL_1;
    public static KeyBinding KEY_SKILLS;
    
    public static void addKeys() {
        KEY_GUILD = new KeyBinding("keys.guilds.description", Keyboard.KEY_G, "keys.guilds.category");
        KEY_SHOP = new KeyBinding("keys.shop.description", Keyboard.KEY_K, "keys.shop.category");
        KEY_SKILL_1 = new KeyBinding("keys.skills.description", Keyboard.KEY_Z, "keys.skills.category");
        KEY_SKILLS = new KeyBinding("keys.skills.skills", Keyboard.KEY_O, "keys.skills.category");
    }
    
    public static void registerKeys() {
        Field[] fields = RPGKeys.class.getFields();
        for (Field field : fields) {
            try {
                if (field.get(RPGKeys.class) != null) {
                    ClientRegistry.registerKeyBinding((KeyBinding) field.get(RPGKeys.class));
                }
            } catch (IllegalArgumentException | IllegalAccessException exception) {
                exception.printStackTrace();
            }
        }
    }
}

The keys works as intended, if i remove one key from here everything works fine. It's just in the Controls screen that the crash happen. What could be the cause of this? :/

Edited by JimiIT92

Don't blame me if i always ask for your help. I just want to learn to be better :)

Link to comment
Share on other sites

Why are you accessing the fields in your class in such a weird way with your getFields() method? Why aren't you just registering your fields directly? You wrote more lines of code to loop through than you actually had key bindings...

 

I'm not sure if your weird way of registering the fields is causing the issue, but I would try making that more simple first.

 

After that, if there is still an issue, you'll notice that the error occurs where the listEntries array is going out of bounds. The size of that array is set based on the number of keybindings in the GameSettings plus the number of categories in KeyBinding together. So it may be an issue with the fact that you're creating new keybinding categories. I have done keybinding before but frankly I always used existing categories, but maybe there is some trick or maybe even bug. I would trace through the execution in debug mode in Eclipse by setting a breakpoint in that loop and watching how the index is advancing.

 

 

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

I've used new categories without problems.

 

		public static KeyBinding eventKey;

...
		eventKey = new KeyBinding("key." + Reference.MOD_ID + ".event", Keyboard.KEY_G, "key.categories." + Reference.MOD_ID);
		ClientRegistry.registerKeyBinding(eventKey);

 

Is addKeys() even called?  If so, you can register them at that point.

Link to comment
Share on other sites

Yes, the addKeys is called (as i said the keys itself works normally, if i press one of them they do what they've been registered for). I used the reflection method because i plan to add more keybinds and with this i just have to register it, but i'll try to register them manually and see what happens :/

Don't blame me if i always ask for your help. I just want to learn to be better :)

Link to comment
Share on other sites

Changing the registration method didn't solved the error, but i've noticed going into debug mode when i enter the controls screen that the key category for KEY_SKILLS and KEY_SKILL_1, wich is the same, is added twice in the key list, while other categories like normal vanilla keybinds categories are added once. Infact, if i move one of them to a new category everything works fine. This is how i register the key binds now

public static void registerKeys() {
        ClientRegistry.registerKeyBinding(KEY_GUILD);
        ClientRegistry.registerKeyBinding(KEY_SHOP);
        ClientRegistry.registerKeyBinding(KEY_SKILLS);
        ClientRegistry.registerKeyBinding(KEY_SKILL_1);
    }

So am i doing something wrong? And if so how can i register 2 keys within the same category? Or it's a Forge bug? 

Don't blame me if i always ask for your help. I just want to learn to be better :)

Link to comment
Share on other sites

Okay, if I look at the KeyBinding.KEYBIND_SET (which contains the categories) it turns out there is an add(category) called on that every time a key binding is constructed. Now technically a Java Set should not allow duplicates.

 

The category is a string, but the Java set properly uses the equals() method for comparison according to the "contract" of the method definition. 

 

So basically the category set will get the add() called every time, but it should not actually create any duplicates.

 

When tracing you should look at the contents of the KEYBIND_SET to see if there is actually an (apparent) duplicate added.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

I've looked at the listEntries array that is generated (and that gives the exception). As you can see there are 2 categories with the same name but different ID, and these are the categories that comes from the 2 keys with the same one

 

Cattura.PNG

Don't blame me if i always ask for your help. I just want to learn to be better :)

Link to comment
Share on other sites

Then you should trace through the constructor of the GuiKeyBindingList because it has a loop where it checks whether each category is unique before adding a category entry to listEntries.

 

Now that I look at it though, I think it is actually a bug. Because the way the loop works is that it has a "previous category" field called s and "current category" field called s1 and checks if they are equal. Basically it is checking if the category of the entry in this iteration of the loop is the same as the previous. However, that requires the categories to be sorted. There is a sort on the list, but I think maybe it is wrong because I think it is sorting the actual key bindings not necessarily just the categories.

 

Check if that is the problem.

 

So I think it might be a bug. You might be able to work around it by naming your keybinds so that the ones in the same category sort together, or something else that makes sure that the categories are processed consecutively.

 

Alternatively, you can override the whole gui by copying the class and fixing the bug and then handling the gui open event to put up your gui instead.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Actually the sort method looks suspicious generally. It is sorting an array of KeyBinding which are cast to Object and I don't think KeyBinding class has a comparator interface to help the sorting. So I don't think the sort would be meaningful in terms of the keybinding unless the default Object sort is based on toString() and even then seems a bit sketchy.

 

Basically when the loop starts you need to see whether the two entries with the same category are right after each other. If not then the loop will probably fail. Or just monitor the s and s1 values during the loop. There is definitely potential for something wrong there I think.

Check out my tutorials here: http://jabelarminecraft.blogspot.com/

Link to comment
Share on other sites

Yes in the first iteration the keys with the same category was not one after the other, meaning that when the game adds the second key the previous category was a different one and so it adds the duplicate. Fun fact: i've added more keys in the same category and now the controls screen appear and in the gui init the check on s and s1 is correct O_O 

Don't blame me if i always ask for your help. I just want to learn to be better :)

Link to comment
Share on other sites

This is how I registered my keybinds (https://github.com/KenLPham/ArcadeMod/blob/1.11.2/src/main/java/superhb/arcademod/util/KeyHandler.java) and I don't have any problems with it.

 

When do you call registerKeys? Copying your method worked, but I called registerKey in addKeys()

 

Also I think if you want to use your lang file for the Categories and Key Description you need to use I18n.format() (I'm guessing that's what you want to do considering what you've named it)

Edited by SuperHB
Link to comment
Share on other sites

Me too has no problem with the keys itself, it's just that if i have exactly 2 keys of the same category (not more) the Controls screen crash the game. And it looks like it's a bug in the Control GUI, because it doesn't make any sense that more keys within the same category doesn't give the same crash

Don't blame me if i always ask for your help. I just want to learn to be better :)

Link to comment
Share on other sites

24 minutes ago, JimiIT92 said:

Me too has no problem with the keys itself, it's just that if i have exactly 2 keys of the same category (not more) the Controls screen crash the game. And it looks like it's a bug in the Control GUI, because it doesn't make any sense that more keys within the same category doesn't give the same crash

I copied your code and was able to open the control screen. Where are you calling registerKey() though? I had it at the end of addKeys()

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.



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • ChemsXpress (https://chemsxpress.com): ChemsXpress is a platform specializing in the distribution of research chemicals and related products. It offers a wide range of substances for scientific and laboratory use, catering to researchers and professionals. BubatzLand (https://bubatzland.com): BubatzLand focuses on providing high-quality cannabis products. The site offers a variety of strains, edibles, and related accessories, aiming to serve the needs of cannabis enthusiasts and medicinal users. HalluShroom (https://hallushroom.com): HalluShroom specializes in the sale of psychedelic mushrooms and related products. It caters to individuals interested in exploring the benefits and experiences associated with psilocybin and other psychedelic substances. HighAsch (https://highasch.com): HighAsch offers a diverse range of cannabis products, including flowers, concentrates, and edibles. The site aims to provide premium-quality products to both recreational and medicinal users. KetaminHaus (https://ketaminhaus.com): KetaminHaus provides ketamine and related products for research and therapeutic use. The platform focuses on ensuring the availability of high-quality, safe, and effective ketamine for various applications. KokainLabor (https://kokainlabor.com): KokainLabor offers cocaine and other related substances. The site targets individuals seeking high-purity products for personal or research purposes, emphasizing quality and safety. MDPHPWelt (https://mdphpwelt.com): MDPHPWelt specializes in the distribution of MDPHP and other similar research chemicals. It aims to supply researchers with high-quality substances for scientific and experimental use. NembutaLabor (https://nembutalabor.com): NembutaLabor provides Nembutal (pentobarbital) and related products. The site focuses on supplying these substances for research and veterinary purposes, ensuring high standards of quality and safety. NembutalQuelle (https://nembutalquelle.com): NembutalQuelle is dedicated to offering Nembutal and similar barbiturates. It caters to researchers and professionals who require these substances for scientific, medical, or veterinary applications. JBSaves Ltda Brazil (https://jbsavesltdabrazil.com): JBSaves Ltda Brazil is involved in the food and agricultural industry, providing a variety of products and services related to food processing, distribution, and agricultural practices. Bello Alimentos Ltda (https://belloalimentosltda.com): Bello Alimentos Ltda offers a wide range of food products. The site focuses on high-quality, nutritious, and safe food items, catering to consumers and businesses in the food industry. São Salvador Alimentos (https://saosalvadoralimentoss.com): São Salvador Alimentos specializes in the production and distribution of food products. The site provides a variety of options aimed at meeting the dietary needs and preferences of diverse consumers. WietWereld (https://wietwereld.com): WietWereld is a platform dedicated to the cannabis community. It offers information, products, and resources related to cannabis cultivation, consumption, and culture. 14. BeuhParadise (https://beuhparadis.com): BeuhParadise offers a range of cannabis products, including flowers, edibles, and concentrates. The site aims to provide high-quality cannabis products to recreational and medicinal users, emphasizing purity and potency. 15. WietWereld (https://wietwereld.com): WietWereld is a comprehensive resource for cannabis enthusiasts. It provides products, cultivation guides, and community forums for those interested in cannabis culture and cultivation. GrasOase (https://grasoase.com): GrasOase specializes in cannabis products and accessories. The site offers a variety of strains, seeds, and related items for cannabis users, focusing on quality and customer satisfaction. https://chemsxpress.com/ https://bubatzland.com/ https://hallushroom.com/ https://highasch.com/ https://ketaminhaus.com/ https://kokainlabor.com/ https://mdphpwelt.com/ https://nembutalabor.com/ https://nembutalquelle.com/ https://jbsavesltdabrazil.com/ https://belloalimentosltda.com/ https://saosalvadoralimentoss.com/ https://wietwereld.com https://beuhparadis.com https://wietwereld.com https://grasoase.com/
    • For Example I have an Main Mod that adds new Content to Minecraft. But I'm using custom Classes etc. and I want it so that is an api integrated in the Main Mod but can be download seperately like an Module. Is this possible? If you need more Information just comment what you need to know ^^
    • Delete the config of this mod (config folder) and test it again   If there is no change, try other builds  
    • Add the full crash-report or latest.log (logs-folder) with sites like https://paste.ee/ and paste the link to it here
  • Topics

×
×
  • Create New...

Important Information

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