- Have python installed
- Download remap.py and put it next to the config file
inputUserMappings.xml
(Should be in ...\Cyberpunk 2077\r6\config) - Open a terminal,
cd
into the directory with the script, and runpython remap.py
- It should create a new file called
inputUserMappings2.xml
- Now rename
inputUserMappings.xml
to something else, and renameinputUserMappings2.xml
toinputUserMappings.xml
-
-
Save Gordin/6fd87fa7ba3b9f50fce4e614cd7c00c6 to your computer and use it in GitHub Desktop.
[tool.pyright] | |
include = ["."] | |
reportMissingImports = true | |
pythonVersion = "3.10" | |
pythonPlatform = "Windows" | |
executionEnvironments = [ | |
{ root = "." } | |
] |
#!/usr/bin/env python | |
from lxml import objectify, etree | |
dvorak_mapping = { | |
# key on (german) keyboard: letter in dvorak | |
'IK_A': 'IK_A', | |
'IK_B': 'IK_X', | |
'IK_C': 'IK_I', | |
'IK_D': 'IK_E', | |
'IK_E': 'IK_Period', | |
'IK_F': 'IK_U', | |
'IK_G': 'IK_I', | |
'IK_H': 'IK_D', | |
'IK_I': 'IK_C', | |
'IK_J': 'IK_H', | |
'IK_K': 'IK_T', | |
'IK_L': 'IK_N', | |
'IK_M': 'IK_M', | |
'IK_N': 'IK_B', | |
'IK_O': 'IK_R', | |
'IK_P': 'IK_L', | |
'IK_Q': 'IK_SingleQuote', | |
'IK_R': 'IK_P', | |
'IK_S': 'IK_O', | |
'IK_T': 'IK_Y', | |
'IK_U': 'IK_G', | |
'IK_V': 'IK_K', | |
'IK_W': 'IK_Comma', | |
'IK_X': 'IK_Q', | |
'IK_Y': 'IK_Semicolon', | |
'IK_Z': 'IK_F', | |
} | |
personal_mapping = { | |
'IK_SingleQuote': 'IK_Comma', | |
'IK_Comma': 'IK_Period', | |
'IK_Period': 'IK_P', | |
'IK_P': 'IK_Y', | |
'IK_Y': 'IK_F', | |
'IK_F': 'IK_G', | |
'IK_G': 'IK_C', | |
'IK_C': 'IK_R', | |
'IK_R': 'IK_L', | |
'IK_L': 'IK_Slash', | |
'IK_A': 'IK_O', | |
'IK_O': 'IK_E', | |
'IK_E': 'IK_U', | |
'IK_U': 'IK_I', | |
'IK_I': 'IK_D', | |
'IK_D': 'IK_H', | |
'IK_H': 'IK_T', | |
'IK_T': 'IK_N', | |
'IK_N': 'IK_S', | |
'IK_Semicolon': 'IK_Q', | |
'IK_Q': 'IK_J', | |
'IK_J': 'IK_K', | |
'IK_K': 'IK_X', | |
'IK_X': 'IK_B', | |
'IK_B': 'IK_M', | |
'IK_M': 'IK_V', | |
'IK_LShift': 'IK_A', | |
'IK_Shift': 'IK_A', | |
'IK_LControl': 'IK_Semicolon', | |
'IK_Ctrl': 'IK_Semicolon', | |
'IK_Left': 'ignore', | |
'IK_Right': 'ignore', | |
'IK_Up': 'ignore', | |
'IK_Down': 'ignore', | |
'IK_Enter': 'ignore', | |
'IK_Backspace': 'ignore', | |
'IK_Space': 'ignore', | |
'IK_Escape': 'ignore', | |
'IK_Tab': 'ignore', | |
'IK_Alt': 'ignore', | |
'ReportIssue_ButtonGroup': 'ignore', | |
'IK_1': 'ignore', | |
'IK_2': 'ignore', | |
'IK_3': 'ignore', | |
'IK_4': 'ignore', | |
'IK_5': 'ignore', | |
'IK_6': 'ignore', | |
'IK_7': 'ignore', | |
'IK_8': 'ignore', | |
'IK_9': 'ignore', | |
'IK_0': 'ignore', | |
'IK_Home': 'ignore', | |
'IK_RControl': 'ignore', | |
'IK_RShift': 'ignore', | |
'IK_1_LShift': 'ignore', | |
'IK_2_LShift': 'ignore', | |
'IK_3_LShift': 'ignore', | |
'IK_CapsLock': 'ignore', | |
} | |
def loadXML(): | |
f = open("inputUserMappings.xml", "r", encoding="utf8") | |
text = f.read() | |
return objectify.fromstring(text) | |
def ignoreButton(name: str): | |
if name.startswith('IK_Pad'): | |
return True | |
if name.startswith('IK_PAD'): | |
return True | |
if name.startswith('IK_Mouse'): | |
return True | |
if name.startswith('IK_NumPad'): | |
return True | |
if name.startswith('IK_PS4'): | |
return True | |
if name.startswith('IK_F') and name != 'IK_F': | |
return True | |
if 'Mouse' in name: | |
return True | |
if 'Thumb' in name: | |
return True | |
return False | |
def remapButton(button): | |
old_id = button.attrib['id'] | |
if ignoreButton(old_id): | |
return | |
new_id = dvorak_mapping.get(old_id) | |
if (new_id): | |
button.attrib['id'] = new_id | |
print('remapped {} to {}'.format(old_id, new_id)) | |
old_id = button.attrib['id'] | |
new_id = personal_mapping.get(old_id) | |
if new_id == 'ignore': | |
pass | |
elif new_id: | |
button.attrib['id'] = new_id | |
print('shift {} over to {}'.format(old_id, new_id)) | |
else: | |
print('missing mapping for {}'.format(old_id)) | |
def main(): | |
tree = loadXML() | |
children = tree.getchildren() | |
for mapping in list(filter(lambda x: x != '', children)): | |
buttons = mapping.getchildren() | |
for button in list(filter(lambda x: x.tag == 'button', buttons)): | |
# print(button.attrib) | |
remapButton(button) | |
return tree | |
if __name__ == "__main__": | |
tree = main() | |
xmlString = etree.tostring(tree, pretty_print=True, encoding='unicode') | |
print(xmlString) | |
with open('inputUserMappings2.xml', 'w', encoding='utf8') as f: | |
f.write('<?xml version="1.0"?>\n') | |
f.write(xmlString) |
@micr0-dev It worked fine when I wrote it 2 years ago... Haven't played Cyberpunk since then.
I'd be surprised if this could crash the game though since it just shuffles existing keys in a config file around. Maybe the game had added more keybinds in the last years and now some keys are bound two multiple things and it doesn't like that. I'm just randomly guessing though, since I haven't played in a long time. Maybe you can even do all the rebinds in the game now ^^ (I'm guessing not though, otherwise why would anyone look at this script...)
thanks for your reply! it does work for some keybinds but not all, some the game doesn't like, I am however running the game via proton on linux so maybe that is messing with it... i will figure something out eventually, for now, I have just been playing with a controller. anyhow thanks! ^^
@Gordin has this script ever worked for you? For me, the game freezes on the starting script it seems to fail to load the key binds