Skip to content

Instantly share code, notes, and snippets.

@ademlabs
Last active June 12, 2022 06:08
Show Gist options
  • Save ademlabs/753bff9a1ec35e4994a11bde68e93ff6 to your computer and use it in GitHub Desktop.
Save ademlabs/753bff9a1ec35e4994a11bde68e93ff6 to your computer and use it in GitHub Desktop.
Download Apex Legends Linux dxvk state cache files and merge automatically
#!/bin/python3
import json, urllib3, re, subprocess, shutil, os, time
steam_library_location = "/home/arvind/Games/Steam/steamapps"
dxvk_cache_tool = "/home/arvind/Games/Steam/steamapps/shadercache/1172470/DXVK_state_cache/dxvk-cache-tool"
url = "https://www.reddit.com/r/linux_gaming/comments/t5xrho.json?limit=99999"
http = urllib3.PoolManager()
main_last_updated = 0
cache_files = list()
def parse_comments(childrenRoot):
for comment in childrenRoot:
# Skip objects of type "load more"
if comment['kind'] == 'more':
continue
# If post has been edited, get the timestamp, else it is a new unedited post and we get the created timestamp instead
comment_last_updated = int(comment['data']['edited']) if comment['data']['edited'] else int(comment['data']['created'])
# We only consider posts that have been added after the main post's last update
if comment_last_updated > main_last_updated:
extract_cache_file_from_url(comment['data']['body'], f"/tmp/{comment['data']['id']}_{comment_last_updated}.dxvk-cache")
# Recurse into children of current comment if there are any replies present
if 'replies' in comment['data'] and comment['data']['replies']:
parse_comments(comment['data']['replies']['data']['children'])
def extract_cache_file_from_url(text, output_file_path):
global cache_files
# Usually, there is a single link to the cache file in that post, retrieve the URL
pattern = re.compile(r"(https:\/\/).*?(r5apex\.dxvk-cache)")
search = pattern.search(text)
if search:
link = search.group()
print(f"Found '{link}', saving to '{output_file_path}'", end=' > ')
# Pull the cache file URL into a local file
exit_code = subprocess.call(["wget", "-q", link, "-O", output_file_path])
if exit_code == 0:
print('OK')
cache_files.append(output_file_path)
else:
print('ERROR!')
def merge_cache_files():
apex_cache_file = f"{steam_library_location}/shadercache/1172470/DXVK_state_cache/r5apex.dxvk-cache"
backup_file = f"{steam_library_location}/shadercache/1172470/DXVK_state_cache/r5apex_{int(time.time())}.dxvk-cache"
# Backup the current cache file before merging anything
print("Backing up Apex Cache File:")
backup_result = subprocess.call(["cp", "-avf", apex_cache_file, backup_file])
if backup_result == 0:
merge_result = subprocess.call([dxvk_cache_tool] + cache_files + [backup_file, '-o', apex_cache_file])
if merge_result > 0:
print("Error during merge, restoring backup file:")
restore_result: subprocess.call(["cp", "-avf", backup_file, apex_cache_file])
print("Done!" if restore_result == 0 else "Catastrophic failure. Please verify manually")
else:
print("Error while backing up files, merging aborted!")
def clean_temp_files():
print("Cleaning up temporary cache files", end=' > ')
cleanup_result = subprocess.call(["rm", "-f"] + cache_files)
print("OK" if cleanup_result == 0 else "Error. Files will be removed at next reboot")
def main():
global main_last_updated
# Pull JSON data from the post
resp = http.request("GET", url, headers = {"User-Agent": "Cache Merger Bot r0"})
data = json.loads(resp.data.decode("utf-8"))
# Retrieve body text of the post and last edited timestamp
text = data[0]['data']['children'][0]['data']['selftext']
main_last_updated = int(data[0]['data']['children'][0]['data']['edited'])
main_filename = f"/tmp/_0_{main_last_updated}.dxvk-cache"
# Extract cache file from Reddit post
extract_cache_file_from_url(text, main_filename)
# Scan the replies for any user contributed files that have been sent after the main post's last update
childrenRoot = data[1]['data']['children']
parse_comments(childrenRoot)
# Retrieve the cache file from bcook254's Github
extract_cache_file_from_url("https://github.com/bcook254/apex-legends-cache/raw/main/r5apex.dxvk-cache", "/tmp/bcook254.dxvk-cache")
if len(cache_files) > 0:
merge_cache_files()
clean_temp_files()
else:
print("Nothing to do")
if __name__=="__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment