in Minecraft/src/main/java/com/microsoft/Malmo/MissionHandlers/CommandForKey.java [271:369]
public void install(MissionInit missionInit)
{
// Attempt to find the keybinding that matches the description we were given,
// and replace it with our own KeyHook object:
GameSettings settings = Minecraft.getMinecraft().gameSettings;
boolean createdHook = false;
// GameSettings contains both a field for each KeyBinding (eg keyBindAttack), and an array of KeyBindings with a pointer to
// each field. We want to make sure we replace both pointers, otherwise Minecraft will end up using our object for some things, and
// the original object for others.
// So we need to use reflection to replace the field:
Field[] fields = GameSettings.class.getFields();
for (int i = 0; i < fields.length; i++)
{
Field f = fields[i];
if (f.getType() == KeyBinding.class)
{
KeyBinding kb;
try
{
kb = (KeyBinding)(f.get(settings));
if (kb != null && kb.getKeyDescription().equals(this.keyDescription))
{
this.originalBinding = kb;
this.keyHook = create(this.originalBinding);
createdHook = true;
f.set(settings, this.keyHook);
}
}
catch (IllegalArgumentException e)
{
e.printStackTrace();
}
catch (IllegalAccessException e)
{
e.printStackTrace();
}
}
}
// And then we replace the pointer in the array:
for (int i = 0; i < settings.keyBindings.length; i++)
{
if (settings.keyBindings[i].getKeyDescription().equals(this.keyDescription))
{
this.originalBindingIndex = i;
if (!createdHook)
{
this.originalBinding = settings.keyBindings[i];
this.keyHook = create(this.originalBinding);
createdHook = true;
}
settings.keyBindings[i] = this.keyHook;
}
}
// And possibly in the hotbar array too:
for (int i = 0; i < settings.keyBindsHotbar.length; i++)
{
if (settings.keyBindsHotbar[i].getKeyDescription().equals(this.keyDescription))
{
this.originalBindingIndex = i;
if (!createdHook)
{
this.originalBinding = settings.keyBindsHotbar[i];
this.keyHook = create(this.originalBinding);
createdHook = true;
}
settings.keyBindsHotbar[i] = this.keyHook;
}
}
// Newer versions of MC have changed the way they map from key value to KeyBinding, so we
// *also* need to fiddle with the static KeyBinding HASH map:
Field[] kbfields = KeyBinding.class.getDeclaredFields();
for (Field f : kbfields)
{
if (f.getType() == KeyBindingMap.class)
{
net.minecraftforge.client.settings.KeyBindingMap kbp;
try
{
f.setAccessible(true);
kbp = (KeyBindingMap) (f.get(null));
// Our new keybinding should already have been added;
// just need to remove the original one.
while (kbp.lookupAll(this.keyHook.getKeyCode()).size() > 1)
kbp.removeKey(this.originalBinding);
return;
}
catch (IllegalArgumentException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}