- 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
Last active
November 19, 2022 16:54
-
-
Save Gordin/6fd87fa7ba3b9f50fce4e614cd7c00c6 to your computer and use it in GitHub Desktop.
Script that remaps Keys in Cyberpunk 2077 from qwertz to dvorak and shifts everything one key to the right (to play with ESDF)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[tool.pyright] | |
include = ["."] | |
reportMissingImports = true | |
pythonVersion = "3.10" | |
pythonPlatform = "Windows" | |
executionEnvironments = [ | |
{ root = "." } | |
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment